Windforge - server-side co-op compatibility patch

 avatar
lua
4 days ago
5.6 KB
17
Indexable
-- Windforge - server-side co-op compatibility patch
-- Tested purpose: disable server-side building resource validation in the
-- separate Windrose WindowsServer process.
--
-- Install as:
--   ...\R5\Builds\WindowsServer\R5\Binaries\Win64\
--      ue4ss\Mods\Windforge\Scripts\main.lua
--
-- Keep the original Windforge script on the client. This file is intended
-- only for the server-side Windforge installation.

local START_DELAY_MS = 5000
local RETRY_INTERVAL_MS = 5000
local RETRY_COUNT = 4

local function Log(message)
    print("[FreeBuildServer] " .. tostring(message) .. "\n")
end

local function PatchSettingsObject(object, label)
    if not object or not object:IsValid() then
        return false
    end

    local write_ok, write_error = pcall(function()
        object.bBuildingResourcesValidation = false
        object.bSkipBuildingCenterValidation = true
    end)

    if not write_ok then
        Log("Failed to patch " .. label .. ": " .. tostring(write_error))
        return false
    end

    -- Read the values back when possible. This improves diagnostics without
    -- making verification mandatory for the patch to continue.
    local read_ok, resources_validation, skip_center_validation = pcall(function()
        return object.bBuildingResourcesValidation,
               object.bSkipBuildingCenterValidation
    end)

    if read_ok then
        local verified =
            resources_validation == false and
            skip_center_validation == true

        Log(
            "Patched " .. label ..
            " (resource validation=" .. tostring(resources_validation) ..
            ", skip center validation=" .. tostring(skip_center_validation) ..
            ", verified=" .. tostring(verified) .. ")"
        )

        return verified
    end

    Log("Patched " .. label .. " (values could not be read back).")
    return true
end

local function PatchBuildingSettings()
    local patched_count = 0
    local instance_count = 0

    -- Patch any live instances that already exist.
    local find_ok, settings_or_error = pcall(function()
        return FindAllOf("R5BuildingSettings")
    end)

    if find_ok and settings_or_error then
        local settings = settings_or_error
        instance_count = #settings

        for index = 1, instance_count do
            if PatchSettingsObject(
                settings[index],
                "R5BuildingSettings instance #" .. tostring(index)
            ) then
                patched_count = patched_count + 1
            end
        end
    elseif not find_ok then
        Log("FindAllOf failed: " .. tostring(settings_or_error))
    end

    -- Always patch the class default object as well. On the WindowsServer
    -- build this may be the only available settings object during startup.
    local cdo_ok, cdo_or_error = pcall(function()
        return StaticFindObject("/Script/R5.Default__R5BuildingSettings")
    end)

    if cdo_ok then
        if PatchSettingsObject(
            cdo_or_error,
            "R5BuildingSettings default object"
        ) then
            patched_count = patched_count + 1
        end
    else
        Log("StaticFindObject failed: " .. tostring(cdo_or_error))
    end

    Log(
        "Patch summary: live instances=" .. tostring(instance_count) ..
        ", successfully patched objects=" .. tostring(patched_count)
    )

    return patched_count > 0
end

local function RunStartupPatch(attempt)
    Log("Startup patch attempt " .. tostring(attempt) ..
        "/" .. tostring(RETRY_COUNT))

    PatchBuildingSettings()

    if attempt < RETRY_COUNT then
        ExecuteWithDelay(RETRY_INTERVAL_MS, function()
            RunStartupPatch(attempt + 1)
        end)
    else
        Log("Startup patch cycle completed.")
    end
end

Log("Server compatibility patch loaded.")

-- The original mod waits for PlayerController:ClientRestart. That event is
-- client-oriented and did not execute the patch in the separate server
-- process. A bounded retry window applies the server settings directly while
-- the world is being initialized.
ExecuteWithDelay(START_DELAY_MS, function()
    RunStartupPatch(1)
end)
Editor is loading...
Leave a Comment