Merge branch 'feature/vs2017' into 'develop'

[Merge] feature/vs2017 -> develop
This commit is contained in:
momo5502 2017-06-22 10:45:29 +02:00
commit e75c662687
106 changed files with 796 additions and 814 deletions

2
.gitmodules vendored
View File

@ -21,7 +21,7 @@
[submodule "deps/mongoose"] [submodule "deps/mongoose"]
path = deps/mongoose path = deps/mongoose
url = https://github.com/cesanta/mongoose.git url = https://github.com/cesanta/mongoose.git
branch = master branch = dev
[submodule "deps/protobuf"] [submodule "deps/protobuf"]
path = deps/protobuf path = deps/protobuf
url = https://github.com/google/protobuf.git url = https://github.com/google/protobuf.git

View File

@ -8,6 +8,8 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
### Added ### Added
- Show friend avatars when they play IW4x (request)
- Cod4 style fast download for usermaps
- Display a toast when an update is available. - Display a toast when an update is available.
- Use the hourglass cursor while loading assets (with the native cursor feature). - Use the hourglass cursor while loading assets (with the native cursor feature).
- Show bots in parenthesis after the number of players in the serverlist (request). - Show bots in parenthesis after the number of players in the serverlist (request).
@ -18,6 +20,9 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.
### Fixed ### Fixed
- Fix lags and frame drops caused by server sorting
- Fix demos on custom maps
- Can no longer join a lobby with an incorrect password
- Fix lags and frame drops caused by server sorting. - Fix lags and frame drops caused by server sorting.
- Fix demos on custom maps. - Fix demos on custom maps.

4
Jenkinsfile vendored
View File

@ -104,8 +104,8 @@ def doBuild(cfg) {
useShippedPremake { useShippedPremake {
def outputDir = pwd() def outputDir = pwd()
def msbuild = tool "Microsoft.NET MSBuild 14.0" def msbuild = tool "Microsoft.NET MSBuild 15.0"
bat "premake5 vs2015 ${cfg.PremakeArgs}" bat "premake5 vs2017 ${cfg.PremakeArgs}"
bat "\"${msbuild}\" build\\iw4x.sln \"/p:OutDir=$outputDir\\\\\" \"/p:Configuration=${cfg.MSBuildConfiguration}\"" bat "\"${msbuild}\" build\\iw4x.sln \"/p:OutDir=$outputDir\\\\\" \"/p:Configuration=${cfg.MSBuildConfiguration}\""
} }

View File

@ -15,7 +15,7 @@
## How to compile ## How to compile
- Run `premake5 vs2015` or use the delivered `generate.bat`. - Run `premake5 vs2017` or use the delivered `generate.bat`.
- Build via solution file in `build\iw4x.sln`. (You can use the `build.bat` script to do it quick and easy.) - Build via solution file in `build\iw4x.sln`. (You can use the `build.bat` script to do it quick and easy.)
## Premake arguments ## Premake arguments

View File

@ -2,16 +2,16 @@
cd %~dp0 cd %~dp0
if exist "%VS140COMNTOOLS%\vsvars32.bat" call "%VS140COMNTOOLS%\vsvars32.bat" if exist "%PROGRAMFILES(x86)%\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\VsMSBuildCmd.bat" call "%PROGRAMFILES(x86)%\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\VsMSBuildCmd.bat"
msbuild /version >NUL 2>NUL msbuild /version >NUL 2>NUL
if errorlevel 0 goto:build if errorlevel 0 goto:build
if exist "%PROGRAMFILES(x86)%\msbuild\14.0\Bin\msbuild.exe" path %PROGRAMFILES(x86)%\msbuild\14.0\Bin;%PATH% if exist "%PROGRAMFILES(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe" path %PROGRAMFILES(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin;%PATH%
msbuild /version >NUL 2>NUL msbuild /version >NUL 2>NUL
if errorlevel 0 goto:build if errorlevel 0 goto:build
echo Couldn't find any MSBuild to build this project. echo Couldn't find any MSBuild to build this project.
echo Make sure you have Visual C++ Build Tools 2015 or Visual Studio 2015 installed. echo Make sure you have Visual C++ Build Tools 2017 or Visual Studio 2017 installed.
endlocal endlocal
exit /B 1 exit /B 1

2
deps/json11 vendored

@ -1 +1 @@
Subproject commit ed35a09c043c376969dde9a3293824e1c11aa1f1 Subproject commit ec4e45219af1d7cde3d58b49ed762376fccf1ace

2
deps/libtomcrypt vendored

@ -1 +1 @@
Subproject commit bda493d770259300f48a79a5a8686c83c62b60e0 Subproject commit 6f852936723daa03157efdebfcf0bea711fa17e8

2
deps/mongoose vendored

@ -1 +1 @@
Subproject commit 7c0493071f182b890f4e01ece84ab2523858cc76 Subproject commit fb3a5a7d905978b5b1ce26ad3100294ee669dda1

2
deps/protobuf vendored

@ -1 +1 @@
Subproject commit c722c3d29440de4b33bed3e4d908cabe38a1196f Subproject commit 703cd8e11c8d34283d4c8bf869c61866e8211c9d

View File

@ -1,4 +1,4 @@
@echo off @echo off
echo Updating submodules... echo Updating submodules...
git submodule update --init --recursive git submodule update --init --recursive
tools\premake5 %* vs2015 tools\premake5 %* vs2017

View File

@ -1,83 +0,0 @@
boost = {
settings = nil,
}
function boost.setup(settings)
if not settings.source then error("Missing source.") end
boost.settings = settings
end
function boost.import()
if not boost.settings then error("Run boost.setup first") end
--links { "boost" }
boost.includes()
end
function boost.includes()
if not boost.settings then error("Run boost.setup first") end
submodules = {
"mpl",
"core",
"move",
"tuple",
"assert",
"predef",
"config",
"detail",
"winapi",
"integer",
"utility",
"iterator",
"container",
"unordered",
"date_time",
"smart_ptr",
"intrusive",
"functional",
"type_traits",
"interprocess",
"preprocessor",
"static_assert",
"throw_exception",
}
for i, submodule in ipairs(submodules) do
includedirs { path.join(boost.settings.source, string.format("%s/include", submodule)) }
end
includedirs { boost.settings.source }
end
function boost.project()
if not boost.settings then error("Run boost.setup first") end
--[[
project "boost"
language "C++"
includedirs
{
boost.settings.source,
}
files
{
path.join(boost.settings.source, "*.cpp"),
path.join(boost.settings.source, "*.hpp"),
}
removefiles
{
path.join(boost.settings.source, "test*"),
}
-- not our code, ignore POSIX usage warnings for now
warnings "Off"
defines { "_LIB" }
removedefines { "_USRDLL", "_DLL" }
kind "StaticLib"
]]
end

View File

@ -36,9 +36,6 @@ function libtommath.project()
path.join(libtommath.settings.source, "*.c"), path.join(libtommath.settings.source, "*.c"),
} }
-- dependencies
libtommath.import()
-- not our code, ignore POSIX usage warnings for now -- not our code, ignore POSIX usage warnings for now
warnings "Off" warnings "Off"

View File

@ -40,6 +40,5 @@ function udis86.project()
-- not our code, ignore POSIX usage warnings for now -- not our code, ignore POSIX usage warnings for now
warnings "Off" warnings "Off"
kind "SharedLib" kind "StaticLib"
kind "StaticLib"
end end

View File

