215 lines
5.9 KiB
PHP
215 lines
5.9 KiB
PHP
<?php require $_SERVER['DOCUMENT_ROOT']."/api/private/core.php";
|
|
|
|
use pizzaboxer\ProjectPolygon\RBXClient;
|
|
|
|
header("content-type: text/plain; charset=utf-8");
|
|
|
|
ob_start();
|
|
?>
|
|
|
|
local jobid, placeid, userId, immediate = ...
|
|
|
|
function enableStats()
|
|
game:SetJobsExtendedStatsWindow(30);
|
|
end
|
|
|
|
function disableStats()
|
|
game:SetJobsExtendedStatsWindow(0);
|
|
end
|
|
|
|
function collectStats()
|
|
|
|
local measures = {}
|
|
|
|
local appendstring = function(name, value)
|
|
local row = "string\t" .. name .. "\t" .. value;
|
|
measures[#measures+1] = row;
|
|
end
|
|
|
|
local appenddouble = function(name, value)
|
|
local row = "double\t" .. name .. "\t" .. value;
|
|
measures[#measures+1] = row;
|
|
end
|
|
|
|
local extendedstats = game:GetJobsExtendedStats();
|
|
-- some known column headers.
|
|
local NAME = 1
|
|
local columnnames = extendedstats[1];
|
|
|
|
-- setup index of running jobs.
|
|
-- fist row is header. start at 2.
|
|
local taskmap = {};
|
|
for i = 2, #(extendedstats) do
|
|
taskmap[extendedstats[i][NAME]] = i;
|
|
end
|
|
|
|
local appendtask = function(taskname)
|
|
if taskmap[taskname] then
|
|
local taskdata = extendedstats[taskmap[taskname]];
|
|
|
|
for col = 2, #taskdata do
|
|
appenddouble(taskname .. "." .. columnnames[col], taskdata[col])
|
|
end
|
|
end
|
|
end
|
|
|
|
appendtask("Physics")
|
|
appendtask("Render")
|
|
appendtask("Heartbeat")
|
|
|
|
local player = game:GetService("Players").LocalPlayer;
|
|
if player then
|
|
appenddouble("UserId", game:GetService("Players").LocalPlayer.userId);
|
|
end
|
|
|
|
if jobid then
|
|
appendstring("JobId", jobid)
|
|
end
|
|
|
|
if placeid then
|
|
appenddouble("PlaceId", placeid)
|
|
end
|
|
|
|
appenddouble("DistributedGameTime", game.Workspace.DistributedGameTime);
|
|
|
|
if taskmap["Render"] then
|
|
appenddouble("Render.interval.peakAbove40ms", game:GetJobIntervalPeakFraction("Render", 0.040));
|
|
appenddouble("Render.time.peakAbove50ms", game:GetJobTimePeakFraction("Render", 0.050));
|
|
end
|
|
if taskmap["Physics"] then
|
|
appenddouble("Physics.interval.peakAbove40ms", game:GetJobIntervalPeakFraction("Physics", 0.040));
|
|
appenddouble("Physics.time.peakAbove50ms", game:GetJobTimePeakFraction("Physics", 0.050));
|
|
end
|
|
|
|
if stats():FindFirstChild("Network") then
|
|
for k, child in pairs(stats().Network:GetChildren()) do
|
|
local rpackets = child:FindFirstChild("Received Physics Packets");
|
|
if rpackets then
|
|
appenddouble("Network." .. tostring(child) .. ".ReceivedPhysicsPackets", rpackets:GetValue())
|
|
end
|
|
end
|
|
end
|
|
|
|
if stats():FindFirstChild("Workspace") then
|
|
appenddouble("Workspace.FPS", stats().Workspace.FPS:GetValue())
|
|
appenddouble("Workspace.World.Primitives", stats().Workspace.World.Primitives:GetValue())
|
|
end
|
|
|
|
appenddouble("ElapsedTime", settings().Diagnostics.ElapsedTime);
|
|
appenddouble("InstanceCount", settings().Diagnostics.InstanceCount);
|
|
appenddouble("JobCount", settings().Diagnostics.JobCount);
|
|
appenddouble("PrivateBytes", settings().Diagnostics.PrivateBytes);
|
|
appenddouble("ProcessCores", settings().Diagnostics.ProcessCores);
|
|
appendstring("RobloxVersion", settings().Diagnostics.RobloxVersion);
|
|
|
|
-- these can be gleaned from the machine config as well, but they are put here for convenience.
|
|
appenddouble("RAM", settings().Diagnostics.RAM);
|
|
appendstring("CPU", settings().Diagnostics.CPU);
|
|
appenddouble("CpuCount", settings().Diagnostics.CpuCount);
|
|
|
|
-- TODO: remove pcall and OsPlatformId once OsPlatform is deployed everywhere
|
|
pcall(function() appendstring("OsPlatform", settings().Diagnostics.OsPlatform) end)
|
|
appenddouble("OsPlatformId", settings().Diagnostics.OsPlatformId)
|
|
|
|
appenddouble("PlayerCount", game.Players.NumPlayers);
|
|
|
|
return measures
|
|
end
|
|
|
|
function postStats(t)
|
|
local poststring = table.concat(t, "\n")
|
|
local player = game:GetService("Players").LocalPlayer;
|
|
local id = 0;
|
|
local idtype = "None";
|
|
if player then
|
|
idtype = "PlayerId"
|
|
id = game:GetService("Players").LocalPlayer.userId;
|
|
end
|
|
if placeid then
|
|
idtype = "PlaceId"
|
|
id = placeid
|
|
end
|
|
|
|
local url = "http://<?=$_SERVER["HTTP_HOST"]?>/Analytics/Measurement.ashx?Type=Game.Performance&IPFilter=primary&SecondaryFilterName=" .. idtype .. "&SecondaryFilterValue=" .. tostring(id);
|
|
--print(url)
|
|
--print(poststring)
|
|
game:HttpPost(url, poststring, false)
|
|
end
|
|
|
|
|
|
enableStats();
|
|
|
|
-- lua doesn't have built in xor!
|
|
-- use this multiplication-based munger instead.
|
|
function munge_words(a, b)
|
|
return ((a * b) / 0x100) % 0x10000;
|
|
end
|
|
|
|
function collectAndPostStatsMaybe()
|
|
local shouldPostProb = 1.0/64.0;
|
|
local shouldPost = (math.random() < shouldPostProb)
|
|
|
|
if jobid then
|
|
-- generate a "random" number from the guid.
|
|
local s = {string.match(jobid, "(%x%x%x%x)(%x%x%x%x)-(%x%x%x%x)-(%x%x%x%x)-(%x%x%x%x)-(%x%x%x%x)(%x%x%x%x)(%x%x%x%x)")};
|
|
local w = 0x0100; -- this is the identity value for munge_words
|
|
for i = 1, #s do
|
|
w = munge_words(w, tonumber(s[i], 16))
|
|
end
|
|
shouldPost = w < 0x10000 * shouldPostProb;
|
|
end
|
|
|
|
if shouldPost then
|
|
postStats(collectStats())
|
|
end
|
|
end
|
|
|
|
if immediate then
|
|
postStats(collectStats())
|
|
else
|
|
delay(1 * 60, function()
|
|
while true do
|
|
collectAndPostStatsMaybe()
|
|
wait(10 * 60)
|
|
end
|
|
end)
|
|
end
|
|
|
|
|
|
function postFrmStats(t, id)
|
|
local poststring = table.concat(t, "\n")
|
|
local idtype = "PlayerId"
|
|
|
|
local url = "http://<?=$_SERVER["HTTP_HOST"]?>/Analytics/Measurement.ashx?Type=Game.Performance.FrameRateManager&IPFilter=primary&SecondaryFilterName=" .. idtype .. "&SecondaryFilterValue=" .. tostring(id);
|
|
--print(url)
|
|
--print(poststring)
|
|
game:HttpPost(url, poststring, false)
|
|
end
|
|
|
|
-- Some sampling condition based on userId
|
|
if (userId % 100) == 0 then
|
|
local frm = stats():FindFirstChild("FrameRateManager")
|
|
local closeConnection = game.Close:connect(function()
|
|
pcall(function()
|
|
local measures = {}
|
|
|
|
local appenddouble = function(name, value)
|
|
local row = "double\t" .. name .. "\t" .. value;
|
|
measures[#measures+1] = row;
|
|
end
|
|
|
|
if frm then
|
|
frm:GetValue()
|
|
for k, child in pairs(frm:GetChildren()) do
|
|
appenddouble(child.Name, child:GetValue())
|
|
end
|
|
end
|
|
postFrmStats(measures, userId)
|
|
postStats(collectStats())
|
|
end)
|
|
end)
|
|
end
|
|
|
|
|
|
|
|
<?php echo RBXClient::CryptSignScript(ob_get_clean());
|