diff --git a/init_coop.lua b/init_coop.lua index 80a68073..9acc17a5 100644 --- a/init_coop.lua +++ b/init_coop.lua @@ -4,6 +4,7 @@ local locationOfRepository = false local locationOfRepositoryCoop = false + -- START OF COPY -- -- in an ideal world this file would be loaded (using dofile) by the other @@ -18,6 +19,64 @@ LOG("Client version: " .. tostring(ClientVersion)) LOG("Game version: " .. tostring(GameVersion)) LOG("Game type: " .. tostring(GameType)) +------------------------------------------------------------------------------- +--#region Adjust process affinity and prioritity + +-- The rendering thread appears to pin itself to the first computing unit of +-- a computer. The first computing unit is often also used by othersoftware, +-- including the OS. Through empirical research the framerate of the game is a +-- lot more consistent when we do not give it access to the first computing +-- unit. + +-- That is what this section helps us do. The game functions best when it has +-- at least four computing units available. If we detect someone has 6 or more +-- computing units then we take the game off the first compute unit. + +-- Note that we can not make the distinction between real computing units and +-- computing units that originate from technology such as hyperthreading. + +local SetProcessPriority = rawget(_G, "SetProcessPriority") +local GetProcessAffinityMask = rawget(_G, "GetProcessAffinityMask") +local SetProcessAffinityMask = rawget(_G, "SetProcessAffinityMask") + +if SetProcessPriority and GetProcessAffinityMask and SetProcessAffinityMask then + + -- priority values can be found at: + -- - https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setpriorityclass + local success = SetProcessPriority(0x00000080) + if success then + LOG("Process - priority set to: 'high'") + else + LOG("Process - Failed to adjust process priority, this may impact your framerate") + end + + -- affinity values acts like a bit mask, we retrieve the mask and shift it if we think there are sufficient computing units + local success, processAffinityMask, systemAffinityMask = GetProcessAffinityMask(); + if success then + -- system has 6 (logical) threads or more, skip first two computing units + if systemAffinityMask >= 63 then + processAffinityMask = systemAffinityMask & (systemAffinityMask << 2) + end + + -- update the afinity mask + if processAffinityMask != systemAffinityMask then + local success = SetProcessAffinityMask(processAffinityMask); + if success then + LOG("Process - affinity set to: " .. tostring(processAffinityMask)) + else + LOG("Process - Failed to adjust the process affinity, this may impact your framerate") + end + end + else + LOG("Process - Failed to retrieve the process affinity, this may impact your framerate") + end +else + LOG("Process - Failed to find process priority and affinity related functions, this may impact your framerate") +end + +--#endregion + + -- upvalued performance local dofile = dofile @@ -64,6 +123,21 @@ local function LowerHashTable(t) return o end +local function FindFilesWithExtension(dir, extension, prepend, files) + files = files or { } + + for k, file in IoDir(dir .. "/*") do + if not (file == '.' or file == '..') then + if StringSub(file, -3) == extension then + TableInsert(files, prepend .. "/" .. file) + end + FindFilesWithExtension(dir .. "/" .. file, extension, prepend .. "/" .. file, files) + end + end + + return files +end + -- mods that have been integrated, based on folder name local integratedMods = { } integratedMods["nvidia fix"] = true @@ -144,8 +218,8 @@ allowedAssetsNxt = LowerHashTable(allowedAssetsNxt) -- default wave banks to prevent collisions local soundsBlocked = { } -local faSounds = IoDir(fa_path .. '/sounds/*') -for k, v in faSounds do +local sounds = FindFilesWithExtension(fa_path .. '/sounds', "xwb", "/sounds") +for k, v in sounds do if v == '.' or v == '..' then continue end @@ -300,19 +374,19 @@ local function MountMapContent(dir) MountDirectory(dir .. "/" .. map .. '/movies', '/movies') end elseif folder == 'sounds' then + local banks = FindFilesWithExtension(dir .. '/' .. map .. "/sounds", "xwb", "/sounds") + -- find conflicting files local conflictingFiles = { } - for _, file in IoDir(dir .. '/' .. map .. '/sounds/*') do - if not (file == '.' or file == '..') then - local identifier = StringLower(file) - if soundsBlocked[identifier] then - TableInsert(conflictingFiles, { file = file, conflict = soundsBlocked[identifier] }) - else - soundsBlocked[identifier] = StringLower(map) - end + for _, bank in banks do + local identifier = StringLower(bank) + if soundsBlocked[identifier] then + TableInsert(conflictingFiles, { file = bank, conflict = soundsBlocked[identifier] }) + else + soundsBlocked[identifier] = StringLower(map) end end - + -- report them if they exist and do not mount if TableGetn(conflictingFiles) > 0 then LOG("Found conflicting sound banks for map: '" .. map .. "', cannot mount the sound bank(s):") @@ -477,23 +551,23 @@ local function MountModContent(dir) -- if we found a directory named 'sounds' then we mount its content if folder == 'sounds' then + local banks = FindFilesWithExtension(dir .. '/' .. mod .. "/sounds", "xwb", "/sounds") + -- find conflicting files local conflictingFiles = { } - for _, file in IoDir(dir .. '/' .. mod .. '/sounds/*') do - if not (file == '.' or file == '..') then - local identifier = StringLower(file) - if soundsBlocked[identifier] then - TableInsert(conflictingFiles, { file = file, conflict = soundsBlocked[identifier] }) - else - soundsBlocked[identifier] = StringLower(mod) - end + for _, bank in banks do + local identifier = StringLower(bank) + if soundsBlocked[identifier] then + TableInsert(conflictingFiles, { file = bank, conflict = soundsBlocked[identifier] }) + else + soundsBlocked[identifier] = StringLower(mod) end end - + -- report them if they exist and do not mount if TableGetn(conflictingFiles) > 0 then LOG("Found conflicting sound banks for mod: '" .. mod .. "', cannot mount the sound bank(s):") - for k, v in conflictingFiles do + for _, v in conflictingFiles do LOG(" - Conflicting sound bank: '" .. v.file .. "' of mod '" .. mod .. "' is conflicting with a sound bank from: '" .. v.conflict .. "'" ) end -- else, mount folder