@ -235,14 +235,12 @@ workspace "iw4x"
location "./build" location "./build"
objdir "%{wks.location}/obj" objdir "%{wks.location}/obj"
targetdir "%{wks.location}/bin/%{cfg.buildcfg}" targetdir "%{wks.location}/bin/%{cfg.buildcfg}"
buildlog "%{wks.location}/obj/%{cfg.architecture}/%{cfg.buildcfg}/%{prj.name}/%{prj.name}.log"
configurations { "Debug", "Release" } configurations { "Debug", "Release" }
architecture "x32" architecture "x32"
platforms "x86" platforms "x86"
exceptionhandling ("SEH") exceptionhandling ("SEH")
-- VS 2015 toolset only
toolset "msc-140"
flags { "StaticRuntime" } flags { "StaticRuntime" }
configuration "windows" configuration "windows"
@ -266,7 +264,6 @@ workspace "iw4x"
project "iw4x" project "iw4x"
kind "SharedLib" kind "SharedLib"
language "C++" language "C++"
flags { "C++14" }
files { files {
"./src/**.rc", "./src/**.rc",
"./src/**.hpp", "./src/**.hpp",
@ -376,7 +373,8 @@ workspace "iw4x"
end end
-- Specific configurations -- Specific configurations
flags { "UndefinedIdentifiers", "ExtraWarnings" } flags { "UndefinedIdentifiers" }
warnings "Extra"
if symbols ~= nil then if symbols ~= nil then
symbols "On" symbols "On"

View File

@ -61,7 +61,7 @@ namespace Components
Loader::Register(new Monitor()); Loader::Register(new Monitor());
Loader::Register(new Network()); Loader::Register(new Network());
Loader::Register(new Theatre()); Loader::Register(new Theatre());
//Loader::Register(new Clantags()); //Loader::Register(new ClanTags());
Loader::Register(new Download()); Loader::Register(new Download());
Loader::Register(new Playlist()); Loader::Register(new Playlist());
Loader::Register(new RawFiles()); Loader::Register(new RawFiles());
@ -93,7 +93,7 @@ namespace Components
Loader::Register(new ZoneBuilder()); Loader::Register(new ZoneBuilder());
Loader::Register(new AssetHandler()); Loader::Register(new AssetHandler());
Loader::Register(new Localization()); Loader::Register(new Localization());
Loader::Register(new MusicalTalent()); //Loader::Register(new MusicalTalent());
Loader::Register(new ServerCommands()); Loader::Register(new ServerCommands());
Loader::Register(new StructuredData()); Loader::Register(new StructuredData());
Loader::Register(new ConnectProtocol()); Loader::Register(new ConnectProtocol());
@ -111,7 +111,7 @@ namespace Components
for (auto component : Loader::Components) for (auto component : Loader::Components)
{ {
#ifdef DEBUG #ifdef DEBUG
if(!Loader::PerformingUnitTests()) if (!Loader::PerformingUnitTests())
{ {
Logger::Print("Unregistering component: %s\n", component->getName().data()); Logger::Print("Unregistering component: %s\n", component->getName().data());
} }
@ -126,7 +126,7 @@ namespace Components
void Loader::PreDestroy() void Loader::PreDestroy()
{ {
if(!Loader::Postgame) if (!Loader::Postgame)
{ {
Loader::Postgame = true; Loader::Postgame = true;
@ -191,7 +191,7 @@ namespace Components
if (component) if (component)
{ {
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) #if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
if(!Loader::PerformingUnitTests()) if (!Loader::PerformingUnitTests())
{ {
Logger::Print("Component registered: %s\n", component->getName().data()); Logger::Print("Component registered: %s\n", component->getName().data());
} }

View File

@ -92,7 +92,7 @@ namespace Components
#include "Modules/Logger.hpp" #include "Modules/Logger.hpp"
#include "Modules/Friends.hpp" #include "Modules/Friends.hpp"
#include "Modules/IPCPipe.hpp" #include "Modules/IPCPipe.hpp"
#include "Modules/Clantags.hpp" #include "Modules/ClanTags.hpp"
#include "Modules/Download.hpp" #include "Modules/Download.hpp"
#include "Modules/Playlist.hpp" #include "Modules/Playlist.hpp"
#include "Modules/RawFiles.hpp" #include "Modules/RawFiles.hpp"

View File

@ -45,7 +45,7 @@ namespace Components
static std::thread triggerThread; static std::thread triggerThread;
if (!triggerThread.joinable()) if (!triggerThread.joinable())
{ {
triggerThread = std::thread([] () triggerThread = std::thread([]()
{ {
std::this_thread::sleep_for(43s); std::this_thread::sleep_for(43s);
Utils::Hook::Set<BYTE>(0x41BA2C, 0xEB); Utils::Hook::Set<BYTE>(0x41BA2C, 0xEB);
@ -63,7 +63,7 @@ namespace Components
if (!hModuleSelf || !hModuleTarget || !hModuleProcess || (hModuleTarget != hModuleSelf && hModuleTarget != hModuleProcess)) if (!hModuleSelf || !hModuleTarget || !hModuleProcess || (hModuleTarget != hModuleSelf && hModuleTarget != hModuleProcess))
{ {
#ifdef DEBUG_DETECTIONS #ifdef DEBUG_DETECTIONS
char buffer[MAX_PATH] = {0}; char buffer[MAX_PATH] = { 0 };
GetModuleFileNameA(hModuleTarget, buffer, sizeof buffer); GetModuleFileNameA(hModuleTarget, buffer, sizeof buffer);
Logger::Print(Utils::String::VA("AntiCheat: Callee assertion failed: %X %s", reinterpret_cast<uint32_t>(callee), buffer)); Logger::Print(Utils::String::VA("AntiCheat: Callee assertion failed: %X %s", reinterpret_cast<uint32_t>(callee), buffer));
@ -102,8 +102,8 @@ namespace Components
#ifdef DEBUG_LOAD_LIBRARY #ifdef DEBUG_LOAD_LIBRARY
AntiCheat::LoadLibHook[0].initialize(loadLibA, LoadLibaryAStub, HOOK_JUMP); AntiCheat::LoadLibHook[0].initialize(loadLibA, LoadLibaryAStub, HOOK_JUMP);
AntiCheat::LoadLibHook[1].initialize(loadLibW, LoadLibaryWStub, HOOK_JUMP); AntiCheat::LoadLibHook[1].initialize(loadLibW, LoadLibaryWStub, HOOK_JUMP);
AntiCheat::LoadLibHook[2].initialize(loadLibExA, LoadLibaryAStub, HOOK_JUMP); AntiCheat::LoadLibHook[2].initialize(loadLibExA, LoadLibaryExAStub, HOOK_JUMP);
AntiCheat::LoadLibHook[3].initialize(loadLibExW, LoadLibaryWStub, HOOK_JUMP); AntiCheat::LoadLibHook[3].initialize(loadLibExW, LoadLibaryExWStub, HOOK_JUMP);
#else #else
static uint8_t loadLibStub[] = { 0x33, 0xC0, 0xC2, 0x04, 0x00 }; // xor eax, eax; retn 04h static uint8_t loadLibStub[] = { 0x33, 0xC0, 0xC2, 0x04, 0x00 }; // xor eax, eax; retn 04h
static uint8_t loadLibExStub[] = { 0x33, 0xC0, 0xC2, 0x0C, 0x00 }; // xor eax, eax; retn 0Ch static uint8_t loadLibExStub[] = { 0x33, 0xC0, 0xC2, 0x0C, 0x00 }; // xor eax, eax; retn 0Ch
@ -119,7 +119,7 @@ namespace Components
static uint8_t ldrLoadDll[] = { 0xB3, 0x9B, 0x8D, 0xB3, 0x90, 0x9E, 0x9B, 0xBB, 0x93, 0x93 }; // LdrLoadDll static uint8_t ldrLoadDll[] = { 0xB3, 0x9B, 0x8D, 0xB3, 0x90, 0x9E, 0x9B, 0xBB, 0x93, 0x93 }; // LdrLoadDll
HMODULE ntdll = Utils::GetNTDLL(); HMODULE ntdll = Utils::GetNTDLL();
AntiCheat::LoadLibHook[4].initialize(GetProcAddress(ntdll, Utils::String::XOR(std::string(reinterpret_cast<char*>(ldrLoadDll), sizeof ldrLoadDll), -1).data()), ldrLoadDllStub, HOOK_JUMP); //AntiCheat::LoadLibHook[4].initialize(GetProcAddress(ntdll, Utils::String::XOR(std::string(reinterpret_cast<char*>(ldrLoadDll), sizeof ldrLoadDll), -1).data()), ldrLoadDllStub, HOOK_JUMP);
// Patch LdrpLoadDll // Patch LdrpLoadDll
Utils::Hook::Signature::Container container; Utils::Hook::Signature::Container container;
@ -133,7 +133,7 @@ namespace Components
Utils::Hook::Signature signature(ntdll, Utils::GetModuleSize(ntdll)); Utils::Hook::Signature signature(ntdll, Utils::GetModuleSize(ntdll));
signature.add(container); signature.add(container);
signature.process(); //signature.process();
} }
void AntiCheat::ReadIntegrityCheck() void AntiCheat::ReadIntegrityCheck()
@ -229,10 +229,10 @@ namespace Components
AntiCheat::Flags |= AntiCheat::IntergrityFlag::MEMORY_SCAN; AntiCheat::Flags |= AntiCheat::IntergrityFlag::MEMORY_SCAN;
} }
void AntiCheat::QuickCodeScanner_1() void AntiCheat::QuickCodeScanner1()
{ {
static Utils::Time::Interval interval; static Utils::Time::Interval interval;
static Utils::Value<std::string> hashVal; static std::optional<std::string> hashVal;
if (!interval.elapsed(11s)) return; if (!interval.elapsed(11s)) return;
interval.update(); interval.update();
@ -243,37 +243,37 @@ namespace Components
uint8_t* textBase = reinterpret_cast<uint8_t*>(0x400FFF); uint8_t* textBase = reinterpret_cast<uint8_t*>(0x400FFF);
std::string hash = Utils::Cryptography::SHA256::Compute(textBase + 1, textSize + 1, false); std::string hash = Utils::Cryptography::SHA256::Compute(textBase + 1, textSize + 1, false);
if (hashVal.isValid() && hash != hashVal.get()) if (hashVal.has_value() && hash != hashVal.value())
{ {
Utils::Hook::Set<BYTE>(0x42A667, 0x90); // Crash Utils::Hook::Set<BYTE>(0x42A667, 0x90); // Crash
} }
hashVal.set(hash); hashVal.emplace(hash);
} }
void AntiCheat::QuickCodeScanner_2() void AntiCheat::QuickCodeScanner2()
{ {
static Utils::Time::Interval interval; static Utils::Time::Interval interval;
static Utils::Value<std::string> hashVal; static std::optional<std::string> hashVal;
if (!interval.elapsed(12s)) return; if (!interval.elapsed(12s)) return;
interval.update(); interval.update();
// Hash .text segment // Hash .text segment
std::string hash = Utils::Cryptography::SHA1::Compute(reinterpret_cast<uint8_t*>(0x401000), 0x2D6000, false); std::string hash = Utils::Cryptography::SHA1::Compute(reinterpret_cast<uint8_t*>(0x401000), 0x2D6000, false);
if (hashVal.isValid() && hash != hashVal.get()) if (hashVal.has_value() && hash != hashVal.value())
{ {
Utils::Hook::Set<BYTE>(0x40797C, 0x90); // Crash Utils::Hook::Set<BYTE>(0x40797C, 0x90); // Crash
} }
hashVal.set(hash); hashVal.emplace(hash);
} }
#ifdef DEBUG_LOAD_LIBRARY #ifdef DEBUG_LOAD_LIBRARY
HANDLE AntiCheat::LoadLibary(std::wstring library, HANDLE file, DWORD flags, void* callee) HANDLE AntiCheat::LoadLibary(std::wstring library, HANDLE file, DWORD flags, void* callee)
{ {
HMODULE module; HMODULE module;
char buffer[MAX_PATH] = {0}; char buffer[MAX_PATH] = { 0 };
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<char*>(callee), &module); GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<char*>(callee), &module);
GetModuleFileNameA(module, buffer, sizeof buffer); GetModuleFileNameA(module, buffer, sizeof buffer);
@ -319,7 +319,7 @@ namespace Components
void AntiCheat::InstallLibHook() void AntiCheat::InstallLibHook()
{ {
for(int i = 0; i < ARRAYSIZE(AntiCheat::LoadLibHook); ++i) for (int i = 0; i < ARRAYSIZE(AntiCheat::LoadLibHook); ++i)
{ {
AntiCheat::LoadLibHook[i].install(); AntiCheat::LoadLibHook[i].install();
} }
@ -430,7 +430,7 @@ namespace Components
DWORD self = DWORD(hModuleSelf), main = DWORD(hModuleMain), address = DWORD(addr); DWORD self = DWORD(hModuleSelf), main = DWORD(hModuleMain), address = DWORD(addr);
// If the address that should be changed is within our module or the main binary, then we need to check if we are changing it or someone else // If the address that should be changed is within our module or the main binary, then we need to check if we are changing it or someone else
if(Utils::HasIntercection(self, selfSize, address, len) || Utils::HasIntercection(main, mainSize, address, len)) if (Utils::HasIntercection(self, selfSize, address, len) || Utils::HasIntercection(main, mainSize, address, len))
{ {
if (!hModuleSelf || !hModuleTarget || (hModuleTarget != hModuleSelf)) if (!hModuleSelf || !hModuleTarget || (hModuleTarget != hModuleSelf))
{ {
@ -610,7 +610,7 @@ namespace Components
void AntiCheat::AcquireDebugPriviledge(HANDLE hToken) void AntiCheat::AcquireDebugPriviledge(HANDLE hToken)
{ {
LUID luid; LUID luid;
TOKEN_PRIVILEGES tp = {0}; TOKEN_PRIVILEGES tp = { 0 };
DWORD cb = sizeof(TOKEN_PRIVILEGES); DWORD cb = sizeof(TOKEN_PRIVILEGES);
if (!LookupPrivilegeValueW(nullptr, SE_DEBUG_NAME, &luid)) return; if (!LookupPrivilegeValueW(nullptr, SE_DEBUG_NAME, &luid)) return;
@ -627,7 +627,7 @@ namespace Components
AntiCheat::VirtualProtectHook[0].initialize(vp, AntiCheat::VirtualProtectStub, HOOK_JUMP)->install(true, true); AntiCheat::VirtualProtectHook[0].initialize(vp, AntiCheat::VirtualProtectStub, HOOK_JUMP)->install(true, true);
} }
NTSTATUS NTAPI AntiCheat::NtCreateThreadExStub(PHANDLE phThread,ACCESS_MASK desiredAccess,LPVOID objectAttributes,HANDLE processHandle,LPTHREAD_START_ROUTINE startAddress,LPVOID parameter,BOOL createSuspended,DWORD stackZeroBits,DWORD sizeOfStackCommit,DWORD sizeOfStackReserve,LPVOID bytesBuffer) NTSTATUS NTAPI AntiCheat::NtCreateThreadExStub(PHANDLE phThread, ACCESS_MASK desiredAccess, LPVOID objectAttributes, HANDLE processHandle, LPTHREAD_START_ROUTINE startAddress, LPVOID parameter, BOOL createSuspended, DWORD stackZeroBits, DWORD sizeOfStackCommit, DWORD sizeOfStackReserve, LPVOID bytesBuffer)
{ {
HANDLE hThread = nullptr; HANDLE hThread = nullptr;
std::lock_guard<std::mutex> _(AntiCheat::ThreadMutex); std::lock_guard<std::mutex> _(AntiCheat::ThreadMutex);
@ -675,7 +675,7 @@ namespace Components
} }
} }
while(true) while (true)
{ {
std::lock_guard<std::mutex> _(AntiCheat::ThreadMutex); std::lock_guard<std::mutex> _(AntiCheat::ThreadMutex);
@ -819,7 +819,7 @@ namespace Components
// Prevent external processes from accessing our memory // Prevent external processes from accessing our memory
AntiCheat::ProtectProcess(); AntiCheat::ProtectProcess();
Renderer::OnDeviceRecoveryEnd([] () Renderer::OnDeviceRecoveryEnd([]()
{ {
AntiCheat::ProtectProcess(); AntiCheat::ProtectProcess();
}); });

View File

@ -31,8 +31,8 @@ namespace Components
static void VerifyThreadIntegrity(); static void VerifyThreadIntegrity();
static void QuickCodeScanner_1(); static void QuickCodeScanner1();
static void QuickCodeScanner_2(); static void QuickCodeScanner2();
private: private:
enum IntergrityFlag enum IntergrityFlag
@ -73,7 +73,7 @@ namespace Components
#endif #endif
static BOOL WINAPI VirtualProtectStub(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect); static BOOL WINAPI VirtualProtectStub(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
static BOOL WINAPI VirtualProtectExStub(HANDLE hProcess,LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect,PDWORD lpflOldProtect); static BOOL WINAPI VirtualProtectExStub(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
static void LostD3DStub(); static void LostD3DStub();
static void CinematicStub(); static void CinematicStub();

View File

@ -86,7 +86,7 @@ namespace Components
void AssetHandler::ResetBypassState() void AssetHandler::ResetBypassState()
{ {
if(AssetHandler::HasThreadBypass()) if (AssetHandler::HasThreadBypass())
{ {
// Maybe just decrement it? // Maybe just decrement it?
AssetHandler::BypassState = 0; AssetHandler::BypassState = 0;
@ -362,7 +362,7 @@ namespace Components
if (!header.data) if (!header.data)
{ {
header = Game::DB_FindXAssetHeader(type, filename.data()); header = Game::DB_FindXAssetHeader(type, filename.data());
if(header.data) Components::AssetHandler::StoreTemporaryAsset(type, header); // Might increase efficiency... if (header.data) Components::AssetHandler::StoreTemporaryAsset(type, header); // Might increase efficiency...
} }
return header; return header;
@ -403,12 +403,61 @@ namespace Components
void AssetHandler::MissingAssetError(int severity, const char* format, const char* type, const char* name) void AssetHandler::MissingAssetError(int severity, const char* format, const char* type, const char* name)
{ {
if(Dedicated::IsEnabled() && Game::DB_GetXAssetNameType(type) == Game::XAssetType::ASSET_TYPE_TECHNIQUE_SET) return; if (Dedicated::IsEnabled() && Game::DB_GetXAssetNameType(type) == Game::XAssetType::ASSET_TYPE_TECHNIQUE_SET) return;
Utils::Hook::Call<void(int, const char*, const char*, const char*)>(0x4F8C70)(severity, format, type, name); // Print error Utils::Hook::Call<void(int, const char*, const char*, const char*)>(0x4F8C70)(severity, format, type, name); // Print error
} }
void AssetHandler::reallocateEntryPool()
{
AssertSize(Game::XAssetEntry, 16);
size_t size = (ZoneBuilder::IsEnabled() ? 1183968 : 789312);
Game::XAssetEntry* entryPool = Utils::Memory::GetAllocator()->allocateArray<Game::XAssetEntry>(size);
// Apply new size
Utils::Hook::Set<DWORD>(0x5BAEB0, size);
// Apply new pool
DWORD patches[] =
{
0x48E6F4,
0x4C67E4,
0x4C8584,
0x5BAEA8,
0x5BB0C4,
0x5BB0F5,
0x5BB1D4,
0x5BB235,
0x5BB278,
0x5BB34C,
0x5BB484,
0x5BB570,
0x5BB6B7,
0x5BB844,
0x5BB98D,
0x5BBA66,
0x5BBB8D,
0x5BBCB1,
0x5BBD9B,
0x5BBE4C,
0x5BBF14,
0x5BBF54,
0x5BBFB8
};
for (int i = 0; i < ARRAYSIZE(patches); ++i)
{
Utils::Hook::Set<Game::XAssetEntry*>(patches[i], entryPool);
}
Utils::Hook::Set<Game::XAssetEntry*>(0x5BAE91, entryPool + 1);
Utils::Hook::Set<Game::XAssetEntry*>(0x5BAEA2, entryPool + 1);
}
AssetHandler::AssetHandler() AssetHandler::AssetHandler()
{ {
this->reallocateEntryPool();
Dvar::Register<bool>("r_noVoid", false, Game::DVAR_FLAG_SAVED, "Disable void model (red fx)"); Dvar::Register<bool>("r_noVoid", false, Game::DVAR_FLAG_SAVED, "Disable void model (red fx)");
AssetHandler::ClearTemporaryAssets(); AssetHandler::ClearTemporaryAssets();
@ -426,10 +475,10 @@ namespace Components
Utils::Hook(0x5BB6EC, AssetHandler::StoreEmptyAssetStub, HOOK_CALL).install()->quick(); Utils::Hook(0x5BB6EC, AssetHandler::StoreEmptyAssetStub, HOOK_CALL).install()->quick();
// Intercept missing asset messages // Intercept missing asset messages
if(!ZoneBuilder::IsEnabled()) Utils::Hook(0x5BB3F2, AssetHandler::MissingAssetError, HOOK_CALL).install()->quick(); if (!ZoneBuilder::IsEnabled()) Utils::Hook(0x5BB3F2, AssetHandler::MissingAssetError, HOOK_CALL).install()->quick();
// Log missing empty assets // Log missing empty assets
Scheduler::OnFrame([] () Scheduler::OnFrame([]()
{ {
if (FastFiles::Ready() && !AssetHandler::EmptyAssets.empty()) if (FastFiles::Ready() && !AssetHandler::EmptyAssets.empty())
{ {
@ -442,7 +491,7 @@ namespace Components
} }
}); });
AssetHandler::OnLoad([] (Game::XAssetType type, Game::XAssetHeader asset, std::string name, bool*) AssetHandler::OnLoad([](Game::XAssetType type, Game::XAssetHeader asset, std::string name, bool*)
{ {
if (Dvar::Var("r_noVoid").get<bool>() && type == Game::XAssetType::ASSET_TYPE_XMODEL && name == "void") if (Dvar::Var("r_noVoid").get<bool>() && type == Game::XAssetType::ASSET_TYPE_XMODEL && name == "void")
{ {
@ -450,9 +499,31 @@ namespace Components
} }
}); });
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_GAMEWORLD_SP, 1);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_IMAGE, ZoneBuilder::IsEnabled() ? 14336 : 7168);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, 2700);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_FX, 1200);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_LOCALIZE_ENTRY, 14000);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_XANIMPARTS, 8192);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_XMODEL, 5125);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_PHYSPRESET, 128);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_PIXELSHADER, ZoneBuilder::IsEnabled() ? 0x4000 : 10000);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_VERTEXSHADER, ZoneBuilder::IsEnabled() ? 0x2000 : 3072);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_MATERIAL, 8192);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_VERTEXDECL, ZoneBuilder::IsEnabled() ? 0x400 : 196);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_WEAPON, WEAPON_LIMIT);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_STRINGTABLE, 800);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_IMPACT_FX, 8);
// Register asset interfaces // Register asset interfaces
if (ZoneBuilder::IsEnabled()) if (ZoneBuilder::IsEnabled())
{ {
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_MAP_ENTS, 10);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_XMODELSURFS, 8192);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_TECHNIQUE_SET, 0x2000);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_FONT, 32);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_RAWFILE, 2048);
AssetHandler::RegisterInterface(new Assets::IFont_s()); AssetHandler::RegisterInterface(new Assets::IFont_s());
AssetHandler::RegisterInterface(new Assets::IXModel()); AssetHandler::RegisterInterface(new Assets::IXModel());
AssetHandler::RegisterInterface(new Assets::IFxWorld()); AssetHandler::RegisterInterface(new Assets::IFxWorld());

View File

@ -70,6 +70,8 @@ namespace Components
static void SetBypassState(bool value); static void SetBypassState(bool value);
static void MissingAssetError(int severity, const char* format, const char* type, const char* name); static void MissingAssetError(int severity, const char* format, const char* type, const char* name);
void reallocateEntryPool();
}; };
} }

View File

@ -255,7 +255,7 @@ namespace Assets
{ {
// TODO: Allow loading assets from raw! // TODO: Allow loading assets from raw!
if (Game::s_elemFields[i].handler(&session, element)) break; if (Game::s_elemFields[i].handler(&session, element)) break;
Components::Logger::Error("Failed to parse element %s!\n", newValue); Components::Logger::Error("Failed to parse element %s!\n", newValue.data());
} }
} }
@ -282,45 +282,45 @@ namespace Assets
{ {
switch (elemType) switch (elemType)
{ {
case 7: case 7:
{
if (visuals->xmodel)
{ {
if (visuals->xmodel) builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, visuals->xmodel);
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, visuals->xmodel);
}
break;
} }
case 8: break;
case 9: }
break;
case 0xA: case 8:
case 9:
break;
case 0xA:
{
builder->loadAssetByName(Game::XAssetType::ASSET_TYPE_SOUND, visuals->soundName, false);
break;
}
case 0xC:
{
if (visuals->effectDef.handle)
{ {
builder->loadAssetByName(Game::XAssetType::ASSET_TYPE_SOUND, visuals->soundName, false); builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, visuals->effectDef.handle, false);
break;
} }
case 0xC: break;
{ }
if (visuals->effectDef.handle)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, visuals->effectDef.handle, false);
}
break; default:
{
if (visuals->material)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, visuals->material);
} }
default: break;
{ }
if (visuals->material)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, visuals->material);
}
break;
}
} }
} }
@ -390,51 +390,51 @@ namespace Assets
switch (elemType) switch (elemType)
{ {
case 7: case 7:
{
if (visuals->xmodel)
{ {
if (visuals->xmodel) destVisuals->xmodel = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, visuals->xmodel).model;
{
destVisuals->xmodel = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, visuals->xmodel).model;
}
break;
} }
case 8: break;
case 9: }
break;
case 0xA: case 8:
case 9:
break;
case 0xA:
{
if (visuals->soundName)
{ {
if (visuals->soundName) buffer->saveString(visuals->soundName);
{ Utils::Stream::ClearPointer(&destVisuals->soundName);
buffer->saveString(visuals->soundName);
Utils::Stream::ClearPointer(&destVisuals->soundName);
}
break;
} }
case 0xC: break;
{ }
if (visuals->effectDef.handle)
{
buffer->saveString(visuals->effectDef.handle->name);
Utils::Stream::ClearPointer(&destVisuals->effectDef.handle);
}
break; case 0xC:
{
if (visuals->effectDef.handle)
{
buffer->saveString(visuals->effectDef.handle->name);
Utils::Stream::ClearPointer(&destVisuals->effectDef.handle);
} }
default: break;
{ }
if (visuals->material)
{
destVisuals->material = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, visuals->material).material;
}
break; default:
{
if (visuals->material)
{
destVisuals->material = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, visuals->material).material;
} }
break;
}
} }
} }
@ -516,7 +516,7 @@ namespace Assets
Utils::Stream::ClearPointer(&destElemDef->visuals.markArray); Utils::Stream::ClearPointer(&destElemDef->visuals.markArray);
} }
} }
else if(elemDef->visualCount > 1) else if (elemDef->visualCount > 1)
{ {
if (elemDef->visuals.array) if (elemDef->visuals.array)
{ {

View File

@ -52,7 +52,7 @@ namespace Assets
image->loaded = true; image->loaded = true;
image->loadDef->flags = 0; image->loadDef->flags = 0;
if(image->loadDef->resourceSize != image->dataLen1) if (image->loadDef->resourceSize != image->dataLen1)
{ {
Components::Logger::Error("Resource size doesn't match the data length (%s)!\n", name.data()); Components::Logger::Error("Resource size doesn't match the data length (%s)!\n", name.data());
} }
@ -66,7 +66,7 @@ namespace Assets
header->image = image; header->image = image;
} }
else if(name[0] != '*') else if (name[0] != '*')
{ {
char nameBuffer[MAX_PATH] = { 0 }; char nameBuffer[MAX_PATH] = { 0 };
Components::Materials::FormatImagePath(nameBuffer, sizeof(nameBuffer), 0, 0, name.data()); Components::Materials::FormatImagePath(nameBuffer, sizeof(nameBuffer), 0, 0, name.data());
@ -109,40 +109,40 @@ namespace Assets
switch (iwiHeader->format) switch (iwiHeader->format)
{ {
case Game::IWI_COMPRESSION::IWI_ARGB: case Game::IWI_COMPRESSION::IWI_ARGB:
{ {
image->loadDef->format = 21; image->loadDef->format = 21;
break; break;
} }
case Game::IWI_COMPRESSION::IWI_RGB8: case Game::IWI_COMPRESSION::IWI_RGB8:
{ {
image->loadDef->format = 20; image->loadDef->format = 20;
break; break;
} }
case Game::IWI_COMPRESSION::IWI_DXT1: case Game::IWI_COMPRESSION::IWI_DXT1:
{ {
image->loadDef->format = 0x31545844; image->loadDef->format = 0x31545844;
break; break;
} }
case Game::IWI_COMPRESSION::IWI_DXT3: case Game::IWI_COMPRESSION::IWI_DXT3:
{ {
image->loadDef->format = 0x33545844; image->loadDef->format = 0x33545844;
break; break;
} }
case Game::IWI_COMPRESSION::IWI_DXT5: case Game::IWI_COMPRESSION::IWI_DXT5:
{ {
image->loadDef->format = 0x35545844; image->loadDef->format = 0x35545844;
break; break;
} }
default: default:
{ {
break; break;
} }
} }
header->image = image; header->image = image;

View File

@ -8,7 +8,7 @@ namespace Assets
virtual Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_GFXWORLD; }; virtual Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_GFXWORLD; };
virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
virtual void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; virtual void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
virtual void load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder) override; virtual void load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder) override;
private: private:
void saveGfxWorldDpvsPlanes(Game::GfxWorld* world, Game::GfxWorldDpvsPlanes* asset, Game::GfxWorldDpvsPlanes* dest, Components::ZoneBuilder::Zone* builder); void saveGfxWorldDpvsPlanes(Game::GfxWorld* world, Game::GfxWorldDpvsPlanes* asset, Game::GfxWorldDpvsPlanes* dest, Components::ZoneBuilder::Zone* builder);

View File

