This commit is contained in:
lx
2026-07-06 14:01:11 -04:00
commit c4f97d729d
16468 changed files with 935321 additions and 0 deletions
@@ -0,0 +1,9 @@
{
"language": {
"mode": "nonstrict"
},
"lint": {
"LocalShadow": "fatal",
"ImplicitReturn": "fatal"
}
}
@@ -0,0 +1,78 @@
local AnalyticsService = game:GetService("RbxAnalyticsService")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local SETTINGS_HUB_INVITE_RELEASE_STREAM_TIME = 10
local function getPlatformTarget()
local platformTarget = "unknownLua"
local platformEnum = Enum.Platform.None
-- the call to GetPlatform is wrapped in a pcall() because the Testing Service
-- executes the scripts in the wrong authorization level
pcall(function()
platformEnum = UserInputService:GetPlatform()
end)
-- bucket the platform based on consumer platform
local isDesktopClient = (platformEnum == Enum.Platform.Windows) or (platformEnum == Enum.Platform.OSX)
local isMobileClient = (platformEnum == Enum.Platform.IOS) or (platformEnum == Enum.Platform.Android)
isMobileClient = isMobileClient or (platformEnum == Enum.Platform.UWP)
local isConsole = (platformEnum == Enum.Platform.XBox360) or (platformEnum == Enum.Platform.XBoxOne)
isConsole = isConsole or (platformEnum == Enum.Platform.PS3) or (platformEnum == Enum.Platform.PS4)
isConsole = isConsole or (platformEnum == Enum.Platform.WiiU)
-- assign a target based on the form factor
if isDesktopClient then
platformTarget = "client"
elseif isMobileClient then
platformTarget = "mobile"
elseif isConsole then
platformTarget = "console"
else
-- if we don't have a name for the form factor, report it here so that we can eventually track it down
platformTarget = platformTarget .. tostring(platformEnum)
end
return platformTarget
end
local EventStream = {}
EventStream.__index = EventStream
function EventStream.new(overridePlatformTarget, overrideAnalyticsImpl)
local self = {}
setmetatable(self, EventStream)
self._analyticsImpl = overrideAnalyticsImpl or AnalyticsService
self._platformTarget = overridePlatformTarget or getPlatformTarget()
return self
end
function EventStream:setRBXEventStream(eventContext, eventName, additionalArgs)
additionalArgs = additionalArgs or {}
-- this function sends reports to the server in batches, not real-time
self._analyticsImpl:SetRBXEventStream(self._platformTarget, eventContext, eventName, additionalArgs)
if not self.timerSteppedConnection then
local lastGameTime = time()
self.timerSteppedConnection = RunService.Stepped:Connect(function(gameTime)
if gameTime - lastGameTime > SETTINGS_HUB_INVITE_RELEASE_STREAM_TIME then
self:releaseRBXEventStream()
end
end)
end
end
function EventStream:releaseRBXEventStream()
self._analyticsImpl:ReleaseRBXEventStream(self._platformTarget)
if self.timerSteppedConnection then
self.timerSteppedConnection:Disconnect()
self.timerSteppedConnection = nil
end
end
return EventStream
@@ -0,0 +1,97 @@
local CorePackages = game:GetService("CorePackages")
local HttpService = game:GetService("HttpService")
local LuaApp = CorePackages.AppTempCommon.LuaApp
local Promise = require(LuaApp.Promise)
local DEFAULT_THROTTLING_PRIORITY = Enum.ThrottlingPriority.Extreme
local DEFAULT_POST_ASYNC_CONTENT_TYPE = Enum.HttpContentType.ApplicationJson
-- httpRequest : (table, optional) an object that implements the same http functions as the data model
return function(httpImpl)
local function doHttpPost(url, options)
local jsonPayload
assert(options.postBody, "Expected a postBody to be specified with this request")
if type(options.postBody) == "table" then
jsonPayload = HttpService:JSONEncode(options.postBody)
elseif type(options.postBody) == "string" then
jsonPayload = options.postBody
else
error("Expected postBody to be a string or table")
end
if not options.contentType then
options.contentType = DEFAULT_POST_ASYNC_CONTENT_TYPE
end
if not options.throttlingPriority then
options.throttlingPriority = DEFAULT_THROTTLING_PRIORITY
end
return function()
return httpImpl:PostAsyncFullUrl(
url,
jsonPayload,
options.throttlingPriority,
options.contentType
)
end
end
local function doHttpGet(url)
return function()
return httpImpl:GetAsyncFullUrl(url, DEFAULT_THROTTLING_PRIORITY)
end
end
-- return the request function
-- url : (string)
-- requestMethod : (string) "GET", "POST"
-- args : (table, optional)
-- options.throttlingPriority : (Enum.ThrottlingPriority, optional)
-- options.contentType : (Enum.HttpContentType, optional)
-- options.postBody : (string, optional ("POST" only))
-- RETURNS : (promise<HttpResponse or string>)
return function(url, requestMethod, options)
assert(type(url) == "string", "Expected url to be a string")
assert(type(requestMethod) == "string", "Expected requestMethod to be a string")
assert(not options or type(options) == "table", "Expected options to be a table")
requestMethod = string.upper(requestMethod)
local httpFunction
if requestMethod == "POST" then
httpFunction = doHttpPost(url, options)
elseif requestMethod == "GET" then
httpFunction = doHttpGet(url)
else
error(string.format("Unsupported requestMethod : %s", requestMethod or "nil"))
end
return Promise.new(function(resolve, reject)
if httpFunction then
spawn(function()
local success, response = pcall(httpFunction)
if success then
local jsonSuccess, decodedJson = pcall(function()
return HttpService:JSONDecode(response)
end)
if jsonSuccess then
resolve({
responseBody = decodedJson,
})
else
reject(decodedJson)
end
else
reject(response)
end
end)
else
reject()
end
end)
end
end
@@ -0,0 +1,61 @@
return function()
local httpRequest = require(script.Parent.httpRequest)
local function createTestRequestFunc(testResponse)
local requestService = {}
function requestService:GetAsyncFullUrl()
return testResponse
end
function requestService:PostAsyncFullUrl()
return testResponse
end
return httpRequest(requestService)
end
it("should return a function", function()
expect(httpRequest()).to.be.ok()
expect(type(httpRequest())).to.equal("function")
end)
it("should validate its inputs", function()
local testRequest = createTestRequestFunc()
local function testParams(url, requestMethod, args)
return function()
testRequest(url, requestMethod, args)
end
end
local validUrl = "friends.roblox.com"
local validMethod = "GET"
local validArgs = {}
-- url checks
expect(testParams(nil, validMethod, validArgs)).to.throw()
expect(testParams(123, validMethod, validArgs)).to.throw()
expect(testParams({}, validMethod, validArgs)).to.throw()
expect(testParams(true, validMethod, validArgs)).to.throw()
expect(testParams(function() end, validMethod, validArgs)).to.throw()
-- request method checks
expect(testParams(validUrl, nil, validArgs)).to.throw()
expect(testParams(validUrl, 123, validArgs)).to.throw()
expect(testParams(validUrl, {}, validArgs)).to.throw()
expect(testParams(validUrl, true, validArgs)).to.throw()
expect(testParams(validUrl, function() end, validArgs)).to.throw()
-- args checks
expect(testParams(validUrl, validMethod, 123)).to.throw()
expect(testParams(validUrl, validMethod, "Test")).to.throw()
expect(testParams(validUrl, validMethod, true)).to.throw()
expect(testParams(validUrl, validMethod, function() end)).to.throw()
end)
it("should throw an error if the requestMethod isn't supported", function()
local testRequest = createTestRequestFunc("foo")
expect(function()
testRequest("testUrl", "GIVEANDTAKE")
end).to.throw()
end)
end
@@ -0,0 +1,16 @@
return function(targetString, blacklistedCharacter)
local charactersArray = {}
local indexArray = {}
for index, byte in utf8.codes(targetString) do
local graphemeCharacter = utf8.char(byte)
table.insert(charactersArray, 1, graphemeCharacter)
table.insert(indexArray, 1, index)
end
for index, graphemeCharacter in ipairs(charactersArray) do
if graphemeCharacter ~= blacklistedCharacter then
return targetString:sub(1, indexArray[index])
end
end
return ""
end
@@ -0,0 +1,71 @@
return function()
local trimCharacterFromEndString = require(script.Parent.trimCharacterFromEndString)
describe("single byte characters", function()
it("should not trim a string if it does not end with passed character", function()
local passedString = "testing"
local passedCharacter = "/"
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(passedString)
end)
it("should trim a string if it ends with a single instance of the passed character", function()
local passedString = "testing/"
local passedCharacter = "/"
local expectedString = "testing"
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(expectedString)
end)
it("should trim a string if it ends with multiple instances of the passed character", function()
local passedString = "testing///"
local passedCharacter = "/"
local expectedString = "testing"
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(expectedString)
end)
it("should do nothing if the passed character is empty", function()
local passedString = "hunter2"
local passedCharacter = ""
local expectedString = "hunter2"
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(expectedString)
end)
end)
describe("multiple byte characters", function()
it("should not trim a string if it does not end with passed character", function()
local passedString = "testing"
local passedCharacter = "🐶"
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(passedString)
end)
it("should trim a string if it ends with a single instance of the passed character", function()
local passedString = "testing🐶"
local passedCharacter = "🐶"
local expectedString = "testing"
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(expectedString)
end)
it("should trim a string if it ends with multiple instances of the passed character", function()
local passedString = "testing🐶🐶🐶"
local passedCharacter = "🐶"
local expectedString = "testing"
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(expectedString)
end)
end)
describe("a string with all blacklisted characters", function()
it("should return a empty string", function()
local passedString = "pppppppppppp"
local passedCharacter = "p"
local expectedString = ""
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(expectedString)
end)
end)
end