do local VERSION = 7 local MODULE_NAMES = { 'Logic.SettingModule.SettingEnum', 'Logic/SettingModule/SettingEnum', '@BakedLua/Logic/SettingModule/SettingEnum', 'SettingEnum', } local state = _G.__GAC_FPS_SETTINGS_120_STATE local Unity = CS.UnityEngine local function remove_callback(callback) if not callback then return end for _, event in ipairs({ {Unity.Application, 'onBeforeRender'}, {Unity.Camera, 'onPreCull'}, }) do pcall(function() event[1][event[2]]('-', callback) end) pcall(function() event[1][event[2]] = event[1][event[2]] - callback end) end end local function add_callback(callback) for _, event in ipairs({ {Unity.Application, 'onBeforeRender'}, {Unity.Camera, 'onPreCull'}, }) do local ok = pcall(function() event[1][event[2]]('+', callback) end) if not ok then ok = pcall(function() event[1][event[2]] = event[1][event[2]] + callback end) end if ok then return true, event[1], event[2] end end return false end if state and state.version ~= VERSION then remove_callback(state.callback) if state.module and state.original_getter then pcall(function() state.module.get_graphics_data_by_type = state.original_getter end) end state = nil end state = state or {version = VERSION, next_check = 0} _G.__GAC_FPS_SETTINGS_120_STATE = state local function log(message) Unity.Debug.Log('[GaC 120 FPS Settings] ' .. message) end if not state.load_logged then state.load_logged = true log('script loaded; checking the native Graphics settings module') end local function add_native_option(list, text_id) if type(list) ~= 'table' then return false end local next_key = 1 local has_30_fps = false local has_60_fps = false for _, option in ipairs(list) do if type(option) == 'table' then if option.setting == 120 then return true, false end if option.setting == 30 and option.text_id == 'UIText_Setting_Level_30FPS' then has_30_fps = true elseif option.setting == 60 and option.text_id == 'UIText_Setting_Level_60FPS' then has_60_fps = true end if type(option.key) == 'number' and option.key >= next_key then next_key = option.key + 1 end end end if not has_30_fps or not has_60_fps then return false, false end table.insert(list, { key = next_key, text_id = text_id, setting = 120, }) return true, true end local function patch_native_data(module) local graphics_data = rawget(module, '_graphics_data') if type(graphics_data) ~= 'table' then if not state.data_probe_logged then state.data_probe_logged = true log('native _graphics_data is not available on the settings module') end return false end local found_fps_list = false local added = false for setting_type, list in pairs(graphics_data) do local ok, matched, inserted = pcall(add_native_option, list, 'UIText_Setting_Level_120FPS') if ok and matched then found_fps_list = true if inserted then added = true end if not state.data_probe_logged then state.data_probe_logged = true log('found native FPS rows in _graphics_data[' .. tostring(setting_type) .. ']') end elseif not ok and not state.data_probe_logged then state.data_probe_logged = true log('_graphics_data probe failed: ' .. tostring(matched)) end end if added and not state.row_added then state.row_added = true log('added the 120 FPS option to the native Graphics data') elseif not found_fps_list and not state.data_probe_logged then state.data_probe_logged = true log('native _graphics_data is present but contains no matching 30/60 FPS rows') end return found_fps_list end local function find_setting_module() for _, name in ipairs(MODULE_NAMES) do local loaded = package.loaded[name] if type(loaded) == 'table' and type(loaded.get_graphics_data_by_type) == 'function' then state.module_alias = name return loaded end end if not state.require_attempted then state.require_attempted = true local outcomes = {} for _, name in ipairs(MODULE_NAMES) do local ok, result = pcall(require, name) if ok and type(result) == 'table' and type(result.get_graphics_data_by_type) == 'function' then state.module_alias = name return result end local loaded = package.loaded[name] if type(loaded) == 'table' and type(loaded.get_graphics_data_by_type) == 'function' then state.module_alias = name return loaded end outcomes[#outcomes + 1] = name .. '=' .. (ok and (type(result) .. ':' .. tostring(result)) or tostring(result)) end state.require_error = table.concat(outcomes, '; ') end local global_registry = rawget(_G, 'G') for _, entry in ipairs({ {value = rawget(_G, 'SettingModule'), name = '_G.SettingModule'}, {value = rawget(_G, 'SettingEnum'), name = '_G.SettingEnum'}, {value = type(global_registry) == 'table' and rawget(global_registry, 'SettingModule') or nil, name = 'G.SettingModule'}, {value = type(global_registry) == 'table' and rawget(global_registry, 'SettingEnum') or nil, name = 'G.SettingEnum'}, }) do local candidate = entry.value if type(candidate) == 'table' and type(candidate.get_graphics_data_by_type) == 'function' then state.module_alias = entry.name return candidate end end return nil end local function install() local module = find_setting_module() if type(module) ~= 'table' then if not state.module_wait_logged then state.module_wait_logged = true log('SettingEnum lookup failed; ' .. tostring(state.require_error)) end return false end local getter = module.get_graphics_data_by_type if type(getter) ~= 'function' then if not state.getter_wait_logged then state.getter_wait_logged = true log('Settings module loaded, but its graphics-data getter is unavailable') end return false end if state.module == module then return true end local fps_text = 'UIText_Setting_Level_120FPS' local original = getter module.get_graphics_data_by_type = function(...) local list = original(...) local ok, result, inserted = pcall(add_native_option, list, fps_text) if not ok and state.last_error ~= tostring(result) then state.last_error = tostring(result) log('could not add the native 120 FPS option: ' .. state.last_error) elseif ok and result and inserted and not state.row_added then state.row_added = true log('added the 120 FPS option to the native Graphics list') elseif not state.getter_probe_logged then state.getter_probe_logged = true local count = type(list) == 'table' and #list or -1 log('Graphics getter called; returned ' .. type(list) .. ' with ' .. tostring(count) .. ' rows') end return list end state.module = module state.original_getter = original log('ready; patched ' .. tostring(state.module_alias)) patch_native_data(module) return true end local function tick() local now = Unity.Time.unscaledTime if now < state.next_check then return end state.next_check = now + 0.5 local ok, result = pcall(install) if not ok then if state.last_error ~= tostring(result) then state.last_error = tostring(result) log('waiting for the native Graphics settings: ' .. state.last_error) end return end if result then remove_callback(state.callback) state.callback = nil end end if not state.module and not state.callback then state.callback = tick local ok = add_callback(state.callback) if not ok then state.callback = nil log('could not register the Graphics settings hook') end end if not state.module then tick() end end