253 lines
9.2 KiB
Lua
253 lines
9.2 KiB
Lua
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
|