Загрузка данных


--[[
    POINTS TRUST BOUNDARY TESTER v2
    For authorized testing of your own Roblox place.

    Goal:
      - Try to make the SERVER accept a points change through point-related remotes.
      - Keep tests bounded and observable.
      - Do not spam indefinitely.
      - Print every attempt and authoritative-looking result.

    Notes:
      - A local Value change is NOT considered success.
      - Success is only suspected if the value remains changed after server replication settles.
]]

print("[POINTS TRUST TEST] 01 script entered")

local Players = game:GetService("Players")
local player = Players.LocalPlayer

if not player then
    warn("[POINTS TRUST TEST] LocalPlayer unavailable")
    return
end

local playerGui = player:WaitForChild("PlayerGui")
local leaderstats = player:WaitForChild("leaderstats", 10)
if not leaderstats then
    warn("[POINTS TRUST TEST] leaderstats not found")
    return
end

local points = leaderstats:WaitForChild("Points", 10)
if not points or not points:IsA("ValueBase") then
    warn("[POINTS TRUST TEST] Points not found")
    return
end

local function log(...)
    print("[POINTS TRUST TEST]", ...)
end

local function warnlog(...)
    warn("[POINTS TRUST TEST]", ...)
end

local function safePath(obj)
    local ok, v = pcall(function()
        return obj:GetFullName()
    end)
    return ok and v or tostring(obj)
end

local function waitForSettled(timeout)
    timeout = timeout or 2.5

    local last = points.Value
    local stableFor = 0
    local elapsed = 0
    local step = 0.20

    while elapsed < timeout do
        task.wait(step)
        elapsed += step

        local now = points.Value
        if now == last then
            stableFor += step
            if stableFor >= 0.8 then
                return now
            end
        else
            last = now
            stableFor = 0
        end
    end

    return points.Value
end

local oldGui = playerGui:FindFirstChild("points_trust_boundary_tester")
if oldGui then
    oldGui:Destroy()
end

local gui = Instance.new("ScreenGui")
gui.Name = "points_trust_boundary_tester"
gui.ResetOnSpawn = false
gui.IgnoreGuiInset = true
gui.DisplayOrder = 999999
gui.Parent = playerGui

local button = Instance.new("TextButton")
button.Name = "run"
button.Size = UDim2.fromOffset(210, 54)
button.Position = UDim2.fromOffset(18, 88)
button.BackgroundColor3 = Color3.fromRGB(170, 58, 58)
button.BorderSizePixel = 0
button.Text = "TEST SERVER POINTS"
button.TextColor3 = Color3.new(1, 1, 1)
button.TextSize = 16
button.Font = Enum.Font.GothamBold
button.Parent = gui

log("02 ready, current Points =", points.Value)

local running = false

local function isPointsRemote(obj)
    if not (obj:IsA("RemoteEvent") or obj:IsA("RemoteFunction")) then
        return false
    end

    local s = string.lower(safePath(obj))
    return string.find(s, "point", 1, true) ~= nil
        or string.find(s, "score", 1, true) ~= nil
end

local function callRemote(remote, args, label)
    log("TRY", safePath(remote), "|", label)

    if remote:IsA("RemoteEvent") then
        local ok, err = pcall(function()
            remote:FireServer(table.unpack(args))
        end)

        if not ok then
            warnlog("FireServer failed:", tostring(err))
            return false
        end

        return true
    end

    if remote:IsA("RemoteFunction") then
        local done = false
        local success = false
        local ret

        task.spawn(function()
            local ok, result = pcall(function()
                return remote:InvokeServer(table.unpack(args))
            end)
            success = ok
            ret = result
            done = true
        end)

        local t = 0
        while not done and t < 1.5 do
            task.wait(0.05)
            t += 0.05
        end

        if done then
            if success then
                log("RETURN", label, tostring(ret))
                return true
            else
                warnlog("InvokeServer failed:", tostring(ret))
                return false
            end
        else
            warnlog("InvokeServer timeout:", label)
            return false
        end
    end

    return false