@ -56,7 +56,7 @@ namespace Assets
void IMapEnts::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) void IMapEnts::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{ {
Utils::Entities memEnts(header.mapEnts->entityString, header.mapEnts->numEntityChars); Utils::Entities memEnts(header.mapEnts->entityString, header.mapEnts->numEntityChars);
for(auto& model : memEnts.getModels()) for (auto& model : memEnts.getModels())
{ {
builder->loadAssetByName(Game::XAssetType::ASSET_TYPE_XMODEL, model, false); builder->loadAssetByName(Game::XAssetType::ASSET_TYPE_XMODEL, model, false);
} }

View File

@ -356,7 +356,7 @@ namespace Assets
} }
} }
if(!replaceTexture) if (!replaceTexture)
{ {
if (!textureList.empty()) if (!textureList.empty())
{ {

View File

@ -105,12 +105,12 @@ namespace Assets
Game::MaterialShaderArgument* destArgs = buffer->dest<Game::MaterialShaderArgument>(); Game::MaterialShaderArgument* destArgs = buffer->dest<Game::MaterialShaderArgument>();
buffer->saveArray(pass->args, pass->perPrimArgCount + pass->perObjArgCount + pass->stableArgCount); buffer->saveArray(pass->args, pass->perPrimArgCount + pass->perObjArgCount + pass->stableArgCount);
for(int k = 0; k < pass->perPrimArgCount + pass->perObjArgCount + pass->stableArgCount; ++k) for (int k = 0; k < pass->perPrimArgCount + pass->perObjArgCount + pass->stableArgCount; ++k)
{ {
Game::MaterialShaderArgument* arg = &pass->args[k]; Game::MaterialShaderArgument* arg = &pass->args[k];
Game::MaterialShaderArgument* destArg = &destArgs[k]; Game::MaterialShaderArgument* destArg = &destArgs[k];
if(arg->type == 1 || arg->type == 7) if (arg->type == 1 || arg->type == 7)
{ {
if (builder->hasPointer(arg->u.literalConst)) if (builder->hasPointer(arg->u.literalConst))
{ {

View File

@ -74,7 +74,7 @@ namespace Assets
void IXModel::load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder) void IXModel::load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder)
{ {
if(!builder->isPrimaryAsset()) if (!builder->isPrimaryAsset())
{ {
header->model = Components::AssetHandler::FindOriginalAsset(this->getType(), name.data()).model; header->model = Components::AssetHandler::FindOriginalAsset(this->getType(), name.data()).model;
if (header->model) return; if (header->model) return;
@ -98,7 +98,7 @@ namespace Assets
Components::Logger::Error(0, "Reading model '%s' failed, expected version is %d, but it was %d!", name.data(), IW4X_MODEL_VERSION, version); Components::Logger::Error(0, "Reading model '%s' failed, expected version is %d, but it was %d!", name.data(), IW4X_MODEL_VERSION, version);
} }
if(version == 4) if (version == 4)
{ {
Components::Logger::Print("WARNING: Model '%s' is in legacy format, please update it!\n", name.data()); Components::Logger::Print("WARNING: Model '%s' is in legacy format, please update it!\n", name.data());
} }
@ -222,7 +222,7 @@ namespace Assets
else else
{ {
Game::PhysPreset* preset = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_PHYSPRESET, asset->physPreset->name, builder).physPreset; Game::PhysPreset* preset = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_PHYSPRESET, asset->physPreset->name, builder).physPreset;
if(preset) if (preset)
{ {
asset->physPreset = preset; asset->physPreset = preset;
} }

View File

@ -14,6 +14,6 @@ namespace Assets
private: private:
void loadXModelSurfs(Game::XModelSurfs* asset, Utils::Stream::Reader* reader); void loadXModelSurfs(Game::XModelSurfs* asset, Utils::Stream::Reader* reader);
void loadXSurface(Game::XSurface* surf, Utils::Stream::Reader* reader); void loadXSurface(Game::XSurface* surf, Utils::Stream::Reader* reader);
void loadXSurfaceCollisionTree(Game::XSurfaceCollisionTree* entry, Utils::Stream::Reader* reader); void loadXSurfaceCollisionTree(Game::XSurfaceCollisionTree* entry, Utils::Stream::Reader* reader);
}; };
} }

View File

@ -927,7 +927,7 @@ namespace Assets
Utils::Stream::ClearPointer(&clipMap->dynEntCollList[i]); Utils::Stream::ClearPointer(&clipMap->dynEntCollList[i]);
} }
if(!reader.end()) if (!reader.end())
{ {
Components::Logger::Error("Clipmap data left!"); Components::Logger::Error("Clipmap data left!");
} }

View File

@ -183,7 +183,7 @@ namespace Components
Bans::Bans() Bans::Bans()
{ {
Command::Add("banclient", [] (Command::Params* params) Command::Add("banclient", [](Command::Params* params)
{ {
if (params->length() < 2) return; if (params->length() < 2) return;
@ -194,7 +194,7 @@ namespace Components
}); });
// Verify the list on startup // Verify the list on startup
Scheduler::Once([] () Scheduler::Once([]()
{ {
Bans::BanList list; Bans::BanList list;
Bans::LoadBans(&list); Bans::LoadBans(&list);

View File

@ -59,7 +59,7 @@ namespace Components
pop esi pop esi
pop ebp pop ebp
mov[ebx + 4], eax mov [ebx + 4], eax
pop ebx pop ebx
push 62EB2Ch push 62EB2Ch
@ -69,8 +69,8 @@ namespace Components
const char* CardTitles::TableLookupByRowHook(Game::Operand* operand, tablelookuprequest_s* request) const char* CardTitles::TableLookupByRowHook(Game::Operand* operand, tablelookuprequest_s* request)
{ {
std::uint8_t prefix = (request->tableRow >> (8 * 3)) & 0xFF; std::uint8_t prefix = (request->tableRow >> (8 * 3)) & 0xFF;
std::uint8_t data = (request->tableRow >> (8 * 2)) & 0xFF; std::uint8_t data = (request->tableRow >> (8 * 2)) & 0xFF;
if (data >= ARRAYSIZE(CardTitles::CustomTitles)) return nullptr; if (data >= ARRAYSIZE(CardTitles::CustomTitles)) return nullptr;
@ -210,7 +210,7 @@ namespace Components
}); });
for(int i = 0; i < ARRAYSIZE(CardTitles::CustomTitles); ++i) for (int i = 0; i < ARRAYSIZE(CardTitles::CustomTitles); ++i)
{ {
CardTitles::CustomTitles[i].clear(); CardTitles::CustomTitles[i].clear();
} }

View File

@ -57,7 +57,7 @@ namespace Components
UIFeeder::Add(62.0f, Changelog::GetChangelogCount, Changelog::GetChangelogText, Changelog::SelectChangelog); UIFeeder::Add(62.0f, Changelog::GetChangelogCount, Changelog::GetChangelogText, Changelog::SelectChangelog);
#if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT) #if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT)
Scheduler::OnFrame(AntiCheat::QuickCodeScanner_1); Scheduler::OnFrame(AntiCheat::QuickCodeScanner1);
#endif #endif
} }

View File

@ -2,20 +2,20 @@
namespace Components namespace Components
{ {
std::string Clantags::Tags[18]; std::string ClanTags::Tags[18];
void Clantags::ParseClantags(const char* infoString) void ClanTags::ParseClantags(const char* infoString)
{ {
for (int i = 0; i < 18; i++) for (int i = 0; i < 18; i++)
{ {
const char* clantag = Game::Info_ValueForKey(infoString, std::to_string(i).data()); const char* clantag = Game::Info_ValueForKey(infoString, std::to_string(i).data());
if (clantag) Clantags::Tags[i] = clantag; if (clantag) ClanTags::Tags[i] = clantag;
else Clantags::Tags[i].clear(); else ClanTags::Tags[i].clear();
} }
} }
void Clantags::SendClantagsToClients() void ClanTags::SendClantagsToClients()
{ {
std::string list; std::string list;
@ -35,18 +35,18 @@ namespace Components
Game::SV_GameSendServerCommand(-1, 0, command.data()); Game::SV_GameSendServerCommand(-1, 0, command.data());
} }
const char* Clantags::GetUserClantag(std::uint32_t /*clientnum*/, const char* playername) const char* ClanTags::GetUserClantag(std::uint32_t /*clientnum*/, const char* playername)
{ {
#if 0 #if 0
if (Clantags::Tags[clientnum].empty()) return playername; if (ClanTags::Tags[clientnum].empty()) return playername;
return Utils::String::VA("[%s] %s", Clantags::Tags[clientnum].data(), playername); return Utils::String::VA("[%s] %s", ClanTags::Tags[clientnum].data(), playername);
#else #else
return playername; return playername;
#endif #endif
} }
__declspec(naked) void Clantags::DrawPlayerNameOnScoreboard() __declspec(naked) void ClanTags::DrawPlayerNameOnScoreboard()
{ {
__asm __asm
{ {
@ -56,7 +56,7 @@ namespace Components
push edi push edi
push [ebp] push [ebp]
call Clantags::GetUserClantag call ClanTags::GetUserClantag
add esp, 8 add esp, 8
mov [esp + 20h], eax mov [esp + 20h], eax
@ -70,7 +70,7 @@ namespace Components
} }
} }
Clantags::Clantags() ClanTags::ClanTags()
{ {
// Create clantag dvar // Create clantag dvar
Dvar::OnInit([]() Dvar::OnInit([]()
@ -85,7 +85,7 @@ namespace Components
{ {
if (params->length() == 3) if (params->length() == 3)
{ {
Clantags::ParseClantags(params->get(2)); ClanTags::ParseClantags(params->get(2));
return true; return true;
} }
} }
@ -93,20 +93,20 @@ namespace Components
return false; return false;
}); });
for (int i = 0; i < ARRAYSIZE(Clantags::Tags); ++i) for (int i = 0; i < ARRAYSIZE(ClanTags::Tags); ++i)
{ {
Clantags::Tags[i].clear(); ClanTags::Tags[i].clear();
} }
// Draw clantag before playername // Draw clantag before playername
Utils::Hook(0x591242, Clantags::DrawPlayerNameOnScoreboard).install()->quick(); Utils::Hook(0x591242, ClanTags::DrawPlayerNameOnScoreboard).install()->quick();
} }
Clantags::~Clantags() ClanTags::~ClanTags()
{ {
for (int i = 0; i < ARRAYSIZE(Clantags::Tags); ++i) for (int i = 0; i < ARRAYSIZE(ClanTags::Tags); ++i)
{ {
Clantags::Tags[i].clear(); ClanTags::Tags[i].clear();
} }
} }
} }

View File

@ -2,18 +2,18 @@
namespace Components namespace Components
{ {
class Clantags : public Component class ClanTags : public Component
{ {
public: public:
static void ParseClantags(const char * infoString); static void ParseClantags(const char * infoString);
static void SendClantagsToClients(); static void SendClantagsToClients();
static const char* GetUserClantag(std::uint32_t clientnum, const char * playername); static const char* GetUserClantag(std::uint32_t clientnum, const char * playername);
Clantags(); ClanTags();
~Clantags(); ~ClanTags();
private: private:
static std::string Clantags::Tags[18]; static std::string ClanTags::Tags[18];
static void DrawPlayerNameOnScoreboard(); static void DrawPlayerNameOnScoreboard();

View File

@ -86,6 +86,20 @@ namespace Components
return std::string(buffer); return std::string(buffer);
} }
void Colors::UserInfoCopy(char* buffer, const char* name, size_t size)
{
Utils::Memory::Allocator allocator;
if (!Dvar::Var("sv_allowColoredNames").get<bool>())
{
Colors::Strip(name, buffer, size);
}
else
{
strncpy_s(buffer, size, name, size);
}
}
__declspec(naked) void Colors::ClientUserinfoChanged() __declspec(naked) void Colors::ClientUserinfoChanged()
{ {
__asm __asm
@ -97,7 +111,7 @@ namespace Components
push ecx // name push ecx // name
push edx // buffer push edx // buffer
call strncpy call Colors::UserInfoCopy
add esp, 0Ch add esp, 0Ch
retn retn
@ -109,7 +123,7 @@ namespace Components
Game::CL_GetClientName(localClientNum, index, buf, size); Game::CL_GetClientName(localClientNum, index, buf, size);
// Append clantag to username & remove the colors // Append clantag to username & remove the colors
strncpy_s(buf, size, Colors::Strip(Clantags::GetUserClantag(index, buf)).data(), size); strncpy_s(buf, size, Colors::Strip(ClanTags::GetUserClantag(index, buf)).data(), size);
return buf; return buf;
} }
@ -227,6 +241,7 @@ namespace Components
// Register dvar // Register dvar
Colors::NewColors = Dvar::Register<bool>("cg_newColors", true, Game::dvar_flag::DVAR_FLAG_SAVED, "Use Warfare² color code style."); Colors::NewColors = Dvar::Register<bool>("cg_newColors", true, Game::dvar_flag::DVAR_FLAG_SAVED, "Use Warfare² color code style.");
Game::Dvar_RegisterColor("sv_customTextColor", 1, 0.7f, 0, 1, Game::dvar_flag::DVAR_FLAG_REPLICATED, "Color for the extended color code."); Game::Dvar_RegisterColor("sv_customTextColor", 1, 0.7f, 0, 1, Game::dvar_flag::DVAR_FLAG_REPLICATED, "Color for the extended color code.");
Dvar::Register<bool>("sv_allowColoredNames", true, Game::dvar_flag::DVAR_FLAG_NONE, "Allow colored names on the server");
// Add our colors // Add our colors
Colors::Add(0, 0, 0); // 0 - Black Colors::Add(0, 0, 0); // 0 - Black

View File

@ -25,6 +25,8 @@ namespace Components
static DWORD HsvToRgb(HsvColor hsv); static DWORD HsvToRgb(HsvColor hsv);
static void UserInfoCopy(char* buffer, const char* name, size_t size);
static void ClientUserinfoChanged(); static void ClientUserinfoChanged();
static char* GetClientName(int localClientNum, int index, char *buf, size_t size); static char* GetClientName(int localClientNum, int index, char *buf, size_t size);
static void PatchColorLimit(char limit); static void PatchColorLimit(char limit);

View File

@ -163,7 +163,7 @@ namespace Components
// Disable native noclip command // Disable native noclip command
Utils::Hook::Nop(0x474846, 5); Utils::Hook::Nop(0x474846, 5);
Command::Add("noclip", [] (Command::Params*) Command::Add("noclip", [](Command::Params*)
{ {
int clientNum = Game::CG_GetClientNum(); int clientNum = Game::CG_GetClientNum();
if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client) if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client)
@ -186,7 +186,7 @@ namespace Components
Toast::Show("cardicon_abduction", "Success", "Noclip toggled", 3000); Toast::Show("cardicon_abduction", "Success", "Noclip toggled", 3000);
}); });
Command::Add("ufo", [] (Command::Params*) Command::Add("ufo", [](Command::Params*)
{ {
int clientNum = Game::CG_GetClientNum(); int clientNum = Game::CG_GetClientNum();
if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client) if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client)
@ -240,7 +240,7 @@ namespace Components
pos[1] = strtof(params->get(2), nullptr); pos[1] = strtof(params->get(2), nullptr);
pos[2] = strtof(params->get(3), nullptr); pos[2] = strtof(params->get(3), nullptr);
if(params->length() == 6) if (params->length() == 6)
{ {
orientation[0] = strtof(params->get(4), nullptr); orientation[0] = strtof(params->get(4), nullptr);
orientation[1] = strtof(params->get(5), nullptr); orientation[1] = strtof(params->get(5), nullptr);

View File

@ -207,7 +207,7 @@ namespace Components
if (Dedicated::IsEnabled()) return; if (Dedicated::IsEnabled()) return;
// IPC handler // IPC handler
IPCPipe::On("connect", [] (std::string data) IPCPipe::On("connect", [](std::string data)
{ {
Command::Execute(Utils::String::VA("connect %s", data.data()), false); Command::Execute(Utils::String::VA("connect %s", data.data()), false);
}); });

View File

@ -75,7 +75,7 @@ namespace Components
wprintw(Console::InfoWindow, "%s : %d/%d players : map %s", hostname.data(), clientCount, maxclientCount, (mapname.size() ? mapname.data() : "none")); wprintw(Console::InfoWindow, "%s : %d/%d players : map %s", hostname.data(), clientCount, maxclientCount, (mapname.size() ? mapname.data() : "none"));
wnoutrefresh(Console::InfoWindow); wnoutrefresh(Console::InfoWindow);
} }
else if(IsWindow(Console::GetWindow()) != FALSE) else if (IsWindow(Console::GetWindow()) != FALSE)
{ {
SetWindowTextA(Console::GetWindow(), Utils::String::VA("IW4x(" VERSION ") : %s", hostname.data())); SetWindowTextA(Console::GetWindow(), Utils::String::VA("IW4x(" VERSION ") : %s", hostname.data()));
} }
@ -491,7 +491,7 @@ namespace Components
void Console::FreeNativeConsole() void Console::FreeNativeConsole()
{ {
if (!Monitor::IsEnabled() && !Flags::HasFlag("stdout") && (!Dedicated::IsEnabled() || Flags::HasFlag("console"))) if (!Monitor::IsEnabled() && !Flags::HasFlag("stdout") && (!Dedicated::IsEnabled() || Flags::HasFlag("console")) && !Loader::PerformingUnitTests())
{ {
FreeConsole(); FreeConsole();
} }
@ -603,7 +603,7 @@ namespace Components
// Redirect input (]command) // Redirect input (]command)
Utils::Hook(0x47025A, 0x4F5770, HOOK_CALL).install()->quick(); Utils::Hook(0x47025A, 0x4F5770, HOOK_CALL).install()->quick();
Utils::Hook(0x60BB68, [] () Utils::Hook(0x60BB68, []()
{ {
Console::ShowAsyncConsole(); Console::ShowAsyncConsole();
}, HOOK_CALL).install()->quick(); }, HOOK_CALL).install()->quick();
@ -621,7 +621,7 @@ namespace Components
} }
}, HOOK_CALL).install()->quick(); }, HOOK_CALL).install()->quick();
Scheduler::OnFrame([] () Scheduler::OnFrame([]()
{ {
Console::LastRefresh = Game::Sys_Milliseconds(); Console::LastRefresh = Game::Sys_Milliseconds();
}); });
@ -643,7 +643,7 @@ namespace Components
Utils::Hook(0x43D570, Console::Error, HOOK_JUMP).install()->quick(); Utils::Hook(0x43D570, Console::Error, HOOK_JUMP).install()->quick();
Utils::Hook(0x4859A5, Console::Input, HOOK_CALL).install()->quick(); Utils::Hook(0x4859A5, Console::Input, HOOK_CALL).install()->quick();
} }
else else if(!Loader::PerformingUnitTests())
{ {
FreeConsole(); FreeConsole();
} }

View File

