"0 or 1 is not an error - it is a sign that we should wait", 2 => "Success", 3 => "Disabled", 4 => "Failed to start", 5 => "Game ended", 6 => "GAME_FULL", 10 => "USER_LEFT" ]; // statuses for placelauncher if(isset($_GET["token"])) { $token = $_GET["token"]; // get the token from the url like: ?token= $checkifuser = $con->prepare('SELECT COUNT(*) FROM tokens WHERE token=:token'); // check if the token even exists $checkifuser->bindParam(':token', $token); $checkifuser->execute(); $momentoftruth = $checkifuser->fetchColumn(); if ($momentoftruth == 1) { $status = '2'; // its defined now! $getstuff = $con->prepare('SELECT placeid FROM tokens WHERE token=:token'); // get the placeid $getstuff->bindParam(':token', $token); $getstuff->execute(); $china = $getstuff->fetch(PDO::FETCH_BOTH); $placeid = $china['placeid']; $okbruh = '1'; // random variable i do because pdo does not allow just "0" or '0' $haha = $con->prepare('SELECT COUNT(*) FROM tokens WHERE token=:token AND passedplacelauncher=:passed'); // check if it has passed placelauncher yet $haha->bindParam(':token', $token); $haha->bindParam(':passed', $okbruh); $haha->execute(); $moretrolling = $haha->fetchColumn(); if ($moretrolling == 1) { header("Location: /"); } else if ($moretrolling == 0) { $checkifjobalreadyexists = $con->prepare('SELECT COUNT(*) FROM jobs WHERE placeid=:placeid AND hasended=:hasended'); // check if theres already a job running and HAS NOT ended $checkifjobalreadyexists->bindParam(':placeid', $placeid); $helppdo = '0'; // random variable i do because pdo does not allow just "0" or '0' (2x) $checkifjobalreadyexists->bindParam(':hasended', $helppdo); $checkifjobalreadyexists->execute(); $okcheck = $checkifjobalreadyexists->fetchColumn(); if ($okcheck == 1) { $passedplacelauncher = '1'; $hahatroll = $con->prepare('UPDATE tokens SET passedplacelauncher = :passedplacelauncher WHERE token=:token'); // make the current token not able to get another placelauncher response $hahatroll->bindParam(':passedplacelauncher', $passedplacelauncher); $hahatroll->bindParam(':token', $token); $hahatroll->execute(); $getjobforalready = $con->prepare('SELECT jobid FROM jobs WHERE placeid=:placeid AND hasended=:hasended'); // get the jobid if theres already a job running $getjobforalready->bindParam(':placeid', $placeid); $getjobforalready->bindParam(':hasended', $helppdo); $getjobforalready->execute(); $china2 = $getjobforalready->fetch(PDO::FETCH_BOTH); $jobid = $china2['jobid']; // get the jobid from pdo $response = [ "jobId" => $jobid, "status" => $status, "joinScriptUrl" => $site['url'] ."/game/join?token=". $token ."&jobid=". $jobid, "authenticationUrl" => $site['url'] ."/Login/Negotiate.ashx", "authenticationTicket" => $token, "message" => $allstatus[$status] ]; die(json_encode($response)); // DON'T FORGET TO DIE OR ELSE IT MIGHT FOLLOW THE SCRIPT UNTIL IT CAN'T FOLLOW IT ANYMORE } elseif ($okcheck == 0) { $passedplacelauncher = '1'; // IF THIS IS 0 THEN IT MEANS PLACELAUNCHER HASN'T PASSED MAKE SURE THIS ITS 1 ONLY IN UR TESTING $hahatroll = $con->prepare('UPDATE tokens SET passedplacelauncher = :passedplacelauncher WHERE token=:token'); // i don't remember but its the same thing as earlier maybe $hahatroll->bindParam(':passedplacelauncher', $passedplacelauncher); $hahatroll->bindParam(':token', $token); $hahatroll->execute(); function generateRandomJobId() { // jobid generator $chars = '0123456789abcdefghijklmnopqrstuvwxyz'; $length = 8; $p1 = substr(str_shuffle(str_repeat($x=$chars, ceil($length/strlen($x)) )),1,$length); $length = 4; $p2 = substr(str_shuffle(str_repeat($x=$chars, ceil($length/strlen($x)) )),1,$length); $length = 4; $p3 = substr(str_shuffle(str_repeat($x=$chars, ceil($length/strlen($x)) )),1,$length); $length = 4; $p4 = substr(str_shuffle(str_repeat($x=$chars, ceil($length/strlen($x)) )),1,$length); $length = 12; $p5 = substr(str_shuffle(str_repeat($x=$chars, ceil($length/strlen($x)) )),1,$length); return $p1."-".$p2."-".$p3."-".$p4."-".$p5; } function generateRandomString($length = 25) { // random string generator used for generating access tokens $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen($characters); $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[random_int(0, $charactersLength - 1)]; } return $randomString; } $port = rand(5000,5999); // generate random port $checkport = $con->prepare('SELECT COUNT(*) FROM jobs WHERE placeid=:placeid AND port=:port'); // check if the port has already been used $checkport->bindParam(':placeid', $placeid); $checkport->bindParam(':port', $port); $checkport->execute(); $okbrahh = $checkport->fetchColumn(); if ($okbrahh == 1) { $port = rand(5000,5999); // great heavens if this ever happens report to me } else if ($okbrahh == 0) { $accesstoken = generateRandomString(500); // generate a accesstoken used by rcc to get the placefile $jobid = generateRandomJobId(); // get a random jobid $placeid = $placeid; // idk why i did this but i did it $ip = $AvailableGameservers["1"]; // get the ip from the config $okaccesstoken = $con->prepare('INSERT INTO accesstokens (ip, accesstoken, placeid, jobid) VALUES (:ip, :accesstoken, :placeid, :jobid)'); // insert the accesstoken $okaccesstoken->bindParam(':ip', $ip); $okaccesstoken->bindParam(':accesstoken', $accesstoken); $okaccesstoken->bindParam(':placeid', $placeid); $okaccesstoken->bindParam(':jobid', $jobid); $okaccesstoken->execute(); $RCCServiceSoap = new Roblox\Grid\Rcc\RCCServiceSoap($ip, 64989); // start the job // script starts here $script = 'print("Starting gameserver at PlaceID: '. $placeid .' on port: '. $port .' with JobID: '. $jobid .'") -- Start Game Script Arguments local placeId = '. $placeid .' local port = '. $port .' local gameId = "'. $jobid .'" local sleeptime = 0 local access = "'. $accesstoken .'" local deprecated = false local timeout = 60 local machineAddress = "'. $ip .'" local gsmInterval = 2 local baseUrl = "sierraf.tk" local maxPlayers = 60 local maxGameInstances = 1 local injectScriptAssetID = 0 local apiKey = "'. $accesstoken .'" local libraryRegistrationScriptAssetID = 0 local deprecated_pingTimesReportInterval = 2 local gameCode = 0 local universeId = "'. $jobid .'" local preferredPlayerCapacity = 60 local matchmakingContextId = 0 local placeVisitAccessKey = "'. $accesstoken .'" local assetGameSubdomain = "assetgame" local protocol = "https://" -----------------------------------"CUSTOM" SHARED CODE---------------------------------- pcall(function() settings().Network.UseInstancePacketCache = true end) pcall(function() settings().Network.UsePhysicsPacketCache = true end) pcall(function() settings()["Task Scheduler"].PriorityMethod = Enum.PriorityMethod.AccumulatedError end) settings().Network.PhysicsSend = Enum.PhysicsSendMethod.TopNErrors settings().Network.ExperimentalPhysicsEnabled = true settings().Network.WaitingForCharacterLogRate = 100 pcall(function() settings().Diagnostics:LegacyScriptMode() end) -----------------------------------START GAME SHARED SCRIPT------------------------------ local assetId = placeId -- might be able to remove this now local url = nil local assetGameUrl = nil local accesstoken = placeVisitAccessKey if baseUrl~=nil and protocol ~= nil then url = protocol .. "www." .. baseUrl --baseUrl is actually the domain, no leading . assetGameUrl = protocol .. assetGameSubdomain .. "." .. baseUrl end local scriptContext = game:GetService("ScriptContext") pcall(function() scriptContext:AddStarterScript(libraryRegistrationScriptAssetID) end) scriptContext.ScriptsDisabled = true game:SetPlaceID(assetId, false) pcall(function () if universeId ~= nil then game:SetUniverseId(universeId) end end) game:GetService("ChangeHistoryService"):SetEnabled(false) -- establish this peer as the Server local ns = game:GetService("NetworkServer") -- Detect cloud edit mode by checking for the dedicated cloud edit matchmaking context local isCloudEdit = matchmakingContextId == 3 if isCloudEdit then print("Configuring as cloud edit server!") game:SetServerSaveUrl(url .. "/ide/publish/UploadFromCloudEdit") ns:ConfigureAsCloudEditServer() end local badgeUrlFlagExists, badgeUrlFlagValue = pcall(function () return settings():GetFFlag("NewBadgeServiceUrlEnabled") end) local newBadgeUrlEnabled = badgeUrlFlagExists and badgeUrlFlagValue if url~=nil then local apiProxyUrl = "https://api." .. baseUrl -- baseUrl is really the domain pcall(function() game:GetService("Players"):SetAbuseReportUrl(url .. "/AbuseReport/InGameChatHandler.ashx") end) pcall(function() game:GetService("ScriptInformationProvider"):SetAssetUrl(assetGameUrl .. "/Asset/") end) pcall(function() game:GetService("ContentProvider"):SetBaseUrl(url .. "/") end) -- pcall(function() game:GetService("Players"):SetChatFilterUrl(assetGameUrl .. "/Game/ChatFilter.ashx") end) if gameCode then game:SetVIPServerId(tostring(gameCode)) end game:GetService("BadgeService"):SetPlaceId(placeId) if newBadgeUrlEnabled then game:GetService("BadgeService"):SetAwardBadgeUrl(apiProxyUrl .. "/assets/award-badge?userId=%d&badgeId=%d&placeId=%d") end if access ~= nil then if not newBadgeUrlEnabled then game:GetService("BadgeService"):SetAwardBadgeUrl(assetGameUrl .. "/Game/Badge/AwardBadge.ashx?UserID=%d&BadgeID=%d&PlaceID=%d") end game:GetService("BadgeService"):SetHasBadgeUrl(assetGameUrl .. "/Game/Badge/HasBadge.ashx?UserID=%d&BadgeID=%d") game:GetService("BadgeService"):SetIsBadgeDisabledUrl(assetGameUrl .. "/Game/Badge/IsBadgeDisabled.ashx?BadgeID=%d&PlaceID=%d") game:GetService("FriendService"):SetMakeFriendUrl(assetGameUrl .. "/Game/CreateFriend?firstUserId=%d&secondUserId=%d") game:GetService("FriendService"):SetBreakFriendUrl(assetGameUrl .. "/Game/BreakFriend?firstUserId=%d&secondUserId=%d") game:GetService("FriendService"):SetGetFriendsUrl(assetGameUrl .. "/Game/AreFriends?userId=%d") end game:GetService("BadgeService"):SetIsBadgeLegalUrl("") game:GetService("InsertService"):SetBaseSetsUrl(assetGameUrl .. "/Game/Tools/InsertAsset.ashx?nsets=10&type=base") game:GetService("InsertService"):SetUserSetsUrl(assetGameUrl .. "/Game/Tools/InsertAsset.ashx?nsets=20&type=user&userid=%d") game:GetService("InsertService"):SetCollectionUrl(assetGameUrl .. "/Game/Tools/InsertAsset.ashx?sid=%d") game:GetService("InsertService"):SetAssetUrl(assetGameUrl .. "/Asset/?id=%d") game:GetService("InsertService"):SetAssetVersionUrl(assetGameUrl .. "/Asset/?assetversionid=%d") if gameCode then pcall(function() loadfile(assetGameUrl .. "/Game/LoadPlaceInfo.ashx?PlaceId=" .. placeId .. "&gameCode=" .. tostring(gameCode))() end) else pcall(function() loadfile(assetGameUrl .. "/Game/LoadPlaceInfo.ashx?PlaceId=" .. placeId)() end) end pcall(function() if access then loadfile(assetGameUrl .. "/Game/PlaceSpecificScript.ashx?PlaceId=" .. placeId)() end end) end pcall(function() game:GetService("NetworkServer"):SetIsPlayerAuthenticationRequired(true) end) settings().Diagnostics.LuaRamLimit = 0 game:GetService("Players").PlayerAdded:connect(function(player) print("Player " .. player.userId .. " added") if assetGameUrl and access and placeId and player and player.userId then local didTeleportIn = "False" if player.TeleportedIn then didTeleportIn = "True" end -- game:HttpGet(assetGameUrl .. "/Game/ClientPresence.ashx?action=connect&PlaceID=" .. placeId .. "&UserID=" .. player.userId) if not isCloudEdit then game:HttpPost(assetGameUrl .. "/Game/PlaceVisit.ashx?UserID=" .. player.userId .. "&AssociatedPlaceID=" .. placeId .. "&placeVisitAccessKey=" .. placeVisitAccessKey .. "&IsTeleport=" .. didTeleportIn, "") end end end) game:GetService("Players").PlayerRemoving:connect(function(player) print("Player " .. player.userId .. " leaving") local isTeleportingOut = "False" if player.Teleported then isTeleportingOut = "True" end if assetGameUrl and access and placeId and player and player.userId then game:HttpGet(assetGameUrl .. "/Game/ClientPresence.ashx?action=disconnect&PlaceID=" .. placeId .. "&UserID=" .. player.userId .. "&IsTeleport=" .. isTeleportingOut .. "&placeVisitAccessKey=" .. accesstoken) end end) local onlyCallGameLoadWhenInRccWithAccessKey = newBadgeUrlEnabled if placeId ~= nil and assetGameUrl ~= nil and ((not onlyCallGameLoadWhenInRccWithAccessKey) or access ~= nil) then -- yield so that file load happens in the heartbeat thread wait() -- load the game game:Load(assetGameUrl .. "/asset/?id=" .. placeId .. "&accesstoken=" .. accesstoken) end -- Configure CloudEdit saving after place has been loaded if isCloudEdit then local doPeriodicSaves = true local delayBetweenSavesSeconds = 5 * 60 -- 5 minutes local function periodicSave() if doPeriodicSaves then game:ServerSave() delay(delayBetweenSavesSeconds, periodicSave) end end -- Spawn thread to save in the future delay(delayBetweenSavesSeconds, periodicSave) -- Hook into OnClose to save on shutdown game.OnClose = function() doPeriodicSaves = false game:ServerSave() end end -- Now start the connection ns:Start(port, sleeptime) if timeout then scriptContext:SetTimeout(timeout) end scriptContext.ScriptsDisabled = false -- StartGame -- if not isCloudEdit then if injectScriptAssetID and (injectScriptAssetID < 0) then pcall(function() Game:LoadGame(injectScriptAssetID * -1) end) else pcall(function() Game:GetService("ScriptContext"):AddStarterScript(injectScriptAssetID) end) end Game:GetService("RunService"):Run() end '; $job = new Roblox\Grid\Rcc\Job($jobid, 99999999999); // pls only set to this amount WHEN ur hosting a gameserver when ur rendering do like 10 minutes $funny = new Roblox\Grid\Rcc\ScriptExecution("Script".rand(1,getrandmax()), $script); // uhhhh idk but this is related to multiple scripts running or smthing like that $result = $RCCServiceSoap->OpenJob($job, $funny); // open the job jobOpened($jobid, 99999999999); // sends message to discord webhook that a job started $sendthatjob = $con->prepare('INSERT INTO jobs (jobid, placeid, port, ip) VALUES (:jobid, :placeid, :port, :ip)'); // get the job in the database! $sendthatjob->bindParam(':jobid', $jobid); $sendthatjob->bindParam(':placeid', $placeid); $sendthatjob->bindParam(':port', $port); $sendthatjob->bindParam(':ip', $AvailableGameservers[1]); $sendthatjob->execute(); // give the response to the client $response = [ "jobId" => $jobid, "status" => $status, "joinScriptUrl" => $site['url'] ."/game/join?token=". $token ."&jobid=". $jobid, "authenticationUrl" => $site['url'] ."/Login/Negotiate.ashx", "authenticationTicket" => $token, "message" => $allstatus[$status] ]; die(json_encode($response)); // make sure to die } } } else { header("Location: /"); } } } ?>