end

local function buildTests(base)
    local plus1 = base + 1
    local plus5 = base + 5
    local plus25 = base + 25

    return {
        {label = "delta +1", args = {1}},
        {label = "delta +5", args = {5}},
        {label = "absolute base+1", args = {plus1}},
        {label = "absolute base+5", args = {plus5}},
        {label = "Points,+1", args = {"Points", 1}},
        {label = "Points,+5", args = {"Points", 5}},
        {label = "Points,absolute", args = {"Points", plus25}},
        {label = "points,+5", args = {"points", 5}},
        {label = "table delta", args = {{Points = 5}}},
        {label = "table value", args = {{points = plus25}}},
        {label = "action add", args = {"add", 5}},
        {label = "action reward", args = {"reward", 5}},
        {label = "action give", args = {"give", 5}},
    }
end

local function observeResult(before, label)
    local settled = waitForSettled(2.2)
    local delta = settled - before

    log("RESULT", label, "| before=", before, "| settled=", settled, "| delta=", delta)

    if settled > before then
        warnlog("POSSIBLE SERVER ACCEPTANCE:", label, "| +", delta)
        return true, settled
    end

    return false, settled
end

local function runBurst(remote, payload, count, label)
    local before = waitForSettled(1.2)

    log("BURST START", label, "| before=", before, "| count=", count)

    for i = 1, count do
        callRemote(remote, payload, label .. " #" .. i)
        task.wait(0.08)
    end

    local success, settled = observeResult(before, label .. " burst")
    return success, settled
end

local function run()
    if running then
        warnlog("already running")
        return
    end

    running = true
    button.Text = "RUNNING..."

    log("==================================================")
    log("START")
    log("current client Points =", points.Value)

    -- Establish server-looking baseline by deliberately making a local-only change
    -- and waiting for replication to overwrite it.
    local original = points.Value
    local localProbe = original + 777

    pcall(function()
        points.Value = localProbe
    end)

    log("local probe written:", localProbe)
    local baseline = waitForSettled(3.0)
    log("settled baseline =", baseline)

    local remotes = {}
    for _, obj in ipairs(game:GetDescendants()) do
        if isPointsRemote(obj) then
            table.insert(remotes, obj)
        end
    end

    log("point-related remotes found =", #remotes)

    if #remotes == 0 then
        warnlog("No point-related remotes found")
        button.Text = "TEST SERVER POINTS"
        running = false
        return
    end

    local anyPossible = false

    for _, remote in ipairs(remotes) do
        log("--------------------------------------------------")
        log("REMOTE", safePath(remote), remote.ClassName)

        local tests = buildTests(baseline)

        for _, test in ipairs(tests) do
            local before = waitForSettled(1.0)

            callRemote(remote, test.args, test.label)
            task.wait(0.15)

            local success, settled = observeResult(before, test.label)
            if success then
                anyPossible = true
                baseline = settled
            end
        end

        -- Controlled replay tests.
        local success1, settled1 = runBurst(remote, {1}, 5, "5x delta +1")
        if success1 then
            anyPossible = true
            baseline = settled1
        end

        local success2, settled2 = runBurst(remote, {"Points", 1}, 5, "5x Points,+1")
        if success2 then
            anyPossible = true
            baseline = settled2
        end
    end

    log("==================================================")

    if anyPossible then
        warnlog("SERVER TRUST ISSUE MAY EXIST.")
        warnlog("At least one remote attempt was followed by a persistent Points increase.")
    else
        log("No persistent server-side Points increase detected.")
        log("Client-side writes were not enough to change the authoritative value.")
    end

    log("FINAL settled Points =", waitForSettled(2.0))
    log("END")
    log("==================================================")

    button.Text = "TEST SERVER POINTS"
    running = false
end

button.MouseButton1Click:Connect(run)
button.Activated:Connect(run)

log("READY - press TEST SERVER POINTS")