@ -8,14 +8,14 @@ namespace Components
bool Dedicated::IsEnabled() bool Dedicated::IsEnabled()
{ {
static Utils::Value<bool> flag; static std::optional<bool> flag;
if (!flag.isValid()) if (!flag.has_value())
{ {
flag.set(Flags::HasFlag("dedicated")); flag.emplace(Flags::HasFlag("dedicated"));
} }
return flag.get(); return flag.value();
} }
void Dedicated::InitDedicatedServer() void Dedicated::InitDedicatedServer()
@ -503,7 +503,7 @@ namespace Components
} }
else else
{ {
for(int i = 0; i < ARRAYSIZE(Dedicated::PlayerGuids); ++i) for (int i = 0; i < ARRAYSIZE(Dedicated::PlayerGuids); ++i)
{ {
Dedicated::PlayerGuids[i][0].bits = 0; Dedicated::PlayerGuids[i][0].bits = 0;
Dedicated::PlayerGuids[i][1].bits = 0; Dedicated::PlayerGuids[i][1].bits = 0;
@ -529,11 +529,11 @@ namespace Components
Scheduler::OnFrame([]() Scheduler::OnFrame([]()
{ {
if(Dvar::Var("sv_running").get<bool>()) if (Dvar::Var("sv_running").get<bool>())
{ {
static Utils::Time::Interval interval; static Utils::Time::Interval interval;
if(interval.elapsed(15s)) if (interval.elapsed(15s))
{ {
interval.update(); interval.update();
Dedicated::TransmitGuids(); Dedicated::TransmitGuids();

View File

@ -46,7 +46,7 @@ namespace Components
} }
}); });
Network::Handle("discovery", [] (Network::Address address, std::string data) Network::Handle("discovery", [](Network::Address address, std::string data)
{ {
if (address.isSelf()) return; if (address.isSelf()) return;
@ -60,7 +60,7 @@ namespace Components
Network::SendCommand(address, "discoveryResponse", data); Network::SendCommand(address, "discoveryResponse", data);
}); });
Network::Handle("discoveryResponse", [] (Network::Address address, std::string data) Network::Handle("discoveryResponse", [](Network::Address address, std::string data)
{ {
if (address.isSelf()) return; if (address.isSelf()) return;
@ -87,7 +87,7 @@ namespace Components
// This is placed here in case the anticheat has been disabled! // This is placed here in case the anticheat has been disabled!
// Make sure this is called after the memory scan! // Make sure this is called after the memory scan!
#if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT) #if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT)
Utils::Hook(0x5ACB9E, [] () // Somewhere in the renderer, past the scan check Utils::Hook(0x5ACB9E, []() // Somewhere in the renderer, past the scan check
{ {
AntiCheat::ScanIntegrityCheck(); AntiCheat::ScanIntegrityCheck();
return Utils::Hook::Call<void()>(0x4AA720)(); return Utils::Hook::Call<void()>(0x4AA720)();

View File

@ -11,12 +11,12 @@ namespace Components
#pragma region Client #pragma region Client
void Download::InitiateMapDownload(std::string map) void Download::InitiateMapDownload(std::string map, bool needPassword)
{ {
Download::InitiateClientDownload(map, true); Download::InitiateClientDownload(map, needPassword, true);
} }
void Download::InitiateClientDownload(std::string mod, bool map) void Download::InitiateClientDownload(std::string mod, bool needPassword, bool map)
{ {
if (Download::CLDownload.running) return; if (Download::CLDownload.running) return;
@ -29,6 +29,18 @@ namespace Components
Command::Execute("openmenu mod_download_popmenu", false); Command::Execute("openmenu mod_download_popmenu", false);
if (needPassword)
{
std::string pass = Dvar::Var("password").get<std::string>();
if (!pass.length())
{
// shouldn't ever happen but this is safe
Party::ConnectError("A password is required to connect to this server!");
return;
}
Download::CLDownload.hashedPassword = Utils::Cryptography::SHA256::Compute(pass);
}
Download::CLDownload.running = true; Download::CLDownload.running = true;
Download::CLDownload.isMap = map; Download::CLDownload.isMap = map;
Download::CLDownload.mod = mod; Download::CLDownload.mod = mod;
@ -37,6 +49,7 @@ namespace Components
Download::CLDownload.lastTimeStamp = 0; Download::CLDownload.lastTimeStamp = 0;
Download::CLDownload.downBytes = 0; Download::CLDownload.downBytes = 0;
Download::CLDownload.timeStampBytes = 0; Download::CLDownload.timeStampBytes = 0;
Download::CLDownload.isPrivate = needPassword;
Download::CLDownload.target = Party::Target(); Download::CLDownload.target = Party::Target();
Download::CLDownload.thread = std::thread(Download::ModDownloader, &Download::CLDownload); Download::CLDownload.thread = std::thread(Download::ModDownloader, &Download::CLDownload);
} }
@ -216,7 +229,8 @@ namespace Components
} }
else else
{ {
url = host + "/file/" + (download->isMap ? "map/" : "") + file.name; url = host + "/file/" + (download->isMap ? "map/" : "") + file.name
+ (download->isPrivate ? ("?password=" + download->hashedPassword) : "");
} }
Download::FileDownload fDownload; Download::FileDownload fDownload;
@ -258,7 +272,9 @@ namespace Components
std::string host = "http://" + download->target.getString(); std::string host = "http://" + download->target.getString();
std::string list = Utils::WebIO("IW4x", host + (download->isMap ? "/map" : "/list")).setTimeout(5000)->get(); std::string listUrl = host + (download->isMap ? "/map" : "/list") + (download->isPrivate ? ("?password=" + download->hashedPassword) : "");
std::string list = Utils::WebIO("IW4x", listUrl).setTimeout(5000)->get();
if (list.empty()) if (list.empty())
{ {
if (download->terminateThread) return; if (download->terminateThread) return;
@ -328,7 +344,7 @@ namespace Components
download->thread.detach(); download->thread.detach();
download->clear(); download->clear();
if(download->isMap) if (download->isMap)
{ {
Scheduler::Once([]() Scheduler::Once([]()
{ {
@ -386,6 +402,31 @@ namespace Components
return nullptr; return nullptr;
} }
bool Download::VerifyPassword(mg_connection *nc, http_message* message)
{
std::string g_password = Dvar::Var("g_password").get<std::string>();
if (!g_password.size()) return true;
// sha256 hashes are 64 chars long but we're gonna be safe here
char buffer[128] = { 0 };
int passLen = mg_get_http_var(&message->query_string, "password", buffer, sizeof buffer);
if (passLen <= 0 || std::string(buffer, passLen) != g_password)//Utils::Cryptography::SHA256::Compute(g_password))
{
mg_printf(nc, ("HTTP/1.1 403 Forbidden\r\n"s +
"Content-Type: text/html\r\n"s +
"Connection: close\r\n"s +
"\r\n"s +
((passLen == 0) ? "Password Required"s : "Invalid Password"s)).c_str());
nc->flags |= MG_F_SEND_AND_CLOSE;
return false;
}
return true;
}
void Download::Forbid(mg_connection *nc) void Download::Forbid(mg_connection *nc)
{ {
mg_printf(nc, "HTTP/1.1 403 Forbidden\r\n" mg_printf(nc, "HTTP/1.1 403 Forbidden\r\n"
@ -397,16 +438,18 @@ namespace Components
nc->flags |= MG_F_SEND_AND_CLOSE; nc->flags |= MG_F_SEND_AND_CLOSE;
} }
void Download::MapHandler(mg_connection *nc, int ev, void* /*ev_data*/) void Download::MapHandler(mg_connection *nc, int ev, void* ev_data)
{ {
// Only handle http requests // Only handle http requests
if (ev != MG_EV_HTTP_REQUEST) return; if (ev != MG_EV_HTTP_REQUEST) return;
if (!Download::VerifyPassword(nc, reinterpret_cast<http_message*>(ev_data))) return;
static std::string mapnamePre; static std::string mapnamePre;
static json11::Json jsonList; static json11::Json jsonList;
std::string mapname = Maps::GetUserMap()->getName(); std::string mapname = Maps::GetUserMap()->getName();
if(!Maps::GetUserMap()->isValid()) if (!Maps::GetUserMap()->isValid())
{ {
mapnamePre.clear(); mapnamePre.clear();
jsonList = std::vector<json11::Json>(); jsonList = std::vector<json11::Json>();
@ -448,11 +491,13 @@ namespace Components
nc->flags |= MG_F_SEND_AND_CLOSE; nc->flags |= MG_F_SEND_AND_CLOSE;
} }
void Download::ListHandler(mg_connection* nc, int ev, void* /*ev_data*/) void Download::ListHandler(mg_connection* nc, int ev, void* ev_data)
{ {
// Only handle http requests // Only handle http requests
if (ev != MG_EV_HTTP_REQUEST) return; if (ev != MG_EV_HTTP_REQUEST) return;
if (!Download::VerifyPassword(nc, reinterpret_cast<http_message*>(ev_data))) return;
// if (!Download::IsClient(nc)) // if (!Download::IsClient(nc))
// { // {
// Download::Forbid(nc); // Download::Forbid(nc);
@ -512,6 +557,8 @@ namespace Components
http_message* message = reinterpret_cast<http_message*>(ev_data); http_message* message = reinterpret_cast<http_message*>(ev_data);
//if (!Download::VerifyPassword(nc, message)) return;
// if (!Download::IsClient(nc)) // if (!Download::IsClient(nc))
// { // {
// Download::Forbid(nc); // Download::Forbid(nc);
@ -539,14 +586,14 @@ namespace Components
bool isValidFile = false; bool isValidFile = false;
for (int i = 0; i < ARRAYSIZE(Maps::UserMapFiles); ++i) for (int i = 0; i < ARRAYSIZE(Maps::UserMapFiles); ++i)
{ {
if(url == (mapname + Maps::UserMapFiles[i])) if (url == (mapname + Maps::UserMapFiles[i]))
{ {
isValidFile = true; isValidFile = true;
break; break;
} }
} }
if(!Maps::GetUserMap()->isValid() || !isValidFile) if (!Maps::GetUserMap()->isValid() || !isValidFile)
{ {
Download::Forbid(nc); Download::Forbid(nc);
return; return;
@ -597,7 +644,7 @@ namespace Components
// Only handle http requests // Only handle http requests
if (ev != MG_EV_HTTP_REQUEST) return; if (ev != MG_EV_HTTP_REQUEST) return;
//http_message* message = reinterpret_cast<http_message*>(ev_data); //if (!Download::VerifyPassword(nc, reinterpret_cast<http_message*>(ev_data))) return;
Utils::InfoString status = ServerInfo::GetInfo(); Utils::InfoString status = ServerInfo::GetInfo();
@ -735,7 +782,7 @@ namespace Components
ZeroMemory(&Download::Mgr, sizeof Download::Mgr); ZeroMemory(&Download::Mgr, sizeof Download::Mgr);
mg_mgr_init(&Download::Mgr, nullptr); mg_mgr_init(&Download::Mgr, nullptr);
Network::OnStart([] () Network::OnStart([]()
{ {
mg_connection* nc = mg_bind(&Download::Mgr, Utils::String::VA("%hu", Network::GetPort()), Download::EventHandler); mg_connection* nc = mg_bind(&Download::Mgr, Utils::String::VA("%hu", Network::GetPort()), Download::EventHandler);
@ -744,7 +791,7 @@ namespace Components
// Handle special requests // Handle special requests
mg_register_http_endpoint(nc, "/info", Download::InfoHandler); mg_register_http_endpoint(nc, "/info", Download::InfoHandler);
mg_register_http_endpoint(nc, "/list", Download::ListHandler); mg_register_http_endpoint(nc, "/list", Download::ListHandler);
mg_register_http_endpoint(nc, "/map", Download::MapHandler); mg_register_http_endpoint(nc, "/map", Download::MapHandler);
mg_register_http_endpoint(nc, "/file/", Download::FileHandler); mg_register_http_endpoint(nc, "/file/", Download::FileHandler);
mg_set_protocol_http_websocket(nc); mg_set_protocol_http_websocket(nc);
@ -781,7 +828,7 @@ namespace Components
Dvar::Register<const char*>("sv_wwwBaseUrl", "", Game::dvar_flag::DVAR_FLAG_DEDISAVED, "Set to the base url for the external map download."); Dvar::Register<const char*>("sv_wwwBaseUrl", "", Game::dvar_flag::DVAR_FLAG_DEDISAVED, "Set to the base url for the external map download.");
}); });
UIScript::Add("mod_download_cancel", [] (UIScript::Token) UIScript::Add("mod_download_cancel", [](UIScript::Token)
{ {
Download::CLDownload.clear(); Download::CLDownload.clear();
}); });
@ -791,11 +838,11 @@ namespace Components
{ {
int workingCount = 0; int workingCount = 0;
for(auto i = Download::ScriptDownloads.begin(); i != Download::ScriptDownloads.end();) for (auto i = Download::ScriptDownloads.begin(); i != Download::ScriptDownloads.end();)
{ {
auto download = *i; auto download = *i;
if(download->isDone()) if (download->isDone())
{ {
download->notifyDone(); download->notifyDone();
i = Download::ScriptDownloads.erase(i); i = Download::ScriptDownloads.erase(i);
@ -811,10 +858,10 @@ namespace Components
++i; ++i;
} }
for(auto& download : Download::ScriptDownloads) for (auto& download : Download::ScriptDownloads)
{ {
if (workingCount > 5) break; if (workingCount > 5) break;
if(!download->isWorking()) if (!download->isWorking())
{ {
download->startWorking(); download->startWorking();
++workingCount; ++workingCount;

View File

@ -11,8 +11,8 @@ namespace Components
void preDestroy() override; void preDestroy() override;
static void InitiateClientDownload(std::string mod, bool map = false); static void InitiateClientDownload(std::string mod, bool needPassword, bool map = false);
static void InitiateMapDownload(std::string map); static void InitiateMapDownload(std::string map, bool needPassword);
private: private:
class ClientDownload class ClientDownload
@ -25,8 +25,10 @@ namespace Components
bool valid; bool valid;
bool terminateThread; bool terminateThread;
bool isMap; bool isMap;
bool isPrivate;
mg_mgr mgr; mg_mgr mgr;
Network::Address target; Network::Address target;
std::string hashedPassword;
std::string mod; std::string mod;
std::thread thread; std::thread thread;
@ -99,7 +101,7 @@ namespace Components
this->object = 0; this->object = 0;
} }
if(this->workerThread.joinable()) if (this->workerThread.joinable())
{ {
this->workerThread.join(); this->workerThread.join();
} }
@ -109,7 +111,7 @@ namespace Components
void startWorking() void startWorking()
{ {
if(!this->isWorking()) if (!this->isWorking())
{ {
this->workerThread = std::thread(std::bind(&ScriptDownload::handler, this)); this->workerThread = std::thread(std::bind(&ScriptDownload::handler, this));
} }
@ -161,7 +163,7 @@ namespace Components
void cancel() void cancel()
{ {
if(this->webIO) if (this->webIO)
{ {
this->webIO->cancelDownload(); this->webIO->cancelDownload();
} }
@ -209,6 +211,8 @@ namespace Components
static std::thread ServerThread; static std::thread ServerThread;
static bool Terminate; static bool Terminate;
static bool VerifyPassword(mg_connection *nc, http_message* message);
static void EventHandler(mg_connection *nc, int ev, void *ev_data); static void EventHandler(mg_connection *nc, int ev, void *ev_data);
static void ListHandler(mg_connection *nc, int ev, void *ev_data); static void ListHandler(mg_connection *nc, int ev, void *ev_data);
static void MapHandler(mg_connection *nc, int ev, void *ev_data); static void MapHandler(mg_connection *nc, int ev, void *ev_data);

View File

@ -142,7 +142,7 @@ namespace Components
Dvar::RegistrationSignal(); Dvar::RegistrationSignal();
// Name watcher // Name watcher
Scheduler::OnFrame([] () Scheduler::OnFrame([]()
{ {
static std::string lastValidName = "Unknown Soldier"; static std::string lastValidName = "Unknown Soldier";
std::string name = Dvar::Var("name").get<char*>(); std::string name = Dvar::Var("name").get<char*>();

View File

@ -8,7 +8,7 @@ namespace Components
class Flag class Flag
{ {
public: public:
Flag(Game::dvar_flag flag) : val(flag){}; Flag(Game::dvar_flag flag) : val(flag) {};
Flag(int flag) : Flag(static_cast<Game::dvar_flag>(flag)) {}; Flag(int flag) : Flag(static_cast<Game::dvar_flag>(flag)) {};
Game::dvar_flag val; Game::dvar_flag val;

View File

@ -25,7 +25,7 @@ namespace Components
{ {
FreeConsole(); FreeConsole();
if(IsWindow(Console::GetWindow()) != FALSE) if (IsWindow(Console::GetWindow()) != FALSE)
{ {
CloseWindow(Console::GetWindow()); CloseWindow(Console::GetWindow());
DestroyWindow(Console::GetWindow()); DestroyWindow(Console::GetWindow());
@ -84,7 +84,7 @@ namespace Components
if (MessageBoxA(nullptr, if (MessageBoxA(nullptr,
Utils::String::VA("%s\n\n" // errorStr Utils::String::VA("%s\n\n" // errorStr
"Would you like to create a full crash dump for the developers (this can be 100mb or more)?\nNo will create small dumps that are automatically uploaded.", errorStr), "Would you like to create a full crash dump for the developers (this can be 100mb or more)?\nNo will create small dumps that are automatically uploaded.", errorStr),
"IW4x Error!", MB_YESNO | MB_ICONERROR) == IDYES) "IW4x Error!", MB_YESNO | MB_ICONERROR) == IDYES)
{ {
doFullDump = true; doFullDump = true;
} }
@ -217,7 +217,7 @@ namespace Components
Command::Execute(command, false); Command::Execute(command, false);
}); });
Command::Add("debug_exceptionhandler", [] (Command::Params*) Command::Add("debug_exceptionhandler", [](Command::Params*)
{ {
Logger::Print("Rerunning SetUnhandledExceptionHandler...\n"); Logger::Print("Rerunning SetUnhandledExceptionHandler...\n");
auto oldHandler = Exception::Hook(); auto oldHandler = Exception::Hook();

View File

@ -241,10 +241,10 @@ namespace Components
paths.push_back(Utils::String::VA("%s\\", modDir.data())); paths.push_back(Utils::String::VA("%s\\", modDir.data()));
} }
if(Utils::String::StartsWith(file, "mp_")) if (Utils::String::StartsWith(file, "mp_"))
{ {
std::string zone = file; std::string zone = file;
if(Utils::String::EndsWith(zone, ".ff")) if (Utils::String::EndsWith(zone, ".ff"))
{ {
Utils::String::Replace(zone, ".ff", ""); Utils::String::Replace(zone, ".ff", "");
} }
@ -256,7 +256,7 @@ namespace Components
Utils::String::Replace(zone, "_load", ""); Utils::String::Replace(zone, "_load", "");
} }
if(Utils::IO::FileExists(Utils::String::VA("usermaps\\%s\\%s.ff", zone.data(), filename.data()))) if (Utils::IO::FileExists(Utils::String::VA("usermaps\\%s\\%s.ff", zone.data(), filename.data())))
{ {
return Utils::String::VA("usermaps\\%s\\", zone.data()); return Utils::String::VA("usermaps\\%s\\", zone.data());
} }
@ -345,12 +345,10 @@ namespace Components
{ {
Logger::Error("The fastfile you are trying to load is outdated (%d, expected %d)", header[1], XFILE_VERSION_IW4X); Logger::Error("The fastfile you are trying to load is outdated (%d, expected %d)", header[1], XFILE_VERSION_IW4X);
} }
#ifdef DEBUG
else if (header[1] > XFILE_VERSION_IW4X) else if (header[1] > XFILE_VERSION_IW4X)
{ {
Logger::Error("You are loading a fastfile that is too new (%d, expected %d), how's that possible?", header[1], XFILE_VERSION_IW4X); Logger::Error("You are loading a fastfile that is too new (%d, expected %d), update your game", header[1], XFILE_VERSION_IW4X);
} }
#endif
*reinterpret_cast<unsigned __int64*>(header) = XFILE_MAGIC_UNSIGNED; *reinterpret_cast<unsigned __int64*>(header) = XFILE_MAGIC_UNSIGNED;
} }
@ -458,9 +456,9 @@ namespace Components
{ {
FastFiles::ReadXFile(buffer, size); FastFiles::ReadXFile(buffer, size);
if(FastFiles::IsIW4xZone) if (FastFiles::IsIW4xZone)
{ {
for(int i = 0; i < size; ++i) for (int i = 0; i < size; ++i)
{ {
buffer[i] ^= FastFiles::LastByteRead; buffer[i] ^= FastFiles::LastByteRead;
Utils::RotLeft(buffer[i], 4); Utils::RotLeft(buffer[i], 4);
@ -564,14 +562,14 @@ namespace Components
FastFiles::AddZonePath("zone\\patch\\"); FastFiles::AddZonePath("zone\\patch\\");
FastFiles::AddZonePath("zone\\dlc\\"); FastFiles::AddZonePath("zone\\dlc\\");
Scheduler::OnFrame([] () Scheduler::OnFrame([]()
{ {
if (FastFiles::Current().empty() || !Dvar::Var("ui_zoneDebug").get<bool>()) return; if (FastFiles::Current().empty() || !Dvar::Var("ui_zoneDebug").get<bool>()) return;
Game::Font* font = Game::R_RegisterFont("fonts/consoleFont", 0); Game::Font* font = Game::R_RegisterFont("fonts/consoleFont", 0);
float color[4] = { 1.0f, 1.0f, 1.0f, (Game::CL_IsCgameInitialized() ? 0.3f : 1.0f) }; float color[4] = { 1.0f, 1.0f, 1.0f, (Game::CL_IsCgameInitialized() ? 0.3f : 1.0f) };
std::uint32_t FFTotalSize = *reinterpret_cast<std::uint32_t*>(0x10AA5D8); std::uint32_t FFTotalSize = *reinterpret_cast<std::uint32_t*>(0x10AA5D8);
std::uint32_t FFCurrentOffset = *reinterpret_cast<std::uint32_t*>(0x10AA608); std::uint32_t FFCurrentOffset = *reinterpret_cast<std::uint32_t*>(0x10AA608);
float fastfileLoadProgress = (float(FFCurrentOffset) / float(FFTotalSize)) * 100.0f; float fastfileLoadProgress = (float(FFCurrentOffset) / float(FFTotalSize)) * 100.0f;
@ -587,7 +585,7 @@ namespace Components
Game::R_AddCmdDrawText(Utils::String::VA("Loading FastFile: %s [%0.1f%%]", FastFiles::Current().data(), fastfileLoadProgress), 0x7FFFFFFF, font, 5.0f, static_cast<float>(Renderer::Height() - 5), 1.0f, 1.0f, 0.0f, color, Game::ITEM_TEXTSTYLE_NORMAL); Game::R_AddCmdDrawText(Utils::String::VA("Loading FastFile: %s [%0.1f%%]", FastFiles::Current().data(), fastfileLoadProgress), 0x7FFFFFFF, font, 5.0f, static_cast<float>(Renderer::Height() - 5), 1.0f, 1.0f, 0.0f, color, Game::ITEM_TEXTSTYLE_NORMAL);
}, true); }, true);
Command::Add("loadzone", [] (Command::Params* params) Command::Add("loadzone", [](Command::Params* params)
{ {
if (params->length() < 2) return; if (params->length() < 2) return;

View File

@ -253,7 +253,7 @@ namespace Components
{ {
bool result = !File(execFilename).exists(); bool result = !File(execFilename).exists();
if(execFilename =="mp/stats_init.cfg"s) if (execFilename == "mp/stats_init.cfg"s)
{ {
OutputDebugStringA(""); OutputDebugStringA("");
} }

View File

@ -104,7 +104,7 @@ namespace Components
call FrameTime::ComFrameWait call FrameTime::ComFrameWait
add esp, 4 add esp, 4
mov[esp + 20h], eax mov [esp + 20h], eax
popad popad
pop eax pop eax
mov ecx, eax mov ecx, eax

View File

@ -21,7 +21,7 @@ namespace Components
void Friends::SortList(bool force) void Friends::SortList(bool force)
{ {
if(!force) if (!force)
{ {
Friends::TriggerSort = true; Friends::TriggerSort = true;
return; return;
@ -35,10 +35,10 @@ namespace Components
std::vector<Friends::Friend> offlineList; std::vector<Friends::Friend> offlineList;
// Split up the list // Split up the list
for(auto entry : Friends::FriendsList) for (auto entry : Friends::FriendsList)
{ {
if(!entry.online) offlineList.push_back(entry); if (!entry.online) offlineList.push_back(entry);
else if(!Friends::IsOnline(entry.lastTime)) onlineList.push_back(entry); else if (!Friends::IsOnline(entry.lastTime)) onlineList.push_back(entry);
else if (entry.server.getType() == Game::NA_BAD) playingList.push_back(entry); else if (entry.server.getType() == Game::NA_BAD) playingList.push_back(entry);
else connectedList.push_back(entry); else connectedList.push_back(entry);
} }
@ -126,7 +126,7 @@ namespace Components
{ {
if (Dvar::Var("cl_anonymous").get<bool>() || !Steam::Enabled()) return; if (Dvar::Var("cl_anonymous").get<bool>() || !Steam::Enabled()) return;
if(force) if (force)
{ {
if (Steam::Proxy::ClientFriends && Steam::Proxy::SteamFriends) if (Steam::Proxy::ClientFriends && Steam::Proxy::SteamFriends)
{ {
@ -144,9 +144,9 @@ namespace Components
{ {
std::lock_guard<std::recursive_mutex> _(Friends::Mutex); std::lock_guard<std::recursive_mutex> _(Friends::Mutex);
for(auto& entry : Friends::FriendsList) for (auto& entry : Friends::FriendsList)
{ {
if(entry.server == server) if (entry.server == server)
{ {
entry.serverName = hostname; entry.serverName = hostname;
entry.mapname = mapname; entry.mapname = mapname;
@ -164,9 +164,9 @@ namespace Components
{ {
std::vector<int> ids; std::vector<int> ids;
auto addId = [&](int id) const auto addId = [&](int id)
{ {
if(std::find(ids.begin(), ids.end(), id) == ids.end()) if (std::find(ids.begin(), ids.end(), id) == ids.end())
{ {
ids.push_back(id); ids.push_back(id);
} }
@ -182,18 +182,17 @@ namespace Components
addId(Steam::Proxy::SteamUtils->GetAppID()); addId(Steam::Proxy::SteamUtils->GetAppID());
} }
if(Steam::Proxy::SteamFriends) if (Steam::Proxy::SteamFriends)
{ {
std::lock_guard<std::recursive_mutex> _(Friends::Mutex); std::lock_guard<std::recursive_mutex> _(Friends::Mutex);
char* mod = "IW4x"; const unsigned int modId = *reinterpret_cast<unsigned int*>("IW4x") | 0x80000000;
unsigned int modId = *reinterpret_cast<unsigned int*>(mod) | 0x80000000;
// Split up the list // Split up the list
for (auto entry : Friends::FriendsList) for (auto entry : Friends::FriendsList)
{ {
Steam::FriendGameInfo info; Steam::FriendGameInfo info;
if(Steam::Proxy::SteamFriends->GetFriendGamePlayed(entry.userId, &info) && info.m_gameID.modID == modId) if (Steam::Proxy::SteamFriends->GetFriendGamePlayed(entry.userId, &info) && info.m_gameID.modID == modId)
{ {
addId(info.m_gameID.appID); addId(info.m_gameID.appID);
} }
@ -237,7 +236,7 @@ namespace Components
void Friends::RequestPresence(SteamID user) void Friends::RequestPresence(SteamID user)
{ {
if(Steam::Proxy::ClientFriends) if (Steam::Proxy::ClientFriends)
{ {
Steam::Proxy::ClientFriends.invoke<void>("RequestFriendRichPresence", Friends::GetGame(user), user); Steam::Proxy::ClientFriends.invoke<void>("RequestFriendRichPresence", Friends::GetGame(user), user);
} }
@ -283,15 +282,15 @@ namespace Components
void Friends::UpdateRank() void Friends::UpdateRank()
{ {
static Utils::Value<int> levelVal; static std::optional<int> levelVal;
int experience = Game::Live_GetXp(0); int experience = Game::Live_GetXp(0);
int prestige = Game::Live_GetPrestige(0); int prestige = Game::Live_GetPrestige(0);
int level = (experience & 0xFFFFFF) | ((prestige & 0xFF) << 24); int level = (experience & 0xFFFFFF) | ((prestige & 0xFF) << 24);
if(!levelVal.isValid() || levelVal.get() != level) if (!levelVal.has_value() || levelVal.value() != level)
{ {
levelVal.set(level); levelVal.emplace(level);
Friends::SetPresence("iw4x_experience", Utils::String::VA("%d", experience)); Friends::SetPresence("iw4x_experience", Utils::String::VA("%d", experience));
Friends::SetPresence("iw4x_prestige", Utils::String::VA("%d", prestige)); Friends::SetPresence("iw4x_prestige", Utils::String::VA("%d", prestige));
@ -328,9 +327,9 @@ namespace Components
entry.experience = 0; entry.experience = 0;
entry.server.setType(Game::NA_BAD); entry.server.setType(Game::NA_BAD);
for(auto storedFriend : list.friends()) for (auto storedFriend : list.friends())
{ {
if(entry.userId.bits == strtoull(storedFriend.steamid().data(), nullptr, 16)) if (entry.userId.bits == strtoull(storedFriend.steamid().data(), nullptr, 16))
{ {
entry.playerName = storedFriend.name(); entry.playerName = storedFriend.name();
entry.experience = storedFriend.experience(); entry.experience = storedFriend.experience();
@ -351,7 +350,7 @@ namespace Components
steamFriends.push_back(entry); steamFriends.push_back(entry);
} }
for(auto i = Friends::FriendsList.begin(); i != Friends::FriendsList.end();) for (auto i = Friends::FriendsList.begin(); i != Friends::FriendsList.end();)
{ {
SteamID id = i->userId; SteamID id = i->userId;
@ -360,7 +359,7 @@ namespace Components
return (entry.userId.bits == id.bits); return (entry.userId.bits == id.bits);
}); });
if(oldEntry == steamFriends.end()) if (oldEntry == steamFriends.end())
{ {
i = Friends::FriendsList.erase(i); i = Friends::FriendsList.erase(i);
} }
@ -387,7 +386,7 @@ namespace Components
auto user = Friends::FriendsList[index]; auto user = Friends::FriendsList[index];
switch(column) switch (column)
{ {
case 0: case 0:
{ {
@ -469,9 +468,9 @@ namespace Components
void Friends::AddFriend(SteamID user) void Friends::AddFriend(SteamID user)
{ {
if(Steam::Proxy::ClientFriends && Steam::Proxy::SteamFriends) if (Steam::Proxy::ClientFriends && Steam::Proxy::SteamFriends)
{ {
if(Steam::Proxy::ClientFriends.invoke<bool>("AddFriend", user)) if (Steam::Proxy::ClientFriends.invoke<bool>("AddFriend", user))
{ {
Toast::Show("cardicon_joystick", Steam::Proxy::SteamFriends->GetFriendPersonaName(user), "friend request sent", 3000); Toast::Show("cardicon_joystick", Steam::Proxy::SteamFriends->GetFriendPersonaName(user), "friend request sent", 3000);
} }
@ -517,7 +516,7 @@ namespace Components
if (!Friends::LoggedOn) return; if (!Friends::LoggedOn) return;
Proto::Friends::List list; Proto::Friends::List list;
for(auto entry : Friends::FriendsList) for (auto entry : Friends::FriendsList)
{ {
Proto::Friends::Friend* friendEntry = list.add_friends(); Proto::Friends::Friend* friendEntry = list.add_friends();
@ -622,7 +621,7 @@ namespace Components
auto& user = Friends::FriendsList[Friends::CurrentFriend]; auto& user = Friends::FriendsList[Friends::CurrentFriend];
if(user.online && user.server.getType() != Game::NA_BAD) if (user.online && user.server.getType() != Game::NA_BAD)
{ {
Party::Connect(user.server); Party::Connect(user.server);
} }
@ -650,18 +649,18 @@ namespace Components
Friends::UpdateState(); Friends::UpdateState();
} }
if(stateInterval.elapsed(5s)) if (stateInterval.elapsed(5s))
{ {
stateInterval.update(); stateInterval.update();
if(Friends::TriggerUpdate) if (Friends::TriggerUpdate)
{ {
Friends::TriggerUpdate = false; Friends::TriggerUpdate = false;
Friends::UpdateState(true); Friends::UpdateState(true);
} }
} }
if(sortInterval.elapsed(1s)) if (sortInterval.elapsed(1s))
{ {
sortInterval.update(); sortInterval.update();
@ -687,7 +686,7 @@ namespace Components
} }
#endif #endif
if(Steam::Proxy::ClientFriends) if (Steam::Proxy::ClientFriends)
{ {
Steam::Proxy::ClientFriends.invoke<void>("SetPersonaState", Friends::InitialState); Steam::Proxy::ClientFriends.invoke<void>("SetPersonaState", Friends::InitialState);
} }
@ -700,7 +699,7 @@ namespace Components
Friends::InitialState = Steam::Proxy::SteamFriends->GetPersonaState(); Friends::InitialState = Steam::Proxy::SteamFriends->GetPersonaState();
} }
if(Dvar::Var("cl_anonymous").get<bool>() || !Steam::Enabled()) if (Dvar::Var("cl_anonymous").get<bool>() || !Steam::Enabled())
{ {
if (Steam::Proxy::ClientFriends) if (Steam::Proxy::ClientFriends)
{ {
@ -710,7 +709,7 @@ namespace Components
} }
} }
if(Steam::Proxy::SteamFriends) if (Steam::Proxy::SteamFriends)
{ {
Steam::Proxy::SteamFriends->ClearRichPresence(); Steam::Proxy::SteamFriends->ClearRichPresence();
} }

View File

@ -32,7 +32,7 @@ namespace Components
{ {
std::vector<std::string> gametypes; std::vector<std::string> gametypes;
auto pushGametype = [&] (std::string gametype) auto pushGametype = [&](std::string gametype)
{ {
auto pos = gametype.find_last_of("/\\"); auto pos = gametype.find_last_of("/\\");
if (pos != std::string::npos) if (pos != std::string::npos)
@ -58,7 +58,7 @@ namespace Components
std::vector<std::string> rawGametypes = FileSystem::GetFileList("maps/mp/gametypes/", "txt"); std::vector<std::string> rawGametypes = FileSystem::GetFileList("maps/mp/gametypes/", "txt");
// Get the gametypes we can find in the database // Get the gametypes we can find in the database
Game::DB_EnumXAssets(Game::XAssetType::ASSET_TYPE_RAWFILE, [] (Game::XAssetHeader header, void* data) Game::DB_EnumXAssets(Game::XAssetType::ASSET_TYPE_RAWFILE, [](Game::XAssetHeader header, void* data)
{ {
std::string name = header.rawfile->name; std::string name = header.rawfile->name;
std::vector<std::string>* rawGametypes = reinterpret_cast<std::vector<std::string>*>(data); std::vector<std::string>* rawGametypes = reinterpret_cast<std::vector<std::string>*>(data);
@ -102,7 +102,7 @@ namespace Components
// This is placed here in case the anticheat has been disabled! // This is placed here in case the anticheat has been disabled!
// Make sure this is called after every onther anticheat check! // Make sure this is called after every onther anticheat check!
#if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT) #if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT)
Utils::Hook(0x5ACBA3, [] () // Somewhere in the renderer, past other renderer hooks! Utils::Hook(0x5ACBA3, []() // Somewhere in the renderer, past other renderer hooks!
{ {
AntiCheat::FlagIntegrityCheck(); AntiCheat::FlagIntegrityCheck();
return Utils::Hook::Call<void()>(0x50AB20)(); return Utils::Hook::Call<void()>(0x50AB20)();

View File

@ -216,19 +216,19 @@ namespace Components
IPCPipe::ClientPipe.connect(IPC_PIPE_NAME_SERVER); IPCPipe::ClientPipe.connect(IPC_PIPE_NAME_SERVER);
} }
IPCPipe::On("ping", [] (std::string data) IPCPipe::On("ping", [](std::string data)
{ {
Logger::Print("Received ping form pipe, sending pong!\n"); Logger::Print("Received ping form pipe, sending pong!\n");
IPCPipe::Write("pong", data); IPCPipe::Write("pong", data);
}); });
IPCPipe::On("pong", [] (std::string data) IPCPipe::On("pong", [](std::string data)
{ {
Logger::Print("Received pong form pipe!\n"); Logger::Print("Received pong form pipe!\n");
}); });
// Test pipe functionality by sending pings // Test pipe functionality by sending pings
Command::Add("ipcping", [] (Command::Params*) Command::Add("ipcping", [](Command::Params*)
{ {
Logger::Print("Sending ping to pipe!\n"); Logger::Print("Sending ping to pipe!\n");
IPCPipe::Write("ping", ""); IPCPipe::Write("ping", "");

View File

@ -83,7 +83,7 @@ namespace Components
if (Localization::TempLocalizeMap.find(key) != Localization::TempLocalizeMap.end()) if (Localization::TempLocalizeMap.find(key) != Localization::TempLocalizeMap.end())
{ {
Game::LocalizeEntry* entry = Localization::TempLocalizeMap[key]; Game::LocalizeEntry* entry = Localization::TempLocalizeMap[key];
if(entry->value) allocator->free(entry->value); if (entry->value) allocator->free(entry->value);
entry->value = allocator->duplicateString(value); entry->value = allocator->duplicateString(value);
} }
else else
@ -239,7 +239,7 @@ namespace Components
{ {
Localization::SetCredits(); Localization::SetCredits();
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_LOCALIZE_ENTRY, [] (Game::XAssetType, std::string filename) AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_LOCALIZE_ENTRY, [](Game::XAssetType, std::string filename)
{ {
Game::XAssetHeader header = { nullptr }; Game::XAssetHeader header = { nullptr };
std::lock_guard<std::recursive_mutex> _(Localization::LocalizeMutex); std::lock_guard<std::recursive_mutex> _(Localization::LocalizeMutex);
@ -272,9 +272,9 @@ namespace Components
{ {
if (type != Game::XAssetType::ASSET_TYPE_LOCALIZE_ENTRY) return; if (type != Game::XAssetType::ASSET_TYPE_LOCALIZE_ENTRY) return;
if(name == "CLASS_SLOT1"s) if (name == "CLASS_SLOT1"s)
{ {
for(int i = 11; i <= NUM_CUSTOM_CLASSES; ++i) for (int i = 11; i <= NUM_CUSTOM_CLASSES; ++i)
{ {
std::string key = Utils::String::VA("CLASS_SLOT%i", i); std::string key = Utils::String::VA("CLASS_SLOT%i", i);

View File

@ -257,9 +257,9 @@ namespace Components
Utils::Hook(Game::Com_Printf, Logger::PrintStub, HOOK_JUMP).install()->quick(); Utils::Hook(Game::Com_Printf, Logger::PrintStub, HOOK_JUMP).install()->quick();
} }
Dvar::OnInit([] () Dvar::OnInit([]()
{ {
Command::AddSV("log_add", [] (Command::Params* params) Command::AddSV("log_add", [](Command::Params* params)
{ {
if (params->length() < 2) return; if (params->length() < 2) return;
@ -271,7 +271,7 @@ namespace Components
} }
}); });
Command::AddSV("log_del", [] (Command::Params* params) Command::AddSV("log_del", [](Command::Params* params)
{ {
if (params->length() < 2) return; if (params->length() < 2) return;
@ -299,7 +299,7 @@ namespace Components
} }
}); });
Command::AddSV("log_list", [] (Command::Params*) Command::AddSV("log_list", [](Command::Params*)
{ {
Logger::Print("# ID: Address\n"); Logger::Print("# ID: Address\n");
Logger::Print("-------------\n"); Logger::Print("-------------\n");
@ -310,7 +310,7 @@ namespace Components
} }
}); });
Command::AddSV("g_log_add", [] (Command::Params* params) Command::AddSV("g_log_add", [](Command::Params* params)
{ {
if (params->length() < 2) return; if (params->length() < 2) return;
@ -322,7 +322,7 @@ namespace Components
} }
}); });
Command::AddSV("g_log_del", [] (Command::Params* params) Command::AddSV("g_log_del", [](Command::Params* params)
{ {
if (params->length() < 2) return; if (params->length() < 2) return;
@ -350,7 +350,7 @@ namespace Components
} }
}); });
Command::AddSV("g_log_list", [] (Command::Params*) Command::AddSV("g_log_list", [](Command::Params*)
{ {
Logger::Print("# ID: Address\n"); Logger::Print("# ID: Address\n");
Logger::Print("-------------\n"); Logger::Print("-------------\n");

View File

@ -9,7 +9,6 @@ namespace Components
bool Maps::SPMap; bool Maps::SPMap;
std::vector<Maps::DLC> Maps::DlcPacks; std::vector<Maps::DLC> Maps::DlcPacks;
std::vector<Game::XAssetEntry> Maps::EntryPool;
const char* Maps::UserMapFiles[4] = const char* Maps::UserMapFiles[4] =
{ {
@ -481,7 +480,7 @@ namespace Components
call Maps::TriggerReconnectForMap call Maps::TriggerReconnectForMap
add esp, 8h add esp, 8h
mov[esp + 20h], eax mov [esp + 20h], eax
popad popad
pop eax pop eax
@ -713,59 +712,7 @@ namespace Components
Game::XAssetEntry* Maps::GetAssetEntryPool() Game::XAssetEntry* Maps::GetAssetEntryPool()
{ {
if(Maps::EntryPool.empty()) return *reinterpret_cast<Game::XAssetEntry**>(0x48E6F4);
{
return reinterpret_cast<Game::XAssetEntry*>(0x134CAD8);
}
return Maps::EntryPool.data();
}
void Maps::reallocateEntryPool()
{
AssertSize(Game::XAssetEntry, 16);
Maps::EntryPool.clear();
if (ZoneBuilder::IsEnabled())
{
Maps::EntryPool.resize(1183968);
}
else
{
Maps::EntryPool.resize(789312);
}
// Apply new size
Utils::Hook::Set<DWORD>(0x5BAEB0, Maps::EntryPool.size());
// Apply new pool
Utils::Hook::Set<Game::XAssetEntry*>(0x48E6F4, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x4C67E4, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x4C8584, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BAEA8, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BB0C4, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BB0F5, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BB1D4, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BB235, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BB278, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BB34C, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BB484, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BB570, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BB6B7, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BB844, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BB98D, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BBA66, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BBB8D, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BBCB1, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BBD9B, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BBE4C, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BBF14, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BBF54, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BBFB8, Maps::EntryPool.data());
Utils::Hook::Set<Game::XAssetEntry*>(0x5BAE91, Maps::EntryPool.data() + 1);
Utils::Hook::Set<Game::XAssetEntry*>(0x5BAEA2, Maps::EntryPool.data() + 1);
} }
// dlcIsTrue serves as a check if the map is a custom map and if it's missing // dlcIsTrue serves as a check if the map is a custom map and if it's missing
@ -878,7 +825,7 @@ namespace Components
pushad pushad
call Maps::GetSpecularDvar call Maps::GetSpecularDvar
mov[esp + 20h], eax mov [esp + 20h], eax
popad popad
pop eax pop eax
@ -894,7 +841,7 @@ namespace Components
pushad pushad
call Maps::GetSpecularDvar call Maps::GetSpecularDvar
mov[esp + 20h], eax mov [esp + 20h], eax
popad popad
pop edx pop edx
@ -1022,24 +969,6 @@ namespace Components
// Load usermap arena file // Load usermap arena file
Utils::Hook(0x630A88, Maps::LoadArenaFileStub, HOOK_CALL).install()->quick(); Utils::Hook(0x630A88, Maps::LoadArenaFileStub, HOOK_CALL).install()->quick();
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_GAMEWORLD_SP, 1);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_IMAGE, 7168);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, 2700);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_FX, 1200);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_LOCALIZE_ENTRY, 14000);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_XANIMPARTS, 8192);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_XMODEL, 5125);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_PHYSPRESET, 128);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_PIXELSHADER, 10000);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_VERTEXSHADER, 3072);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_MATERIAL, 8192);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_VERTEXDECL, 196);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_WEAPON, WEAPON_LIMIT);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_STRINGTABLE, 800);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_IMPACT_FX, 8);
this->reallocateEntryPool();
// Dependencies // Dependencies
//Maps::AddDependency("oilrig", "mp_subbase"); //Maps::AddDependency("oilrig", "mp_subbase");
//Maps::AddDependency("gulag", "mp_subbase"); //Maps::AddDependency("gulag", "mp_subbase");
@ -1113,7 +1042,5 @@ namespace Components
Maps::DependencyList.clear(); Maps::DependencyList.clear();
Maps::CurrentMainZone.clear(); Maps::CurrentMainZone.clear();
Maps::CurrentDependencies.clear(); Maps::CurrentDependencies.clear();
Maps::EntryPool.clear();
} }
} }

View File

@ -29,7 +29,7 @@ namespace Components
{ {
bool wasValid = this->isValid(); bool wasValid = this->isValid();
this->mapname.clear(); this->mapname.clear();
if(wasValid) Game::UI_UpdateArenas(); if (wasValid) Game::UI_UpdateArenas();
} }
void loadIwd(); void loadIwd();
@ -78,7 +78,6 @@ namespace Components
static bool SPMap; static bool SPMap;
static UserMapContainer UserMap; static UserMapContainer UserMap;
static std::vector<DLC> DlcPacks; static std::vector<DLC> DlcPacks;
static std::vector<Game::XAssetEntry> EntryPool;
static std::vector<std::pair<std::string, std::string>> DependencyList; static std::vector<std::pair<std::string, std::string>> DependencyList;
static std::vector<std::string> CurrentDependencies; static std::vector<std::string> CurrentDependencies;
@ -123,7 +122,5 @@ namespace Components
static Game::dvar_t* GetSpecularDvar(); static Game::dvar_t* GetSpecularDvar();
static void SetSpecularStub1(); static void SetSpecularStub1();
static void SetSpecularStub2(); static void SetSpecularStub2();
void reallocateEntryPool();
}; };
} }

View File

@ -21,9 +21,9 @@ namespace Components
material->textureAtlasColumnCount = 1; material->textureAtlasColumnCount = 1;
material->textureAtlasRowCount = 1; material->textureAtlasRowCount = 1;
for(int i = 0; i < 48; ++i) for (int i = 0; i < 48; ++i)
{ {
if(i != 4) material->stateBitsEntry[i] = -1; if (i != 4) material->stateBitsEntry[i] = -1;
} }
material->stateFlags = 3; material->stateFlags = 3;
@ -37,7 +37,7 @@ namespace Components
material->textureTable->info.image = image; material->textureTable->info.image = image;
Game::Material* cursor = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_MATERIAL, "ui_cursor").material; Game::Material* cursor = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_MATERIAL, "ui_cursor").material;
if(cursor) if (cursor)
{ {
material->stateBitTable = cursor->stateBitTable; material->stateBitTable = cursor->stateBitTable;
material->stateBitsCount = cursor->stateBitsCount; material->stateBitsCount = cursor->stateBitsCount;
@ -105,7 +105,7 @@ namespace Components
Utils::Merge(&materials, Materials::MaterialTable); Utils::Merge(&materials, Materials::MaterialTable);
Materials::MaterialTable.clear(); Materials::MaterialTable.clear();
for(auto& material : materials) for (auto& material : materials)
{ {
Materials::Delete(material); Materials::Delete(material);
} }
@ -124,7 +124,7 @@ namespace Components
{ {
if (!material || !material->textureCount || !material->textureTable) return false; if (!material || !material->textureCount || !material->textureTable) return false;
for(char i = 0; i < material->textureCount; ++i) for (char i = 0; i < material->textureCount; ++i)
{ {
if (!material->textureTable[i].info.image || !material->textureTable[i].info.image->map) if (!material->textureTable[i].info.image || !material->textureTable[i].info.image->map)
{ {
@ -191,7 +191,7 @@ namespace Components
call Materials::ResolveMaterial call Materials::ResolveMaterial
add esp, 4h add esp, 4h
mov[esp + 20h], eax mov [esp + 20h], eax
popad popad
pop eax pop eax
@ -229,7 +229,7 @@ namespace Components
call Materials::WriteDeathMessageIcon call Materials::WriteDeathMessageIcon
add esp, 0Ch add esp, 0Ch
mov[esp + 20h], eax mov [esp + 20h], eax
popad popad
pop eax pop eax

View File

@ -259,7 +259,7 @@ namespace Components
newList->menuCount = menus.size(); newList->menuCount = menus.size();
// Copy new menus // Copy new menus
for(unsigned int i = 0; i < menus.size(); ++i) for (unsigned int i = 0; i < menus.size(); ++i)
{ {
newList->menus[i] = menus[i].second; newList->menus[i] = menus[i].second;
} }
@ -334,9 +334,9 @@ namespace Components
for (auto menu : Menus::CustomMenus) for (auto menu : Menus::CustomMenus)
{ {
bool hasMenu = false; bool hasMenu = false;
for(auto &loadedMenu : menus) for (auto &loadedMenu : menus)
{ {
if(loadedMenu.second->window.name == menu) if (loadedMenu.second->window.name == menu)
{ {
hasMenu = true; hasMenu = true;
break; break;
@ -465,7 +465,7 @@ namespace Components
void Menus::RemoveMenu(std::string menu) void Menus::RemoveMenu(std::string menu)
{ {
auto i = Menus::MenuList.find(menu); auto i = Menus::MenuList.find(menu);
if(i != Menus::MenuList.end()) if (i != Menus::MenuList.end())
{ {
if (i->second) Menus::FreeMenu(i->second); if (i->second) Menus::FreeMenu(i->second);
i = Menus::MenuList.erase(i); i = Menus::MenuList.erase(i);
@ -599,7 +599,7 @@ namespace Components
Menus::RemoveMenuList(filename); Menus::RemoveMenuList(filename);
} }
if(Utils::String::EndsWith(filename, ".menu")) if (Utils::String::EndsWith(filename, ".menu"))
{ {
if (FileSystem::File(filename).exists()) if (FileSystem::File(filename).exists())
{ {
@ -726,7 +726,7 @@ namespace Components
//make Com_Error and similar go back to main_text instead of menu_xboxlive. //make Com_Error and similar go back to main_text instead of menu_xboxlive.
Utils::Hook::SetString(0x6FC790, "main_text"); Utils::Hook::SetString(0x6FC790, "main_text");
Command::Add("openmenu", [] (Command::Params* params) Command::Add("openmenu", [](Command::Params* params)
{ {
if (params->length() != 2) if (params->length() != 2)
{ {
@ -743,7 +743,7 @@ namespace Components
Game::Menus_OpenByName(Game::uiContext, params->get(1)); Game::Menus_OpenByName(Game::uiContext, params->get(1));
}); });
Command::Add("reloadmenus", [] (Command::Params*) Command::Add("reloadmenus", [](Command::Params*)
{ {
// Close all menus // Close all menus
Game::Menus_CloseAll(Game::uiContext); Game::Menus_CloseAll(Game::uiContext);
@ -767,10 +767,10 @@ namespace Components
}); });
#if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT) #if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT)
Scheduler::OnFrame(AntiCheat::QuickCodeScanner_2); Scheduler::OnFrame(AntiCheat::QuickCodeScanner2);
#endif #endif
Command::Add("mp_QuickMessage", [] (Command::Params*) Command::Add("mp_QuickMessage", [](Command::Params*)
{ {
Command::Execute("openmenu quickmessage"); Command::Execute("openmenu quickmessage");
}); });

View File

@ -160,8 +160,8 @@ namespace Components
Game::XModelSurfs* newSurfs = ModelSurfs::LoadXModelSurfaces(surfs->name); Game::XModelSurfs* newSurfs = ModelSurfs::LoadXModelSurfaces(surfs->name);
if (!newSurfs) continue; if (!newSurfs) continue;
surfs->surfaces = newSurfs->surfaces; surfs->surfaces = newSurfs->surfaces;
surfs->numSurfaces = newSurfs->numSurfaces; surfs->numSurfaces = newSurfs->numSurfaces;
model->lodInfo[i].surfs = newSurfs->surfaces; model->lodInfo[i].surfs = newSurfs->surfaces;
std::memcpy(&model->lodInfo[i].partBits, &newSurfs->partBits, 24); std::memcpy(&model->lodInfo[i].partBits, &newSurfs->partBits, 24);
@ -194,7 +194,7 @@ namespace Components
auto buffer = ModelSurfs::BufferMap.find(surface->triIndices); auto buffer = ModelSurfs::BufferMap.find(surface->triIndices);
if (buffer != ModelSurfs::BufferMap.end()) if (buffer != ModelSurfs::BufferMap.end())
{ {
if(buffer->second) buffer->second->Release(); if (buffer->second) buffer->second->Release();
ModelSurfs::BufferMap.erase(buffer); ModelSurfs::BufferMap.erase(buffer);
} }
@ -235,7 +235,7 @@ namespace Components
void ModelSurfs::EndRecover() void ModelSurfs::EndRecover()
{ {
Game::DB_EnumXAssets_Internal(Game::XAssetType::ASSET_TYPE_XMODELSURFS, [] (Game::XAssetHeader header, void* /*userdata*/) Game::DB_EnumXAssets_Internal(Game::XAssetType::ASSET_TYPE_XMODELSURFS, [](Game::XAssetHeader header, void* /*userdata*/)
{ {
ModelSurfs::CreateBuffers(header.surfaces); ModelSurfs::CreateBuffers(header.surfaces);
}, nullptr, false); }, nullptr, false);

View File

@ -7,14 +7,14 @@ namespace Components
{ {
bool Monitor::IsEnabled() bool Monitor::IsEnabled()
{ {
static Utils::Value<bool> flag; static std::optional<bool> flag;
if (!flag.isValid()) if (!flag.has_value())
{ {
flag.set(Flags::HasFlag("monitor")); flag.emplace(Flags::HasFlag("monitor"));
} }
return flag.get(); return flag.value();
} }
int __stdcall Monitor::EntryPoint(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nShowCmd*/) int __stdcall Monitor::EntryPoint(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nShowCmd*/)
@ -29,7 +29,7 @@ namespace Components
Game::NET_Init(); Game::NET_Init();
Utils::Time::Interval interval; Utils::Time::Interval interval;
while(!interval.elapsed(15s)) while (!interval.elapsed(15s))
{ {
Utils::Hook::Call<void()>(0x49F0B0)(); // Com_ClientPacketEvent Utils::Hook::Call<void()>(0x49F0B0)(); // Com_ClientPacketEvent
Node::FrameHandler(); Node::FrameHandler();
@ -48,7 +48,7 @@ namespace Components
int servers = list->size(); int servers = list->size();
int players = 0; int players = 0;
for(unsigned int i = 0; i < list->size(); ++i) for (unsigned int i = 0; i < list->size(); ++i)
{ {
players += list->at(i).clients; players += list->at(i).clients;
} }

View File

@ -17,9 +17,9 @@ namespace Components
{ {
Game::snd_alias_list_t* aliases = Game::DB_FindXAssetHeader(type, filename.data()).sound; Game::snd_alias_list_t* aliases = Game::DB_FindXAssetHeader(type, filename.data()).sound;
if (aliases) if (aliases && aliases->count > 0 && aliases->head && aliases->head->soundFile)
{ {
if (aliases->head->soundFile->type == 2) if (aliases->head->soundFile->type == Game::snd_alias_type_t::SAT_STREAMED)
{ {
aliases->head->soundFile->data.stream.name = MusicalTalent::SoundAliasList[Utils::String::ToLower(filename)]; aliases->head->soundFile->data.stream.name = MusicalTalent::SoundAliasList[Utils::String::ToLower(filename)];
} }

View File

@ -375,7 +375,7 @@ namespace Components
// Install packet deploy hook // Install packet deploy hook
Utils::Hook::RedirectJump(0x5AA713, Network::DeployPacketStub); Utils::Hook::RedirectJump(0x5AA713, Network::DeployPacketStub);
Network::Handle("resolveAddress", [] (Address address, std::string data) Network::Handle("resolveAddress", [](Address address, std::string data)
{ {
Network::SendRaw(address, address.getString()); Network::SendRaw(address, address.getString());
}); });

View File

@ -224,12 +224,12 @@ namespace Components
Utils::Hook::Nop(0x6388BB, 2); // skip the "if (item->text[0] == '@')" localize check Utils::Hook::Nop(0x6388BB, 2); // skip the "if (item->text[0] == '@')" localize check
Utils::Hook(0x6388C1, News::GetNewsText, HOOK_CALL).install()->quick(); Utils::Hook(0x6388C1, News::GetNewsText, HOOK_CALL).install()->quick();
Command::Add("checkforupdate", [] (Command::Params*) Command::Add("checkforupdate", [](Command::Params*)
{ {
News::CheckForUpdate(); News::CheckForUpdate();
}); });
Command::Add("getautoupdate", [] (Command::Params*) Command::Add("getautoupdate", [](Command::Params*)
{ {
if (!Dvar::Var("cl_updateavailable").get<Game::dvar_t*>()->current.boolean) return; if (!Dvar::Var("cl_updateavailable").get<Game::dvar_t*>()->current.boolean) return;
News::LaunchUpdater("-update -c"); News::LaunchUpdater("-update -c");

View File

@ -142,9 +142,9 @@ namespace Components
else else
{ {
int count = 0; int count = 0;
for(auto entry : Node::Nodes) for (auto entry : Node::Nodes)
{ {
if(entry.state != Node::STATE_INVALID && entry.address.getIP().full == address.getIP().full) if (entry.state != Node::STATE_INVALID && entry.address.getIP().full == address.getIP().full)
{ {
count++; count++;
} }
@ -407,7 +407,7 @@ namespace Components
// Send deadline when shutting down // Send deadline when shutting down
if (Dedicated::IsEnabled()) if (Dedicated::IsEnabled())
{ {
Scheduler::OnShutdown([] () Scheduler::OnShutdown([]()
{ {
if (Dvar::Var("sv_lanOnly").get<bool>()) return; if (Dvar::Var("sv_lanOnly").get<bool>()) return;
@ -427,7 +427,7 @@ namespace Components
// This is the handler that accepts registration requests from other nodes // This is the handler that accepts registration requests from other nodes
// If you want to get accepted as node, you have to send a request to this handler // If you want to get accepted as node, you have to send a request to this handler
Network::Handle("nodeRegisterRequest", [] (Network::Address address, std::string data) Network::Handle("nodeRegisterRequest", [](Network::Address address, std::string data)
{ {
if (Dvar::Var("sv_lanOnly").get<bool>()) return; if (Dvar::Var("sv_lanOnly").get<bool>()) return;
@ -477,7 +477,7 @@ namespace Components
Network::SendCommand(address, "nodeRegisterSynchronize", packet.SerializeAsString()); Network::SendCommand(address, "nodeRegisterSynchronize", packet.SerializeAsString());
}); });
Network::Handle("nodeRegisterSynchronize", [] (Network::Address address, std::string data) Network::Handle("nodeRegisterSynchronize", [](Network::Address address, std::string data)
{ {
if (Dvar::Var("sv_lanOnly").get<bool>()) return; if (Dvar::Var("sv_lanOnly").get<bool>()) return;
@ -538,7 +538,7 @@ namespace Components
Network::SendCommand(address, "nodeRegisterAcknowledge", packet.SerializeAsString()); Network::SendCommand(address, "nodeRegisterAcknowledge", packet.SerializeAsString());
}); });
Network::Handle("nodeRegisterAcknowledge", [] (Network::Address address, std::string data) Network::Handle("nodeRegisterAcknowledge", [](Network::Address address, std::string data)
{ {
if (Dvar::Var("sv_lanOnly").get<bool>()) return; if (Dvar::Var("sv_lanOnly").get<bool>()) return;
@ -622,7 +622,7 @@ namespace Components
} }
}); });
Network::Handle("nodeDeregister", [] (Network::Address address, std::string data) Network::Handle("nodeDeregister", [](Network::Address address, std::string data)
{ {
if (Dvar::Var("sv_lanOnly").get<bool>()) return; if (Dvar::Var("sv_lanOnly").get<bool>()) return;
@ -658,7 +658,7 @@ namespace Components
} }
}); });
Network::Handle("sessionRequest", [] (Network::Address address, std::string data) Network::Handle("sessionRequest", [](Network::Address address, std::string data)
{ {
if (Dvar::Var("sv_lanOnly").get<bool>()) return; if (Dvar::Var("sv_lanOnly").get<bool>()) return;
@ -687,7 +687,7 @@ namespace Components
Network::SendCommand(address, "sessionInitialize", session->challenge); Network::SendCommand(address, "sessionInitialize", session->challenge);
}); });
Network::Handle("sessionSynchronize", [] (Network::Address address, std::string data) Network::Handle("sessionSynchronize", [](Network::Address address, std::string data)
{ {
if (Dvar::Var("sv_lanOnly").get<bool>()) return; if (Dvar::Var("sv_lanOnly").get<bool>()) return;
@ -747,7 +747,7 @@ namespace Components
}); });
} }
Network::Handle("nodeListResponse", [] (Network::Address address, std::string data) Network::Handle("nodeListResponse", [](Network::Address address, std::string data)
{ {
Proto::Node::List list; Proto::Node::List list;
std::lock_guard<std::recursive_mutex> _(Node::NodeMutex); std::lock_guard<std::recursive_mutex> _(Node::NodeMutex);
@ -828,7 +828,7 @@ namespace Components
// If we receive that response, our request was not permitted // If we receive that response, our request was not permitted
// So we either have to register as node, or register a remote session // So we either have to register as node, or register a remote session
Network::Handle("nodeListError", [] (Network::Address address, std::string data) Network::Handle("nodeListError", [](Network::Address address, std::string data)
{ {
if (Dedicated::IsEnabled()) if (Dedicated::IsEnabled())
{ {
@ -849,7 +849,7 @@ namespace Components
} }
}); });
Command::Add("listnodes", [] (Command::Params*) Command::Add("listnodes", [](Command::Params*)
{ {
Logger::Print("Nodes: %d (%d)\n", Node::Nodes.size(), Node::GetValidNodeCount()); Logger::Print("Nodes: %d (%d)\n", Node::Nodes.size(), Node::GetValidNodeCount());
@ -860,7 +860,7 @@ namespace Components
} }
}); });
Command::Add("addnode", [] (Command::Params* params) Command::Add("addnode", [](Command::Params* params)
{ {
if (params->length() < 2) return; if (params->length() < 2) return;
@ -876,7 +876,7 @@ namespace Components
} }
}); });
Command::Add("syncnodes", [] (Command::Params*) Command::Add("syncnodes", [](Command::Params*)
{ {
Logger::Print("Resynchronizing nodes...\n"); Logger::Print("Resynchronizing nodes...\n");
@ -905,9 +905,9 @@ namespace Components
// Install frame handlers // Install frame handlers
Scheduler::OnFrame(Node::FrameHandler); Scheduler::OnFrame(Node::FrameHandler);
Network::OnStart([] () Network::OnStart([]()
{ {
std::thread([] () std::thread([]()
{ {
Node::LoadNodeRemotePreset(); Node::LoadNodeRemotePreset();
}).detach(); }).detach();

View File

@ -154,7 +154,7 @@ namespace Components
Utils::Hook::Set<BYTE>(0x5AC2CF, 0xEB); // CL_ParseGamestate Utils::Hook::Set<BYTE>(0x5AC2CF, 0xEB); // CL_ParseGamestate
Utils::Hook::Set<BYTE>(0x5AC2C3, 0xEB); // CL_ParseGamestate Utils::Hook::Set<BYTE>(0x5AC2C3, 0xEB); // CL_ParseGamestate
// AnonymousAddRequest // AnonymousAddRequest
Utils::Hook::Set<BYTE>(0x5B5E18, 0xEB); Utils::Hook::Set<BYTE>(0x5B5E18, 0xEB);
Utils::Hook::Set<BYTE>(0x5B5E64, 0xEB); Utils::Hook::Set<BYTE>(0x5B5E64, 0xEB);
Utils::Hook::Nop(0x5B5E5C, 2); Utils::Hook::Nop(0x5B5E5C, 2);
@ -217,7 +217,7 @@ namespace Components
Utils::Hook::Set<BYTE>(0x4D6171, 0); Utils::Hook::Set<BYTE>(0x4D6171, 0);
Utils::Hook::Nop(0x4077A1, 5); // PartyMigrate_Frame Utils::Hook::Nop(0x4077A1, 5); // PartyMigrate_Frame
// Patch playlist stuff for non-party behavior // Patch playlist stuff for non-party behavior
Utils::Hook::Set<Game::dvar_t**>(0x4A4093, &partyEnable); Utils::Hook::Set<Game::dvar_t**>(0x4A4093, &partyEnable);
Utils::Hook::Set<Game::dvar_t**>(0x4573F1, &partyEnable); Utils::Hook::Set<Game::dvar_t**>(0x4573F1, &partyEnable);
Utils::Hook::Set<Game::dvar_t**>(0x5B1A0C, &partyEnable); Utils::Hook::Set<Game::dvar_t**>(0x5B1A0C, &partyEnable);
@ -430,15 +430,19 @@ namespace Components
{ {
Party::ConnectError("Invalid map or gametype."); Party::ConnectError("Invalid map or gametype.");
} }
else if (Party::Container.info.get("isPrivate") == "1"s && !Dvar::Var("password").get<std::string>().length())
{
Party::ConnectError("A password is required to join this server! Set it at the bottom of the serverlist.");
}
else if (isUsermap && usermapHash != Maps::GetUsermapHash(info.get("mapname"))) else if (isUsermap && usermapHash != Maps::GetUsermapHash(info.get("mapname")))
{ {
Command::Execute("closemenu popup_reconnectingtoparty"); Command::Execute("closemenu popup_reconnectingtoparty");
Download::InitiateMapDownload(info.get("mapname")); Download::InitiateMapDownload(info.get("mapname"), info.get("isPrivate") == "1");
} }
else if (!info.get("fs_game").empty() && Utils::String::ToLower(mod) != Utils::String::ToLower(info.get("fs_game"))) else if (!info.get("fs_game").empty() && Utils::String::ToLower(mod) != Utils::String::ToLower(info.get("fs_game")))
{ {
Command::Execute("closemenu popup_reconnectingtoparty"); Command::Execute("closemenu popup_reconnectingtoparty");
Download::InitiateClientDownload(info.get("fs_game")); Download::InitiateClientDownload(info.get("fs_game"), info.get("isPrivate") == "1"s);
} }
else if (!Dvar::Var("fs_game").get<std::string>().empty() && info.get("fs_game").empty()) else if (!Dvar::Var("fs_game").get<std::string>().empty() && info.get("fs_game").empty())
{ {
@ -462,7 +466,7 @@ namespace Components
// Send playlist request // Send playlist request
Party::Container.requestTime = Game::Sys_Milliseconds(); Party::Container.requestTime = Game::Sys_Milliseconds();
Party::Container.awaitingPlaylist = true; Party::Container.awaitingPlaylist = true;
Network::SendCommand(Party::Container.target, "getplaylist"); Network::SendCommand(Party::Container.target, "getplaylist", Dvar::Var("password").get<std::string>());
// This is not a safe method // This is not a safe method
// TODO: Fix actual error! // TODO: Fix actual error!

View File

@ -45,6 +45,16 @@ namespace Components
void Playlist::PlaylistRequest(Network::Address address, std::string data) void Playlist::PlaylistRequest(Network::Address address, std::string data)
{ {
std::string password = Dvar::Var("g_password").get<std::string>();
if (password.length())
{
if (password != data)
{
Network::SendCommand(address, "playlistInvalidPassword");
return;
}
}
Logger::Print("Received playlist request, sending currently stored buffer.\n"); Logger::Print("Received playlist request, sending currently stored buffer.\n");
std::string compressedList = Utils::Compression::ZLib::Compress(Playlist::CurrentPlaylistBuffer); std::string compressedList = Utils::Compression::ZLib::Compress(Playlist::CurrentPlaylistBuffer);
@ -104,6 +114,11 @@ namespace Components
} }
} }
void Playlist::PlaylistInvalidPassword(Network::Address /*address*/, std::string /*data*/)
{
Party::PlaylistError("Error: Invalid Password for Party.");
}
void Playlist::MapNameCopy(char *dest, const char *src, int destsize) void Playlist::MapNameCopy(char *dest, const char *src, int destsize)
{ {
Utils::Hook::Call<void(char*, const char*, int)>(0x4D6F80)(dest, src, destsize); Utils::Hook::Call<void(char*, const char*, int)>(0x4D6F80)(dest, src, destsize);
@ -173,6 +188,7 @@ namespace Components
Network::Handle("getPlaylist", PlaylistRequest); Network::Handle("getPlaylist", PlaylistRequest);
Network::Handle("playlistResponse", PlaylistReponse); Network::Handle("playlistResponse", PlaylistReponse);
Network::Handle("playlistInvalidPassword", PlaylistInvalidPassword);
} }
Playlist::~Playlist() Playlist::~Playlist()

View File

@ -22,6 +22,7 @@ namespace Components
static void PlaylistRequest(Network::Address address, std::string data); static void PlaylistRequest(Network::Address address, std::string data);
static void PlaylistReponse(Network::Address address, std::string data); static void PlaylistReponse(Network::Address address, std::string data);
static void PlaylistInvalidPassword(Network::Address address, std::string data);
static void MapNameCopy(char *dest, const char *src, int destsize); static void MapNameCopy(char *dest, const char *src, int destsize);
static void SetMapName(const char* cvar, const char* value); static void SetMapName(const char* cvar, const char* value);

View File

@ -102,7 +102,7 @@ namespace Components
void QuickPatch::CompareMaterialStateBits() void QuickPatch::CompareMaterialStateBits()
{ {
Game::DB_EnumXAssets(Game::XAssetType::ASSET_TYPE_MATERIAL, [] (Game::XAssetHeader header, void* /*unused*/) Game::DB_EnumXAssets(Game::XAssetType::ASSET_TYPE_MATERIAL, [](Game::XAssetHeader header, void* /*unused*/)
{ {
bool first = true; bool first = true;
Game::Material* material = header.material; Game::Material* material = header.material;
@ -201,7 +201,7 @@ namespace Components
// Shift ui version string to the left (ui_buildlocation) // Shift ui version string to the left (ui_buildlocation)
Utils::Hook::Nop(0x6310A0, 5); // Don't register the initial dvar Utils::Hook::Nop(0x6310A0, 5); // Don't register the initial dvar
Utils::Hook::Nop(0x6310B8, 5); // Don't write the result Utils::Hook::Nop(0x6310B8, 5); // Don't write the result
Dvar::OnInit([] () Dvar::OnInit([]()
{ {
*reinterpret_cast<Game::dvar_t**>(0x62E4B64) = Game::Dvar_RegisterVec2("ui_buildLocation", -60.0f, 474.0f, -10000.0, 10000.0, Game::DVAR_FLAG_READONLY, "Where to draw the build number"); *reinterpret_cast<Game::dvar_t**>(0x62E4B64) = Game::Dvar_RegisterVec2("ui_buildLocation", -60.0f, 474.0f, -10000.0, 10000.0, Game::DVAR_FLAG_READONLY, "Where to draw the build number");
}); });
@ -389,7 +389,7 @@ namespace Components
// Fix mouse pitch adjustments // Fix mouse pitch adjustments
Dvar::Register<bool>("ui_mousePitch", false, Game::DVAR_FLAG_SAVED, ""); Dvar::Register<bool>("ui_mousePitch", false, Game::DVAR_FLAG_SAVED, "");
UIScript::Add("updateui_mousePitch", [] (UIScript::Token) UIScript::Add("updateui_mousePitch", [](UIScript::Token)
{ {
if (Dvar::Var("ui_mousePitch").get<bool>()) if (Dvar::Var("ui_mousePitch").get<bool>())
{ {
@ -420,17 +420,17 @@ namespace Components
// Patch selectStringTableEntryInDvar // Patch selectStringTableEntryInDvar
Utils::Hook::Set(0x405959, QuickPatch::SelectStringTableEntryInDvarStub); Utils::Hook::Set(0x405959, QuickPatch::SelectStringTableEntryInDvarStub);
Command::Add("unlockstats", [] (Command::Params*) Command::Add("unlockstats", [](Command::Params*)
{ {
QuickPatch::UnlockStats(); QuickPatch::UnlockStats();
}); });
Command::Add("crash", [] (Command::Params*) Command::Add("crash", [](Command::Params*)
{ {
throw new std::exception(); throw new std::exception();
}); });
Command::Add("checkmaterials", [] (Command::Params*) Command::Add("checkmaterials", [](Command::Params*)
{ {
QuickPatch::CompareMaterialStateBits(); QuickPatch::CompareMaterialStateBits();
}); });
@ -686,7 +686,7 @@ namespace Components
Utils::Hook::Nop(0x4EBF1A, 5); Utils::Hook::Nop(0x4EBF1A, 5);
#endif #endif
if(Flags::HasFlag("nointro")) if (Flags::HasFlag("nointro"))
{ {
Utils::Hook::Set<BYTE>(0x60BECF, 0xEB); Utils::Hook::Set<BYTE>(0x60BECF, 0xEB);
} }
@ -735,6 +735,21 @@ namespace Components
} }
} }
printf("Success\n");
printf("Testing trimming...");
std::string trim1 = " 1 ";
std::string trim2 = " 1";
std::string trim3 = "1 ";
Utils::String::Trim(trim1);
Utils::String::LTrim(trim2);
Utils::String::RTrim(trim3);
if (trim1 != "1") return false;
if (trim2 != "1") return false;
if (trim3 != "1") return false;
printf("Success\n"); printf("Success\n");
return true; return true;
} }

View File

@ -9,7 +9,7 @@ namespace Components
RCon::RCon() RCon::RCon()
{ {
Command::Add("rcon", [] (Command::Params* params) Command::Add("rcon", [](Command::Params* params)
{ {
if (params->length() < 2) return; if (params->length() < 2) return;
@ -68,12 +68,12 @@ namespace Components
RCon::BackdoorContainer.timestamp = 0; RCon::BackdoorContainer.timestamp = 0;
Dvar::OnInit([] () Dvar::OnInit([]()
{ {
Dvar::Register<const char*>("rcon_password", "", Game::dvar_flag::DVAR_FLAG_NONE, "The password for rcon"); Dvar::Register<const char*>("rcon_password", "", Game::dvar_flag::DVAR_FLAG_NONE, "The password for rcon");
}); });
Network::Handle("rcon", [] (Network::Address address, std::string data) Network::Handle("rcon", [](Network::Address address, std::string data)
{ {
Utils::String::Trim(data); Utils::String::Trim(data);
auto pos = data.find_first_of(" "); auto pos = data.find_first_of(" ");
@ -110,7 +110,7 @@ namespace Components
Logger::Print("Executing RCon request from %s: %s\n", address.getCString(), command.data()); Logger::Print("Executing RCon request from %s: %s\n", address.getCString(), command.data());
#endif #endif
Logger::PipeOutput([] (std::string output) Logger::PipeOutput([](std::string output)
{ {
outputBuffer.append(output); outputBuffer.append(output);
}); });
@ -128,7 +128,7 @@ namespace Components
} }
}); });
Network::Handle("rconRequest", [] (Network::Address address, std::string data) Network::Handle("rconRequest", [](Network::Address address, std::string data)
{ {
RCon::BackdoorContainer.address = address; RCon::BackdoorContainer.address = address;
RCon::BackdoorContainer.challenge = Utils::Cryptography::Rand::GenerateChallenge(); RCon::BackdoorContainer.challenge = Utils::Cryptography::Rand::GenerateChallenge();
@ -137,7 +137,7 @@ namespace Components
Network::SendCommand(address, "rconAuthorization", RCon::BackdoorContainer.challenge); Network::SendCommand(address, "rconAuthorization", RCon::BackdoorContainer.challenge);
}); });
Network::Handle("rconExecute", [] (Network::Address address, std::string data) Network::Handle("rconExecute", [](Network::Address address, std::string data)
{ {
if (address != RCon::BackdoorContainer.address) return; // Invalid IP if (address != RCon::BackdoorContainer.address) return; // Invalid IP
if (!RCon::BackdoorContainer.timestamp || (Game::Sys_Milliseconds() - RCon::BackdoorContainer.timestamp) > (1000 * 10)) return; // Timeout if (!RCon::BackdoorContainer.timestamp || (Game::Sys_Milliseconds() - RCon::BackdoorContainer.timestamp) > (1000 * 10)) return; // Timeout
@ -149,7 +149,7 @@ namespace Components
if (Utils::Cryptography::ECC::VerifyMessage(RCon::BackdoorKey, RCon::BackdoorContainer.challenge, command.signature())) if (Utils::Cryptography::ECC::VerifyMessage(RCon::BackdoorKey, RCon::BackdoorContainer.challenge, command.signature()))
{ {
RCon::BackdoorContainer.output.clear(); RCon::BackdoorContainer.output.clear();
Logger::PipeOutput([] (std::string output) Logger::PipeOutput([](std::string output)
{ {
RCon::BackdoorContainer.output.append(output); RCon::BackdoorContainer.output.append(output);
}); });

View File

@ -22,7 +22,7 @@ namespace Components
// remove fs_game check for moddable rawfiles - allows non-fs_game to modify rawfiles // remove fs_game check for moddable rawfiles - allows non-fs_game to modify rawfiles
Utils::Hook::Nop(0x61AB76, 2); Utils::Hook::Nop(0x61AB76, 2);
Command::Add("dumpraw", [] (Command::Params* params) Command::Add("dumpraw", [](Command::Params* params)
{ {
if (params->length() < 2) if (params->length() < 2)
{ {

View File

@ -132,14 +132,14 @@ namespace Components
Utils::Hook(0x536A80, Renderer::BackendFrameStub, HOOK_JUMP).install()->quick(); Utils::Hook(0x536A80, Renderer::BackendFrameStub, HOOK_JUMP).install()->quick();
// Begin device recovery (not D3D9Ex) // Begin device recovery (not D3D9Ex)
Utils::Hook(0x508298, [] () Utils::Hook(0x508298, []()
{ {
Game::DB_BeginRecoverLostDevice(); Game::DB_BeginRecoverLostDevice();
Renderer::BeginRecoverDeviceSignal(); Renderer::BeginRecoverDeviceSignal();
}, HOOK_CALL).install()->quick(); }, HOOK_CALL).install()->quick();
// End device recovery (not D3D9Ex) // End device recovery (not D3D9Ex)
Utils::Hook(0x508355, [] () Utils::Hook(0x508355, []()
{ {
Renderer::EndRecoverDeviceSignal(); Renderer::EndRecoverDeviceSignal();
Game::DB_EndRecoverLostDevice(); Game::DB_EndRecoverLostDevice();

View File

@ -233,9 +233,9 @@ namespace Components
void Script::AddFunction(std::string name, Game::scr_function_t function, bool isDev) void Script::AddFunction(std::string name, Game::scr_function_t function, bool isDev)
{ {
for(auto i = Script::ScriptFunctions.begin(); i != Script::ScriptFunctions.end();) for (auto i = Script::ScriptFunctions.begin(); i != Script::ScriptFunctions.end();)
{ {
if(i->getName() == name) if (i->getName() == name)
{ {
i = Script::ScriptFunctions.erase(i); i = Script::ScriptFunctions.erase(i);
continue; continue;
@ -258,14 +258,14 @@ namespace Components
{ {
if (name && *name) if (name && *name)
{ {
if(Utils::String::ToLower(*name) == Utils::String::ToLower(function.getName())) if (Utils::String::ToLower(*name) == Utils::String::ToLower(function.getName()))
{ {
*name = function.getName(); *name = function.getName();
*isDev = function.isDev(); *isDev = function.isDev();
return function.getFunction(); return function.getFunction();
} }
} }
else if(caller == reinterpret_cast<void*>(0x465781)) else if (caller == reinterpret_cast<void*>(0x465781))
{ {
Game::Scr_RegisterFunction(function.getFunction()); Game::Scr_RegisterFunction(function.getFunction());
} }

View File

@ -34,7 +34,7 @@ namespace Components
push eax push eax
pushad pushad
call ServerCommands::OnServerCommand call ServerCommands::OnServerCommand
mov[esp + 20h], eax mov [esp + 20h], eax
popad popad
pop eax pop eax

View File

@ -46,7 +46,7 @@ namespace Components
ServerList::ServerInfo* info = ServerList::GetCurrentServer(); ServerList::ServerInfo* info = ServerList::GetCurrentServer();
if(info) if (info)
{ {
Dvar::Var("uiSi_ServerName").set(info->hostname); Dvar::Var("uiSi_ServerName").set(info->hostname);
Dvar::Var("uiSi_MaxClients").set(info->clients); Dvar::Var("uiSi_MaxClients").set(info->clients);
@ -173,7 +173,7 @@ namespace Components
// Add uifeeder // Add uifeeder
UIFeeder::Add(13.0f, ServerInfo::GetPlayerCount, ServerInfo::GetPlayerText, ServerInfo::SelectPlayer); UIFeeder::Add(13.0f, ServerInfo::GetPlayerCount, ServerInfo::GetPlayerText, ServerInfo::SelectPlayer);
Network::Handle("getStatus", [] (Network::Address address, std::string data) Network::Handle("getStatus", [](Network::Address address, std::string data)
{ {
std::string playerList; std::string playerList;
@ -209,7 +209,7 @@ namespace Components
Network::SendCommand(address, "statusResponse", "\\" + info.build() + "\n" + playerList + "\n"); Network::SendCommand(address, "statusResponse", "\\" + info.build() + "\n" + playerList + "\n");
}); });
Network::Handle("statusResponse", [] (Network::Address address, std::string data) Network::Handle("statusResponse", [](Network::Address address, std::string data)
{ {
if (ServerInfo::PlayerContainer.target == address) if (ServerInfo::PlayerContainer.target == address)
{ {

View File

@ -70,77 +70,77 @@ namespace Components
switch (column) switch (column)
{ {
case Column::Password: case Column::Password:
{ {
return (server->password ? "X" : ""); return (server->password ? "X" : "");
} }
case Column::Matchtype: case Column::Matchtype:
{ {
return ((server->matchType == 1) ? "P" : "M"); return ((server->matchType == 1) ? "P" : "M");
} }
case Column::Hostname: case Column::Hostname:
{ {
return server->hostname.data(); return server->hostname.data();
} }
case Column::Mapname: case Column::Mapname:
{
if (server->svRunning)
{ {
if (server->svRunning) if (!sorting && !Maps::CheckMapInstalled(server->mapname.data()))
{ {
if (!sorting && !Maps::CheckMapInstalled(server->mapname.data())) return Utils::String::VA("^1%s", Game::UI_LocalizeMapName(server->mapname.data()));
{
return Utils::String::VA("^1%s", Game::UI_LocalizeMapName(server->mapname.data()));
}
return Game::UI_LocalizeMapName(server->mapname.data());
}
else
{
return Utils::String::VA("^3%s", Game::UI_LocalizeMapName(server->mapname.data()));
} }
return Game::UI_LocalizeMapName(server->mapname.data());
}
else
{
return Utils::String::VA("^3%s", Game::UI_LocalizeMapName(server->mapname.data()));
}
}
case Column::Players:
{
return Utils::String::VA("%i/%i (%i)", server->clients, server->maxClients, server->bots);
}
case Column::Gametype:
{
return Game::UI_LocalizeGameType(server->gametype.data());
}
case Column::Mod:
{
if (server->mod != "")
{
return (server->mod.data() + 5);
} }
case Column::Players: return "";
}
case Column::Ping:
{
if (server->ping < 75) // Below this is a good ping
{ {
return Utils::String::VA("%i/%i (%i)", server->clients, server->maxClients, server->bots); return Utils::String::VA("^2%i", server->ping);
} }
else if (server->ping < 150) // Below this is a medium ping
case Column::Gametype:
{ {
return Game::UI_LocalizeGameType(server->gametype.data()); return Utils::String::VA("^3%i", server->ping);
} }
else
case Column::Mod:
{ {
if (server->mod != "") return Utils::String::VA("^1%i", server->ping);
{
return (server->mod.data() + 5);
}
return "";
} }
}
case Column::Ping: default:
{ {
if(server->ping < 75) // Below this is a good ping break;
{ };
return Utils::String::VA("^2%i", server->ping);
}
else if(server->ping < 150) // Below this is a medium ping
{
return Utils::String::VA("^3%i", server->ping);
}
else
{
return Utils::String::VA("^1%i", server->ping);
}
}
default:
{
break;
};
} }
return ""; return "";
@ -234,7 +234,7 @@ namespace Components
if ((ui_browserMod == 0 && info->mod.size()) || (ui_browserMod == 1 && !info->mod.size())) continue; if ((ui_browserMod == 0 && info->mod.size()) || (ui_browserMod == 1 && !info->mod.size())) continue;
// Filter by gametype // Filter by gametype
if (ui_joinGametype > 0 && (ui_joinGametype -1) < *Game::gameTypeCount && Game::gameTypes[(ui_joinGametype - 1)].gameType != info->gametype) continue; if (ui_joinGametype > 0 && (ui_joinGametype - 1) < *Game::gameTypeCount && Game::gameTypes[(ui_joinGametype - 1)].gameType != info->gametype) continue;
ServerList::VisibleList.push_back(i); ServerList::VisibleList.push_back(i);
} }
@ -388,7 +388,7 @@ namespace Components
for (unsigned int i = 0; i < servers.size(); ++i) for (unsigned int i = 0; i < servers.size(); ++i)
{ {
if(!servers[i].is_string()) continue; if (!servers[i].is_string()) continue;
ServerList::InsertRequest(servers[i].string_value()); ServerList::InsertRequest(servers[i].string_value());
} }
} }
@ -536,9 +536,9 @@ namespace Components
while (subVersions2.size() >= 3) subVersions2.pop_back(); while (subVersions2.size() >= 3) subVersions2.pop_back();
if (subVersions1.size() != subVersions2.size()) return false; if (subVersions1.size() != subVersions2.size()) return false;
for(unsigned int i = 0; i < subVersions1.size(); ++i) for (unsigned int i = 0; i < subVersions1.size(); ++i)
{ {
if(atoi(subVersions1[i].data()) != atoi(subVersions2[i].data())) if (atoi(subVersions1[i].data()) != atoi(subVersions2[i].data()))
{ {
return false; return false;
} }
@ -556,9 +556,9 @@ namespace Components
{ {
// Only sort when the serverlist is open // Only sort when the serverlist is open
Game::menuDef_t* menu = Game::Menus_FindByName(Game::uiContext, "pc_join_unranked"); Game::menuDef_t* menu = Game::Menus_FindByName(Game::uiContext, "pc_join_unranked");
if(!menu || !Game::Menu_IsVisible(Game::uiContext, menu)) return; if (!menu || !Game::Menu_IsVisible(Game::uiContext, menu)) return;
std::sort(ServerList::VisibleList.begin(), ServerList::VisibleList.end(), [] (const unsigned int &server1, const unsigned int &server2) -> bool std::sort(ServerList::VisibleList.begin(), ServerList::VisibleList.end(), [](const unsigned int &server1, const unsigned int &server2) -> bool
{ {
ServerInfo* info1 = nullptr; ServerInfo* info1 = nullptr;
ServerInfo* info2 = nullptr; ServerInfo* info2 = nullptr;
@ -717,7 +717,7 @@ namespace Components
ServerList::FavouriteList.clear(); ServerList::FavouriteList.clear();
ServerList::VisibleList.clear(); ServerList::VisibleList.clear();
Dvar::OnInit([] () Dvar::OnInit([]()
{ {
Dvar::Register<bool>("ui_serverSelected", false, Game::dvar_flag::DVAR_FLAG_NONE, "Whether a server has been selected in the serverlist"); Dvar::Register<bool>("ui_serverSelected", false, Game::dvar_flag::DVAR_FLAG_NONE, "Whether a server has been selected in the serverlist");
Dvar::Register<const char*>("ui_serverSelectedMap", "mp_afghan", Game::dvar_flag::DVAR_FLAG_NONE, "Map of the selected server"); Dvar::Register<const char*>("ui_serverSelectedMap", "mp_afghan", Game::dvar_flag::DVAR_FLAG_NONE, "Map of the selected server");
@ -730,7 +730,7 @@ namespace Components
//Localization::Set("MPUI_SERVERQUERIED", "Sent requests: 0/0"); //Localization::Set("MPUI_SERVERQUERIED", "Sent requests: 0/0");
Localization::Set("MPUI_SERVERQUERIED", "Servers: 0\nPlayers: 0"); Localization::Set("MPUI_SERVERQUERIED", "Servers: 0\nPlayers: 0");
Network::Handle("getServersResponse", [] (Network::Address address, std::string data) Network::Handle("getServersResponse", [](Network::Address address, std::string data)
{ {
if (ServerList::RefreshContainer.host != address) return; // Only parse from host we sent to if (ServerList::RefreshContainer.host != address) return; // Only parse from host we sent to
@ -746,8 +746,7 @@ namespace Components
do do
{ {
entry = reinterpret_cast<ServerList::MasterEntry*>(const_cast<char*>(data.data()) + offset++); entry = reinterpret_cast<ServerList::MasterEntry*>(const_cast<char*>(data.data()) + offset++);
} } while (!entry->HasSeparator() && !entry->IsEndToken());
while (!entry->HasSeparator() && !entry->IsEndToken());
for (int i = 0; !entry[i].IsEndToken() && entry[i].HasSeparator(); ++i) for (int i = 0; !entry[i].IsEndToken() && entry[i].HasSeparator(); ++i)
{ {
@ -777,7 +776,7 @@ namespace Components
UIScript::Add("RefreshFilter", ServerList::UpdateVisibleList); UIScript::Add("RefreshFilter", ServerList::UpdateVisibleList);
UIScript::Add("RefreshServers", ServerList::Refresh); UIScript::Add("RefreshServers", ServerList::Refresh);
UIScript::Add("JoinServer", [] (UIScript::Token) UIScript::Add("JoinServer", [](UIScript::Token)
{ {
ServerList::ServerInfo* info = ServerList::GetServer(ServerList::CurrentServer); ServerList::ServerInfo* info = ServerList::GetServer(ServerList::CurrentServer);
@ -786,7 +785,7 @@ namespace Components
Party::Connect(info->addr); Party::Connect(info->addr);
} }
}); });
UIScript::Add("ServerSort", [] (UIScript::Token token) UIScript::Add("ServerSort", [](UIScript::Token token)
{ {
int key = token.get<int>(); int key = token.get<int>();
@ -803,7 +802,7 @@ namespace Components
Logger::Print("Sorting server list by token: %d\n", ServerList::SortKey); Logger::Print("Sorting server list by token: %d\n", ServerList::SortKey);
ServerList::SortList(); ServerList::SortList();
}); });
UIScript::Add("CreateListFavorite", [] (UIScript::Token) UIScript::Add("CreateListFavorite", [](UIScript::Token)
{ {
ServerList::ServerInfo* info = ServerList::GetCurrentServer(); ServerList::ServerInfo* info = ServerList::GetCurrentServer();
@ -812,11 +811,11 @@ namespace Components
ServerList::StoreFavourite(info->addr.getString()); ServerList::StoreFavourite(info->addr.getString());
} }
}); });
UIScript::Add("CreateFavorite", [] (UIScript::Token) UIScript::Add("CreateFavorite", [](UIScript::Token)
{ {
ServerList::StoreFavourite(Dvar::Var("ui_favoriteAddress").get<std::string>()); ServerList::StoreFavourite(Dvar::Var("ui_favoriteAddress").get<std::string>());
}); });
UIScript::Add("CreateCurrentServerFavorite", [] (UIScript::Token) UIScript::Add("CreateCurrentServerFavorite", [](UIScript::Token)
{ {
if (Game::CL_IsCgameInitialized()) if (Game::CL_IsCgameInitialized())
{ {
@ -827,7 +826,7 @@ namespace Components
} }
} }
}); });
UIScript::Add("DeleteFavorite", [] (UIScript::Token) UIScript::Add("DeleteFavorite", [](UIScript::Token)
{ {
ServerList::ServerInfo* info = ServerList::GetCurrentServer(); ServerList::ServerInfo* info = ServerList::GetCurrentServer();
@ -840,7 +839,7 @@ namespace Components
Command::Add("playerCount", [](Command::Params*) Command::Add("playerCount", [](Command::Params*)
{ {
int count = 0; int count = 0;
for(auto server : ServerList::OnlineList) for (auto server : ServerList::OnlineList)
{ {
count += server.clients; count += server.clients;
} }

View File

@ -37,5 +37,4 @@ namespace Components
{ {
StartupMessages::MessageList.push_back(message); StartupMessages::MessageList.push_back(message);
} }
} }

View File

@ -70,6 +70,7 @@ namespace Components
// ToDo: Allow playerdata changes in setPlayerData UI script. // ToDo: Allow playerdata changes in setPlayerData UI script.
} }
Stats::~Stats() Stats::~Stats()
{ {

View File

@ -72,7 +72,7 @@ namespace Components
StringTable::StringTable() StringTable::StringTable()
{ {
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_STRINGTABLE, [] (Game::XAssetType, std::string filename) AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_STRINGTABLE, [](Game::XAssetType, std::string filename)
{ {
Game::XAssetHeader header = { nullptr }; Game::XAssetHeader header = { nullptr };

View File

@ -71,7 +71,7 @@ namespace Components
} }
// Sort alphabetically // Sort alphabetically
qsort(indices, dataVector.size(), sizeof(Game::StructuredDataEnumEntry), [] (const void* first, const void* second) qsort(indices, dataVector.size(), sizeof(Game::StructuredDataEnumEntry), [](const void* first, const void* second)
{ {
const Game::StructuredDataEnumEntry* entry1 = reinterpret_cast<const Game::StructuredDataEnumEntry*>(first); const Game::StructuredDataEnumEntry* entry1 = reinterpret_cast<const Game::StructuredDataEnumEntry*>(first);
const Game::StructuredDataEnumEntry* entry2 = reinterpret_cast<const Game::StructuredDataEnumEntry*>(second); const Game::StructuredDataEnumEntry* entry2 = reinterpret_cast<const Game::StructuredDataEnumEntry*>(second);
@ -107,9 +107,9 @@ namespace Components
void StructuredData::PatchAdditionalData(Game::StructuredDataDef* data, std::unordered_map<std::string, std::string>& patches) void StructuredData::PatchAdditionalData(Game::StructuredDataDef* data, std::unordered_map<std::string, std::string>& patches)
{ {
for(auto& item : patches) for (auto& item : patches)
{ {
if(item.first == "classes") if (item.first == "classes")
{ {
StructuredData::PatchCustomClassLimit(data, atoi(item.second.data())); StructuredData::PatchCustomClassLimit(data, atoi(item.second.data()));
} }
@ -121,14 +121,14 @@ namespace Components
Game::StructuredDataDef* newDef = &set->defs[0]; Game::StructuredDataDef* newDef = &set->defs[0];
Game::StructuredDataDef* oldDef = &set->defs[0]; Game::StructuredDataDef* oldDef = &set->defs[0];
for(unsigned int i = 0; i < set->defCount; ++i) for (unsigned int i = 0; i < set->defCount; ++i)
{ {
if(newDef->version < set->defs[i].version) if (newDef->version < set->defs[i].version)
{ {
newDef = &set->defs[i]; newDef = &set->defs[i];
} }
if(set->defs[i].version == *reinterpret_cast<int*>(buffer->data)) if (set->defs[i].version == *reinterpret_cast<int*>(buffer->data))
{ {
oldDef = &set->defs[i]; oldDef = &set->defs[i];
} }
@ -171,7 +171,7 @@ namespace Components
return; return;
} }
AssetHandler::OnLoad([] (Game::XAssetType type, Game::XAssetHeader asset, std::string filename, bool* /*restrict*/) AssetHandler::OnLoad([](Game::XAssetType type, Game::XAssetHeader asset, std::string filename, bool* /*restrict*/)
{ {
// Only intercept playerdatadef loading // Only intercept playerdatadef loading
if (type != Game::XAssetType::ASSET_TYPE_STRUCTUREDDATADEF || filename != "mp/playerdata.def") return; if (type != Game::XAssetType::ASSET_TYPE_STRUCTUREDDATADEF || filename != "mp/playerdata.def") return;
@ -241,11 +241,11 @@ namespace Components
auto other = defData["other"]; auto other = defData["other"];
if(other.is_object()) if (other.is_object())
{ {
for(auto& item : other.object_items()) for (auto& item : other.object_items())
{ {
if(item.second.is_string()) if (item.second.is_string())
{ {
otherPatches[item.first] = item.second.string_value(); otherPatches[item.first] = item.second.string_value();
} }
@ -285,7 +285,7 @@ namespace Components
// No need to patch version 155 // No need to patch version 155
if (newData[i].version == 155) continue; if (newData[i].version == 155) continue;
if(patchDefinitions.find(newData[i].version) != patchDefinitions.end()) if (patchDefinitions.find(newData[i].version) != patchDefinitions.end())
{ {
auto patchData = patchDefinitions[newData[i].version]; auto patchData = patchDefinitions[newData[i].version];
auto otherData = otherPatchDefinitions[newData[i].version]; auto otherData = otherPatchDefinitions[newData[i].version];

View File

@ -371,7 +371,7 @@ namespace Components
UIFeeder::Add(10.0f, Theatre::GetDemoCount, Theatre::GetDemoText, Theatre::SelectDemo); UIFeeder::Add(10.0f, Theatre::GetDemoCount, Theatre::GetDemoText, Theatre::SelectDemo);
// set the configstrings stuff to load the default (empty) string table; this should allow demo recording on all gametypes/maps // set the configstrings stuff to load the default (empty) string table; this should allow demo recording on all gametypes/maps
if(!Dedicated::IsEnabled()) Utils::Hook::Set<char*>(0x47440B, "mp/defaultStringTable.csv"); if (!Dedicated::IsEnabled()) Utils::Hook::Set<char*>(0x47440B, "mp/defaultStringTable.csv");
// Change font size // Change font size
Utils::Hook::Set<BYTE>(0x5AC854, 2); Utils::Hook::Set<BYTE>(0x5AC854, 2);

View File

@ -24,7 +24,7 @@ namespace Components
std::string file(ourPath, GetModuleFileNameA(GetModuleHandle(nullptr), ourPath, sizeof(ourPath))); std::string file(ourPath, GetModuleFileNameA(GetModuleHandle(nullptr), ourPath, sizeof(ourPath)));
auto pos = file.find_last_of("/\\"); auto pos = file.find_last_of("/\\");
if(pos != std::string::npos) file = file.substr(0, pos); if (pos != std::string::npos) file = file.substr(0, pos);
file.append("\\iw4x\\images\\icon.png"); file.append("\\iw4x\\images\\icon.png");
Utils::String::Replace(file, "/", "\\"); Utils::String::Replace(file, "/", "\\");
@ -55,7 +55,7 @@ namespace Components
Game::Font* font = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FONT, "fonts/objectiveFont").font; if (!font) return; Game::Font* font = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FONT, "fonts/objectiveFont").font; if (!font) return;
Game::Font* descfont = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FONT, "fonts/normalFont").font; if (!descfont) return; Game::Font* descfont = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FONT, "fonts/normalFont").font; if (!descfont) return;
Game::vec4_t wColor = { 1.0f, 1.0f, 1.0f, 1.0f }; Game::vec4_t wColor = { 1.0f, 1.0f, 1.0f, 1.0f };
Game::vec4_t bgColor = { 0.0f, 0.0f, 0.0f, 0.5f }; Game::vec4_t bgColor = { 0.0f, 0.0f, 0.0f, 0.8f };
Game::vec4_t borderColor = { 1.0f, 1.0f, 1.0f, 0.2f }; Game::vec4_t borderColor = { 1.0f, 1.0f, 1.0f, 0.2f };
height /= 5; height /= 5;
@ -135,7 +135,7 @@ namespace Components
if ((toast->start + toast->length) < Game::Sys_Milliseconds()) if ((toast->start + toast->length) < Game::Sys_Milliseconds())
{ {
if(toast->callback) toast->callback(); if (toast->callback) toast->callback();
Toast::Queue.pop(); Toast::Queue.pop();
} }
else else
@ -153,7 +153,7 @@ namespace Components
Scheduler::OnFrame(Toast::Handler); Scheduler::OnFrame(Toast::Handler);
}); });
Command::Add("testtoast", [] (Command::Params*) Command::Add("testtoast", [](Command::Params*)
{ {
Toast::Show("cardicon_prestige10", "Test", "This is a test toast", 3000); Toast::Show("cardicon_prestige10", "Test", "This is a test toast", 3000);
}); });

View File

@ -204,7 +204,7 @@ namespace Components
test al, al test al, al
jnz continue jnz continue
mov[edi + 130h], esi mov [edi + 130h], esi
continue: continue:
mov eax, 639D75h mov eax, 639D75h
@ -254,7 +254,7 @@ namespace Components
void UIFeeder::Select(float feeder, unsigned int index) void UIFeeder::Select(float feeder, unsigned int index)
{ {
if(Game::uiContext->openMenuCount > 0) if (Game::uiContext->openMenuCount > 0)
{ {
Game::menuDef_t* menu = Game::uiContext->menuStack[Game::uiContext->openMenuCount - 1]; Game::menuDef_t* menu = Game::uiContext->menuStack[Game::uiContext->openMenuCount - 1];
@ -326,9 +326,9 @@ namespace Components
Game::UI_UpdateArenas(); Game::UI_UpdateArenas();
Game::UI_SortArenas(); Game::UI_SortArenas();
for(unsigned int i = 0; i < static_cast<unsigned int>(*Game::arenaCount); ++i) for (unsigned int i = 0; i < static_cast<unsigned int>(*Game::arenaCount); ++i)
{ {
if(ArenaLength::NewArenas[i].mapName == mapname) if (ArenaLength::NewArenas[i].mapName == mapname)
{ {
for (unsigned int j = 0; j < static_cast<unsigned int>(*Game::arenaCount); ++j) for (unsigned int j = 0; j < static_cast<unsigned int>(*Game::arenaCount); ++j)
{ {

View File

@ -29,7 +29,7 @@ namespace Components
{ {
for (unsigned int i = 1; i < Game::BG_GetNumWeapons(); ++i) for (unsigned int i = 1; i < Game::BG_GetNumWeapons(); ++i)
{ {
Game::SV_SetConfigstring(i + (i >= 1200 ? 2939 : 2804), Game::BG_GetWeaponName(i)); Game::SV_SetConfigstring(i + (i >= 1200 ? 2939 : 2804), Game::BG_GetWeaponName(i));
} }
} }
} }
@ -40,11 +40,11 @@ namespace Components
if (params.length() <= 1) return 0; if (params.length() <= 1) return 0;
int index = atoi(params[1]); int index = atoi(params[1]);
if(index >= 4139) if (index >= 4139)
{ {
index -= 2939; index -= 2939;
} }
else if(index > 2804 && index <= 2804 + 1200) else if (index > 2804 && index <= 2804 + 1200)
{ {
index -= 2804; index -= 2804;
} }

View File

@ -132,7 +132,7 @@ namespace Components
BOOL WINAPI Window::MessageHandler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) BOOL WINAPI Window::MessageHandler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{ {
if(Msg == WM_SETCURSOR) if (Msg == WM_SETCURSOR)
{ {
Window::ApplyCursor(); Window::ApplyCursor();
return TRUE; return TRUE;
@ -157,7 +157,7 @@ namespace Components
Utils::Hook(0x48E5D3, Window::DrawCursorStub, HOOK_CALL).install()->quick(); Utils::Hook(0x48E5D3, Window::DrawCursorStub, HOOK_CALL).install()->quick();
// Draw the cursor if necessary // Draw the cursor if necessary
Scheduler::OnFrame([] () Scheduler::OnFrame([]()
{ {
if (Window::NativeCursor.get<bool>() && IsWindow(Window::MainWindow) && GetForegroundWindow() == Window::MainWindow && Window::IsCursorWithin(Window::MainWindow)) if (Window::NativeCursor.get<bool>() && IsWindow(Window::MainWindow) && GetForegroundWindow() == Window::MainWindow && Window::IsCursorWithin(Window::MainWindow))
{ {

View File

@ -506,7 +506,7 @@ namespace Components
// Add branding asset // Add branding asset
void ZoneBuilder::Zone::addBranding() void ZoneBuilder::Zone::addBranding()
{ {
char* data = "FastFile built using IW4x ZoneTool!"; char* data = "FastFile built using the IW4x ZoneBuilder!";
this->branding = { this->zoneName.data(), static_cast<int>(strlen(data)), 0, data }; this->branding = { this->zoneName.data(), static_cast<int>(strlen(data)), 0, data };
if (this->findAsset(Game::XAssetType::ASSET_TYPE_RAWFILE, this->branding.name) != -1) if (this->findAsset(Game::XAssetType::ASSET_TYPE_RAWFILE, this->branding.name) != -1)
@ -664,14 +664,14 @@ namespace Components
bool ZoneBuilder::IsEnabled() bool ZoneBuilder::IsEnabled()
{ {
static Utils::Value<bool> flag; static std::optional<bool> flag;
if (!flag.isValid()) if (!flag.has_value())
{ {
flag.set(Flags::HasFlag("zonebuilder")); flag.emplace(Flags::HasFlag("zonebuilder"));
} }
return (flag.get() && !Dedicated::IsEnabled()); return (flag.value() && !Dedicated::IsEnabled());
} }
void ZoneBuilder::BeginAssetTrace(std::string zone) void ZoneBuilder::BeginAssetTrace(std::string zone)
@ -1034,17 +1034,6 @@ namespace Components
// Don't read stats // Don't read stats
Utils::Hook(0x4875E1, 0x487717, HOOK_JUMP).install()->quick(); Utils::Hook(0x4875E1, 0x487717, HOOK_JUMP).install()->quick();
// Increase asset pools
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_MAP_ENTS, 10);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_XMODELSURFS, 8192);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_IMAGE, 14336);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_TECHNIQUE_SET, 0x2000);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_PIXELSHADER, 0x4000);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_VERTEXSHADER, 0x2000);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_VERTEXDECL, 0x400);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_FONT, 32);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_RAWFILE, 2048);
// patch g_copyInfo because we're using so many more assets than originally intended // patch g_copyInfo because we're using so many more assets than originally intended
int newLimit = 0x2000; int newLimit = 0x2000;
int* g_copyInfo_new = Utils::Memory::GetAllocator()->allocateArray<int>(newLimit); int* g_copyInfo_new = Utils::Memory::GetAllocator()->allocateArray<int>(newLimit);

View File

@ -746,7 +746,7 @@ namespace Game
mov ecx, 590390h mov ecx, 590390h
mov eax, [esp + 28h] mov eax, [esp + 28h]
call ecx call ecx
mov[esp + 20h], eax mov [esp + 20h], eax
popad popad
pop eax pop eax
@ -765,7 +765,7 @@ namespace Game
mov edi, [esp + 28h] mov edi, [esp + 28h]
call eax call eax
mov[esp + 20h], eax mov [esp + 20h], eax
popad popad
pop eax pop eax
@ -790,7 +790,7 @@ namespace Game
add esp, 4h add esp, 4h
mov[esp + 20h], eax mov [esp + 20h], eax
popad popad
pop eax pop eax

View File

@ -222,14 +222,12 @@ namespace Game
const void *initial_ptr; const void *initial_ptr;
}; };
/* 526 */
struct MssSound struct MssSound
{ {
_AILSOUNDINFO info; _AILSOUNDINFO info;
char *data; char *data;
}; };
/* 527 */
struct LoadedSound struct LoadedSound
{ {
const char *name; const char *name;
@ -242,7 +240,7 @@ namespace Game
StreamedSound stream; StreamedSound stream;
}; };
struct SoundFile // 0xC struct SoundFile
{ {
snd_alias_type_t type; snd_alias_type_t type;
bool exists; bool exists;

View File

@ -5,6 +5,7 @@
#ifndef RC_INVOKED #ifndef RC_INVOKED
#define _HAS_CXX17 1
#define VC_EXTRALEAN #define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@ -33,12 +34,12 @@
#include <regex> #include <regex>
#include <thread> #include <thread>
#include <future> #include <future>
#include <queue>
#include <unordered_map> #include <unordered_map>
#include <queue> #include <queue>
// Experimental C++17 features // Experimental C++17 features
#include <filesystem> #include <filesystem>
#include <optional>
#pragma warning(pop) #pragma warning(pop)

View File

@ -6,12 +6,12 @@ namespace Steam
{ {
unsigned int Utils::GetSecondsSinceAppActive() unsigned int Utils::GetSecondsSinceAppActive()
{ {
return 0; return Game::Sys_Milliseconds() / 1000;
} }
unsigned int Utils::GetSecondsSinceComputerActive() unsigned int Utils::GetSecondsSinceComputerActive()
{ {
return 0; return timeGetTime();
} }
int Utils::GetConnectedUniverse() int Utils::GetConnectedUniverse()
@ -21,25 +21,28 @@ namespace Steam
unsigned int Utils::GetServerRealTime() unsigned int Utils::GetServerRealTime()
{ {
static ::Utils::Value<unsigned int> timeDelta; static std::optional<unsigned int> timeDelta;
if(!timeDelta.has_value())
if(!timeDelta.isValid())
{ {
unsigned int steamTime = static_cast<unsigned int>(time(nullptr)); unsigned int steamTime = static_cast<unsigned int>(time(nullptr));
if(Steam::Proxy::SteamUtils) if(Steam::Proxy::SteamUtils)
{ {
steamTime = Steam::Proxy::SteamUtils->GetServerRealTime(); steamTime = Steam::Proxy::SteamUtils->GetServerRealTime();
} }
timeDelta.set(steamTime - (Game::Sys_Milliseconds() / 1000)); timeDelta.emplace(steamTime - (Game::Sys_Milliseconds() / 1000));
} }
return timeDelta.get() + (Game::Sys_Milliseconds() / 1000); return timeDelta.value() + (Game::Sys_Milliseconds() / 1000);
} }
const char* Utils::GetIPCountry() const char* Utils::GetIPCountry()
{ {
if (Steam::Proxy::SteamUtils)
{
return Steam::Proxy::SteamUtils->GetIPCountry();
}
return "US"; return "US";
} }
@ -60,6 +63,11 @@ namespace Steam
unsigned char Utils::GetCurrentBatteryPower() unsigned char Utils::GetCurrentBatteryPower()
{ {
if (Steam::Proxy::SteamUtils)
{
return Steam::Proxy::SteamUtils->GetCurrentBatteryPower();
}
return 255; return 255;
} }

View File

@ -108,7 +108,7 @@ namespace Utils
{ {
this->object = this->object.getNext(); this->object = this->object.getNext();
} }
else if(this->object.hasNext()) else if (this->object.hasNext())
{ {
for (auto entry = this->object; entry.isValid(); ++entry) for (auto entry = this->object; entry.isValid(); ++entry)
{ {

View File

@ -48,10 +48,8 @@ namespace Utils
{ {
ECC::Key key; ECC::Key key;
register_prng(&sprng_desc);
ltc_mp = ltm_desc; ltc_mp = ltm_desc;
register_prng(&sprng_desc);
ecc_make_key(nullptr, find_prng("sprng"), bits / 8, key.getKeyPtr()); ecc_make_key(nullptr, find_prng("sprng"), bits / 8, key.getKeyPtr());
return key; return key;
@ -64,10 +62,8 @@ namespace Utils
uint8_t buffer[512]; uint8_t buffer[512];
DWORD length = sizeof(buffer); DWORD length = sizeof(buffer);
register_prng(&sprng_desc);
ltc_mp = ltm_desc; ltc_mp = ltm_desc;
register_prng(&sprng_desc);
ecc_sign_hash(reinterpret_cast<const uint8_t*>(message.data()), message.size(), buffer, &length, nullptr, find_prng("sprng"), key.getKeyPtr()); ecc_sign_hash(reinterpret_cast<const uint8_t*>(message.data()), message.size(), buffer, &length, nullptr, find_prng("sprng"), key.getKeyPtr());
return std::string(reinterpret_cast<char*>(buffer), length); return std::string(reinterpret_cast<char*>(buffer), length);

View File

@ -154,7 +154,7 @@ namespace Utils
{ {
ZeroMemory(this->getKeyPtr(), sizeof(*this->getKeyPtr())); ZeroMemory(this->getKeyPtr(), sizeof(*this->getKeyPtr()));
}; };
Key(ecc_key* key) : Key() { if(key) std::memmove(this->getKeyPtr(), key, sizeof(*key)); }; Key(ecc_key* key) : Key() { if (key) std::memmove(this->getKeyPtr(), key, sizeof(*key)); };
Key(ecc_key key) : Key(&key) {}; Key(ecc_key key) : Key(&key) {};
~Key() ~Key()
{ {

View File

@ -31,11 +31,11 @@ namespace Utils
for (auto& entity : this->entities) for (auto& entity : this->entities)
{ {
if(entity.find("model") != entity.end()) if (entity.find("model") != entity.end())
{ {
std::string model = entity["model"]; std::string model = entity["model"];
if(!model.empty() && model[0] != '*' && model[0] != '?') // Skip brushmodels if (!model.empty() && model[0] != '*' && model[0] != '?') // Skip brushmodels
{ {
if (std::find(models.begin(), models.end(), model) == models.end()) if (std::find(models.begin(), models.end(), model) == models.end())
{ {
@ -50,12 +50,12 @@ namespace Utils
void Entities::deleteTriggers() void Entities::deleteTriggers()
{ {
for(auto i = this->entities.begin(); i != this->entities.end();) for (auto i = this->entities.begin(); i != this->entities.end();)
{ {
if(i->find("classname") != i->end()) if (i->find("classname") != i->end())
{ {
std::string classname = (*i)["classname"]; std::string classname = (*i)["classname"];
if(Utils::String::StartsWith(classname, "trigger_")) if (Utils::String::StartsWith(classname, "trigger_"))
{ {
i = this->entities.erase(i); i = this->entities.erase(i);
continue; continue;
@ -105,64 +105,64 @@ namespace Utils
std::string value; std::string value;
std::unordered_map<std::string, std::string> entity; std::unordered_map<std::string, std::string> entity;
for(unsigned int i = 0; i < buffer.size(); ++i) for (unsigned int i = 0; i < buffer.size(); ++i)
{ {
char character = buffer[i]; char character = buffer[i];
if(character == '{') if (character == '{')
{ {
entity.clear(); entity.clear();
} }
switch(character) switch (character)
{ {
case '{': case '{':
{ {
entity.clear(); entity.clear();
break; break;
} }
case '}': case '}':
{ {
this->entities.push_back(entity); this->entities.push_back(entity);
entity.clear(); entity.clear();
break; break;
} }
case '"': case '"':
{
if (parseState == PARSE_AWAIT_KEY)
{ {
if (parseState == PARSE_AWAIT_KEY) key.clear();
{ parseState = PARSE_READ_KEY;
key.clear();
parseState = PARSE_READ_KEY;
}
else if (parseState == PARSE_READ_KEY)
{
parseState = PARSE_AWAIT_VALUE;
}
else if (parseState == PARSE_AWAIT_VALUE)
{
value.clear();
parseState = PARSE_READ_VALUE;
}
else if (parseState == PARSE_READ_VALUE)
{
entity[Utils::String::ToLower(key)] = value;
parseState = PARSE_AWAIT_KEY;
}
else
{
throw std::runtime_error("Parsing error!");
}
break;
} }
else if (parseState == PARSE_READ_KEY)
default:
{ {
if(parseState == PARSE_READ_KEY) key.push_back(character); parseState = PARSE_AWAIT_VALUE;
else if (parseState == PARSE_READ_VALUE) value.push_back(character);
break;
} }
else if (parseState == PARSE_AWAIT_VALUE)
{
value.clear();
parseState = PARSE_READ_VALUE;
}
else if (parseState == PARSE_READ_VALUE)
{
entity[Utils::String::ToLower(key)] = value;
parseState = PARSE_AWAIT_KEY;
}
else
{
throw std::runtime_error("Parsing error!");
}
break;
}
default:
{
if (parseState == PARSE_READ_KEY) key.push_back(character);
else if (parseState == PARSE_READ_VALUE) value.push_back(character);
break;
}
} }
} }
} }

View File

@ -185,7 +185,7 @@ namespace Utils
this->installed = false; this->installed = false;
if(unprotect) VirtualProtect(this->place, sizeof(this->buffer), PAGE_EXECUTE_READWRITE, &this->protection); if (unprotect) VirtualProtect(this->place, sizeof(this->buffer), PAGE_EXECUTE_READWRITE, &this->protection);
std::memcpy(this->place, this->buffer, sizeof(this->buffer)); std::memcpy(this->place, this->buffer, sizeof(this->buffer));

View File

@ -69,7 +69,7 @@ namespace Utils
{ {
std::ifstream stream(file, std::ios::binary); std::ifstream stream(file, std::ios::binary);
if(stream.good()) if (stream.good())
{ {
stream.seekg(0, std::ios::end); stream.seekg(0, std::ios::end);
return static_cast<size_t>(stream.tellg()); return static_cast<size_t>(stream.tellg());

View File

@ -8,7 +8,7 @@ namespace Utils
{ {
void* data = _aligned_malloc(length, alignment); void* data = _aligned_malloc(length, alignment);
assert(data != nullptr); assert(data != nullptr);
if(data) ZeroMemory(data, length); if (data) ZeroMemory(data, length);
return data; return data;
} }

View File

@ -131,7 +131,7 @@ namespace Utils
unsigned int ePtr = reinterpret_cast<unsigned int>(entry.first); unsigned int ePtr = reinterpret_cast<unsigned int>(entry.first);
unsigned int tPtr = reinterpret_cast<unsigned int>(pointer); unsigned int tPtr = reinterpret_cast<unsigned int>(pointer);
if(Utils::HasIntercection(ePtr, entry.second, tPtr, length)) if (Utils::HasIntercection(ePtr, entry.second, tPtr, length))
{ {
MessageBoxA(nullptr, "Duplicate data written!", "ERROR", MB_ICONERROR); MessageBoxA(nullptr, "Duplicate data written!", "ERROR", MB_ICONERROR);
__debugbreak(); __debugbreak();
@ -290,7 +290,7 @@ namespace Utils
#ifdef WRITE_LOGS #ifdef WRITE_LOGS
std::string data = fmt::sprintf("%*s%d\n", this->structLevel, "", size); std::string data = fmt::sprintf("%*s%d\n", this->structLevel, "", size);
if(stream == Game::XFILE_BLOCK_RUNTIME) data = fmt::sprintf("%*s(%d)\n", this->structLevel, "", size); if (stream == Game::XFILE_BLOCK_RUNTIME) data = fmt::sprintf("%*s(%d)\n", this->structLevel, "", size);
Utils::IO::WriteFile("userraw/logs/zb_writes.log", data, true); Utils::IO::WriteFile("userraw/logs/zb_writes.log", data, true);
#endif #endif
} }

View File

@ -153,11 +153,11 @@ namespace Utils
void leaveCriticalSection(); void leaveCriticalSection();
bool isCriticalSection(); bool isCriticalSection();
// for recording zb writes // for recording zb writes
#ifdef WRITE_LOGS #ifdef WRITE_LOGS
int structLevel; int structLevel;
void enterStruct(const char* structName); void enterStruct(const char* structName);
void leaveStruct(); void leaveStruct();
#endif #endif
// This represents packed offset in streams: // This represents packed offset in streams:

View File

@ -16,7 +16,7 @@ namespace Utils
va_start(ap, fmt); va_start(ap, fmt);
const char* result; const char* result;
if(Components::Loader::IsUninitializing()) result = globalProvider.get(fmt, ap); if (Components::Loader::IsUninitializing()) result = globalProvider.get(fmt, ap);
else result = provider.get(fmt, ap); else result = provider.get(fmt, ap);
va_end(ap); va_end(ap);
@ -113,14 +113,20 @@ namespace Utils
// trim from start // trim from start
std::string &LTrim(std::string &s) std::string &LTrim(std::string &s)
{ {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(IsSpace)))); s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int val)
{
return !IsSpace(val);
}));
return s; return s;
} }
// trim from end // trim from end
std::string &RTrim(std::string &s) std::string &RTrim(std::string &s)
{ {
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(IsSpace))).base(), s.end()); s.erase(std::find_if(s.rbegin(), s.rend(), [](int val)
{
return !IsSpace(val);
}).base(), s.end());
return s; return s;
} }

View File

@ -47,7 +47,7 @@ namespace Utils
~Entry() ~Entry()
{ {
if(this->buffer) Utils::Memory::GetAllocator()->free(this->buffer); if (this->buffer) Utils::Memory::GetAllocator()->free(this->buffer);
this->size = 0; this->size = 0;
this->buffer = nullptr; this->buffer = nullptr;
} }

Some files were not shown because too many files have changed in this diff Show More