Merge branch 'develop' into runtime_errors

This commit is contained in:
INeedBots 2020-12-10 03:32:23 -06:00
commit 442980c056
32 changed files with 525 additions and 685 deletions

View File

@ -4,15 +4,50 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.3.0/) and this project adheres to [Semantic Versioning](http://semver.org/). The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0.3.0/) and this project adheres to [Semantic Versioning](http://semver.org/).
## [unreleased] - xxxx-xx-xx ## [0.6.1 Community] - 2020-12-05
### Added ### Added
- Add host information to /info endpoint (request) - Add host information to /info endpoint (request)
- Add fileWrite GSC Function (#36)
- Add fileRead GSC Function (#36)
- Add fileExists GSC Function (#36)
- Add fileRemove GSC Function (#36)
- Add botMovement GSC Function (#46)
- Add botAction GSC Function (#46)
- Add botWeapon GSC Function (#46)
- Add botStop GSC Function (#46)
- Add isBot GSC Function (#46)
- Add setPing GSC Function (#46)
- Add GetSystemTime and GetSystemTimeMilliseconds GSC Functions (#46)
- Add PrintConsole GSC Function (#46)
- Add Exec GSC Function (#46)
- Add getIP GSC Method (#36)
- Add getPing GSC Method (#36)
- Add scr_intermissionTime GSC Function (#25)
- Add g_playerCollision Dvar (#36)
- Add g_playerEjection Dvar (#36)
- Add r_specularCustomMaps Dvar (#36)
- Unlock safeArea_horizontal and safeArea_vertical Dvars (#42)
- Unlock cg_fovscale Dvar (#47)
### Changed ### Changed
- Stats are now separate for each mod (#6). Player stats are copied to `fs_game` folder if no stats exist for this mod yet. Keep in mind this also means that level, XP and classes will not be synchronized with the main stats file after this point. - Stats are now separate for each mod (#6). Player stats are copied to `fs_game` folder if no stats exist for this mod yet. Keep in mind this also means that level, XP and classes will not be synchronized with the main stats file after this point.
- Reduced duration of toasts (#48)
- Removed old updater functionality
- Use old bot names if bots.txt is not found (#46)
- Removed Steam integration because Steam updates kept breaking it (#51)
### Fixed
- Fixed a node system related crash (#45)
- Fixed an issue that made dedicated servers crash when info was requested during map rotation (#43)
- Fixed an issue where the game was trying to decrypt gsc files which caused it to crash when loading mods (#35)
#######################End of official IW4x Development - Project goes Open Source#######################
## [0.6.0] - 2018-12-30 ## [0.6.0] - 2018-12-30

View File

@ -12,7 +12,7 @@ namespace Components
std::lock_guard<std::mutex> _(Changelog::Mutex); std::lock_guard<std::mutex> _(Changelog::Mutex);
Changelog::Lines.clear(); Changelog::Lines.clear();
std::string data = Utils::Cache::GetFile("/iw4/changelog.txt"); std::string data = Utils::Cache::GetFile("/develop/CHANGELOG.md");
if (data.empty()) if (data.empty())
{ {

View File

@ -13,7 +13,7 @@ namespace Components
~ClanTags(); ~ClanTags();
private: private:
static std::string ClanTags::Tags[18]; static std::string Tags[18];
static void DrawPlayerNameOnScoreboard(); static void DrawPlayerNameOnScoreboard();

View File

@ -31,7 +31,7 @@ namespace Components
if (mode != "append"s && mode != "write"s) if (mode != "append"s && mode != "write"s)
{ {
Game::Com_Printf(0, "^3fileWrite: mode not defined or was wrong, defaulting to 'write'\n"); Game::Com_Printf(0, "^3fileWrite: mode not defined or was wrong, defaulting to 'write'\n");
mode = "write"; mode = const_cast<char*>("write");
} }
if (mode == "write"s) if (mode == "write"s)

View File

@ -25,7 +25,7 @@ namespace Components
char* Command::ClientParams::get(size_t index) char* Command::ClientParams::get(size_t index)
{ {
if (index >= this->length()) return ""; if (index >= this->length()) return const_cast<char*>("");
return Game::cmd_argv[this->commandId][index]; return Game::cmd_argv[this->commandId][index];
} }
@ -36,7 +36,7 @@ namespace Components
char* Command::ServerParams::get(size_t index) char* Command::ServerParams::get(size_t index)
{ {
if (index >= this->length()) return ""; if (index >= this->length()) return const_cast<char*>("");
return Game::cmd_argv_sv[this->commandId][index]; return Game::cmd_argv_sv[this->commandId][index];
} }

View File

@ -537,7 +537,7 @@ namespace Components
Console::Console() Console::Console()
{ {
// Console '%s: %s> ' string // Console '%s: %s> ' string
Utils::Hook::Set<char*>(0x5A44B4, "IW4x: " VERSION "> "); Utils::Hook::Set<const char*>(0x5A44B4, "IW4x: " VERSION "> ");
// Patch console color // Patch console color
static float consoleColor[] = { 0.70f, 1.00f, 0.00f, 1.00f }; static float consoleColor[] = { 0.70f, 1.00f, 0.00f, 1.00f };

View File

@ -27,7 +27,7 @@ namespace Components
return const_cast<char*>(this->dvar->current.string); return const_cast<char*>(this->dvar->current.string);
} }
return ""; return const_cast<char*>("");
} }
template <> const char* Dvar::Var::get() template <> const char* Dvar::Var::get()
{ {

View File

@ -186,7 +186,7 @@ namespace Components
{ {
std::lock_guard<std::recursive_mutex> _(Friends::Mutex); std::lock_guard<std::recursive_mutex> _(Friends::Mutex);
const unsigned int modId = *reinterpret_cast<unsigned int*>("IW4x") | 0x80000000; const unsigned int modId = *reinterpret_cast<unsigned int*>(const_cast<char*>("IW4x")) | 0x80000000;
// Split up the list // Split up the list
for (auto entry : Friends::FriendsList) for (auto entry : Friends::FriendsList)

View File

@ -766,8 +766,7 @@ namespace Components
{ {
if (pack.index == dlc) if (pack.index == dlc)
{ {
News::LaunchUpdater(Utils::String::VA("-dlc %i -c", pack.index)); ShellExecute(0, 0, L"https://xlabs.dev/support_iw4x_client.html", 0, 0, SW_SHOW);
//ShellExecuteA(nullptr, "open", pack.url.data(), nullptr, nullptr, SW_SHOWNORMAL);
return; return;
} }
} }

View File

@ -907,6 +907,7 @@ namespace Components
Menus::Add("ui_mp/pc_store.menu"); Menus::Add("ui_mp/pc_store.menu");
Menus::Add("ui_mp/iw4x_credits.menu"); Menus::Add("ui_mp/iw4x_credits.menu");
Menus::Add("ui_mp/resetclass.menu"); Menus::Add("ui_mp/resetclass.menu");
Menus::Add("ui_mp/popup_customtitle.menu");
} }
Menus::~Menus() Menus::~Menus()

View File

@ -15,7 +15,7 @@ namespace Components
static void Add(const std::string& menu); static void Add(const std::string& menu);
static Game::MenuList* Menus::LoadCustomMenuList(const std::string& menu, Utils::Memory::Allocator* allocator); static Game::MenuList* LoadCustomMenuList(const std::string& menu, Utils::Memory::Allocator* allocator);
static std::vector<std::pair<bool, Game::menuDef_t*>> LoadMenu(Game::menuDef_t* menudef); static std::vector<std::pair<bool, Game::menuDef_t*>> LoadMenu(Game::menuDef_t* menudef);
static std::vector<std::pair<bool, Game::menuDef_t*>> LoadMenu(const std::string& file); static std::vector<std::pair<bool, Game::menuDef_t*>> LoadMenu(const std::string& file);

View File

@ -364,7 +364,7 @@ namespace Components
Utils::Hook::Set<BYTE>(0x4050A5, 125); Utils::Hook::Set<BYTE>(0x4050A5, 125);
// Parse port as short in Net_AddrToString // Parse port as short in Net_AddrToString
Utils::Hook::Set<char*>(0x4698E3, "%u.%u.%u.%u:%hu"); Utils::Hook::Set<const char*>(0x4698E3, "%u.%u.%u.%u:%hu");
// Install startup handler // Install startup handler
Utils::Hook(0x4FD4D4, Network::NetworkStartStub, HOOK_JUMP).install()->quick(); Utils::Hook(0x4FD4D4, Network::NetworkStartStub, HOOK_JUMP).install()->quick();

View File

@ -6,9 +6,6 @@ namespace Components
{ {
bool News::Terminate; bool News::Terminate;
std::thread News::Thread; std::thread News::Thread;
std::string News::UpdaterArgs;
std::string News::UpdaterHash;
std::mutex News::UpdaterMutex;
bool News::unitTest() bool News::unitTest()
{ {
@ -33,165 +30,18 @@ namespace Components
return result; return result;
} }
void News::ExitProcessStub(unsigned int exitCode)
{
std::this_thread::sleep_for(10ms);
STARTUPINFOA sInfo;
PROCESS_INFORMATION pInfo;
ZeroMemory(&sInfo, sizeof(sInfo));
ZeroMemory(&pInfo, sizeof(pInfo));
sInfo.cb = sizeof(sInfo);
CreateProcessA("updater.exe", const_cast<char*>(Utils::String::VA("updater.exe %s", News::UpdaterArgs.data())), nullptr, nullptr, false, NULL, nullptr, nullptr, &sInfo, &pInfo);
if (pInfo.hThread && pInfo.hThread != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hThread);
if (pInfo.hProcess && pInfo.hProcess != INVALID_HANDLE_VALUE) CloseHandle(pInfo.hProcess);
TerminateProcess(GetCurrentProcess(), exitCode);
}
bool News::GetLatestUpdater()
{
std::lock_guard<std::mutex> _(News::UpdaterMutex);
if (Utils::IO::FileExists("updater.exe"))
{
// Generate hash of local updater.exe
std::string localUpdater = Utils::IO::ReadFile("updater.exe");
localUpdater = Utils::Cryptography::SHA1::Compute(localUpdater, true);
static Utils::Time::Interval updateInterval;
if (News::UpdaterHash.empty() || updateInterval.elapsed(15min)) // Check for updater Update every 15 mins max
{
updateInterval.update();
std::string data = Utils::Cache::GetFile("/json/updater"); // {"updater.exe":{"SHA1":"*HASH*"}}
std::string error;
json11::Json listData = json11::Json::parse(data, error);
if (error.empty() || listData.is_object())
{
News::UpdaterHash = listData["updater.exe"]["SHA1"].string_value();
}
}
if (!News::UpdaterHash.empty() && localUpdater != News::UpdaterHash)
{
remove("updater.exe");
}
}
if (!Utils::IO::FileExists("updater.exe"))
{
return News::DownloadUpdater();
}
return true;
}
bool News::DownloadUpdater()
{
std::string data = Utils::Cache::GetFile("/iw4/updater.exe");
if (!data.empty())
{
Utils::IO::WriteFile("updater.exe", data);
return true;
}
return false;
}
const char* News::GetNewsText() const char* News::GetNewsText()
{ {
return Localization::Get("MPUI_MOTD_TEXT"); return Localization::Get("MPUI_MOTD_TEXT");
} }
void News::CheckForUpdate()
{
std::string _client = Utils::Cache::GetFile("/json/client");
if (!_client.empty())
{
std::string error;
json11::Json client = json11::Json::parse(_client.data(), error);
int revisionNumber;
if (client["revision"].is_number())
{
revisionNumber = client["revision"].int_value();
}
else if (client["revision"].is_string())
{
revisionNumber = atoi(client["revision"].string_value().data());
}
else return;
Dvar::Var("cl_updateversion").get<Game::dvar_t*>()->current.integer = revisionNumber;
Dvar::Var("cl_updateavailable").get<Game::dvar_t*>()->current.enabled = (revisionNumber > REVISION);
// if there is an update then show the toast, but only once
static bool showToast = true;
if (revisionNumber > REVISION && showToast)
{
showToast = false;
Scheduler::OnReady([]()
{
Toast::Show("cardicon_gears", "^4Update Available", "There is an update available for your client!", 5000);
});
}
}
}
void News::LaunchUpdater(const std::string& params)
{
if (News::Updating()) return;
News::UpdaterArgs = params;
Localization::SetTemp("MENU_RECONNECTING_TO_PARTY", "Downloading updater");
Command::Execute("openmenu popup_reconnectingtoparty", true);
// Run the updater on shutdown
Utils::Hook::Set(0x6D72A0, News::ExitProcessStub);
std::thread([]()
{
if (News::GetLatestUpdater())
{
Console::SetSkipShutdown();
Command::Execute("wait 300; quit;", false);
}
else
{
Localization::ClearTemp();
News::UpdaterArgs.clear();
Command::Execute("closemenu popup_reconnectingtoparty", false);
Game::ShowMessageBox("Failed to download the updater!", "Error");
}
}).detach();
}
bool News::Updating()
{
return !News::UpdaterArgs.empty();
}
News::News() News::News()
{ {
News::UpdaterArgs.clear();
News::UpdaterHash.clear();
if (ZoneBuilder::IsEnabled() || Dedicated::IsEnabled()) return; // Maybe also dedi? if (ZoneBuilder::IsEnabled() || Dedicated::IsEnabled()) return; // Maybe also dedi?
Dvar::Register<bool>("g_firstLaunch", true, Game::DVAR_FLAG_SAVED, ""); Dvar::Register<bool>("g_firstLaunch", true, Game::DVAR_FLAG_SAVED, "");
Dvar::Register<int>("cl_updateoldversion", REVISION, REVISION, REVISION, Game::DVAR_FLAG_WRITEPROTECTED, "Current version number."); Dvar::Register<int>("cl_updateoldversion", REVISION, REVISION, REVISION, Game::DVAR_FLAG_WRITEPROTECTED, "Current version number.");
Dvar::Register<int>("cl_updateversion", 0, 0, -1, Game::DVAR_FLAG_WRITEPROTECTED, "New version number.");
Dvar::Register<bool>("cl_updateavailable", false, Game::DVAR_FLAG_WRITEPROTECTED, "New update is available.");
UIScript::Add("checkFirstLaunch", [](UIScript::Token) UIScript::Add("checkFirstLaunch", [](UIScript::Token)
{ {
@ -221,8 +71,6 @@ namespace Components
Localization::Set("MPUI_CHANGELOG_TEXT", "Loading..."); Localization::Set("MPUI_CHANGELOG_TEXT", "Loading...");
Localization::Set("MPUI_MOTD_TEXT", NEWS_MOTD_DEFAULT); Localization::Set("MPUI_MOTD_TEXT", NEWS_MOTD_DEFAULT);
//News::GetLatestUpdater();
// make newsfeed (ticker) menu items not cut off based on safe area // make newsfeed (ticker) menu items not cut off based on safe area
Utils::Hook::Nop(0x63892D, 5); Utils::Hook::Nop(0x63892D, 5);
@ -230,17 +78,6 @@ 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*)
{
News::CheckForUpdate();
});
Command::Add("getautoupdate", [](Command::Params*)
{
if (!Dvar::Var("cl_updateavailable").get<Game::dvar_t*>()->current.enabled) return;
News::LaunchUpdater("-update -c");
});
if (!Utils::IsWineEnvironment() && !Loader::IsPerformingUnitTests()) if (!Utils::IsWineEnvironment() && !Loader::IsPerformingUnitTests())
{ {
News::Terminate = false; News::Terminate = false;
@ -257,12 +94,8 @@ namespace Components
if (!Loader::IsPerformingUnitTests() && !News::Terminate) if (!Loader::IsPerformingUnitTests() && !News::Terminate)
{ {
News::GetLatestUpdater();
while (!News::Terminate) while (!News::Terminate)
{ {
News::CheckForUpdate();
// Sleep for 3 minutes // Sleep for 3 minutes
for (int i = 0; i < 180 && !News::Terminate; ++i) for (int i = 0; i < 180 && !News::Terminate; ++i)
{ {
@ -274,12 +107,6 @@ namespace Components
} }
} }
News::~News()
{
News::UpdaterArgs.clear();
News::UpdaterHash.clear();
}
void News::preDestroy() void News::preDestroy()
{ {
News::Terminate = true; News::Terminate = true;

View File

@ -6,27 +6,16 @@ namespace Components
{ {
public: public:
News(); News();
~News();
void preDestroy() override; void preDestroy() override;
bool unitTest() override; bool unitTest() override;
static void LaunchUpdater(const std::string& params);
static bool Updating();
private: private:
static std::string UpdaterArgs;
static std::string UpdaterHash;
static std::thread Thread; static std::thread Thread;
static std::mutex UpdaterMutex;
static bool Terminate; static bool Terminate;
static bool GetLatestUpdater();
static bool DownloadUpdater(); static bool DownloadUpdater();
static void CheckForUpdate();
static void ExitProcessStub(unsigned int exitCode);
static const char* GetNewsText(); static const char* GetNewsText();
}; };
} }

View File

@ -210,7 +210,7 @@ namespace Components
// Force xblive_privatematch 0 and rename it // Force xblive_privatematch 0 and rename it
//Utils::Hook::Set<BYTE>(0x420A6A, 4); //Utils::Hook::Set<BYTE>(0x420A6A, 4);
Utils::Hook::Set<BYTE>(0x420A6C, 0); Utils::Hook::Set<BYTE>(0x420A6C, 0);
Utils::Hook::Set<char*>(0x420A6E, "xblive_privateserver"); Utils::Hook::Set<const char*>(0x420A6E, "xblive_privateserver");
// Remove migration shutdown, it causes crashes and will be destroyed when erroring anyways // Remove migration shutdown, it causes crashes and will be destroyed when erroring anyways
Utils::Hook::Nop(0x5A8E1C, 12); Utils::Hook::Nop(0x5A8E1C, 12);
@ -244,9 +244,9 @@ namespace Components
//Utils::Hook(0x4D5D51, Party::RegisterMinPlayers, HOOK_CALL).install()->quick(); //Utils::Hook(0x4D5D51, Party::RegisterMinPlayers, HOOK_CALL).install()->quick();
// Set ui_maxclients to sv_maxclients // Set ui_maxclients to sv_maxclients
Utils::Hook::Set<char*>(0x42618F, "sv_maxclients"); Utils::Hook::Set<const char*>(0x42618F, "sv_maxclients");
Utils::Hook::Set<char*>(0x4D3756, "sv_maxclients"); Utils::Hook::Set<const char*>(0x4D3756, "sv_maxclients");
Utils::Hook::Set<char*>(0x5E3772, "sv_maxclients"); Utils::Hook::Set<const char*>(0x5E3772, "sv_maxclients");
// Unlatch maxclient dvars // Unlatch maxclient dvars
Utils::Hook::Xor<BYTE>(0x426187, Game::dvar_flag::DVAR_FLAG_LATCHED); Utils::Hook::Xor<BYTE>(0x426187, Game::dvar_flag::DVAR_FLAG_LATCHED);

View File

@ -150,7 +150,7 @@ namespace Components
Playlist::Playlist() Playlist::Playlist()
{ {
// Default playlists // Default playlists
Utils::Hook::Set<char*>(0x60B06E, "playlists_default.info"); Utils::Hook::Set<const char*>(0x60B06E, "playlists_default.info");
// disable playlist download function // disable playlist download function
Utils::Hook::Set<BYTE>(0x4D4790, 0xC3); Utils::Hook::Set<BYTE>(0x4D4790, 0xC3);

View File

@ -159,7 +159,7 @@ namespace Components
__declspec(naked) void QuickPatch::InvalidNameStub() __declspec(naked) void QuickPatch::InvalidNameStub()
{ {
static char* kick_reason = "Invalid name detected."; static const char* kick_reason = "Invalid name detected.";
__asm __asm
{ {
@ -216,11 +216,11 @@ namespace Components
{ {
static std::vector < char * > values = static std::vector < char * > values =
{ {
"auto", const_cast<char*>("auto"),
"standard", const_cast<char*>("standard"),
"wide 16:10", const_cast<char*>("wide 16:10"),
"wide 16:9", const_cast<char*>("wide 16:9"),
"custom", const_cast<char*>("custom"),
nullptr, nullptr,
}; };
@ -443,16 +443,16 @@ namespace Components
Utils::Hook::Set<DWORD>(0x45ACE0, 0xC301B0); Utils::Hook::Set<DWORD>(0x45ACE0, 0xC301B0);
// fs_basegame // fs_basegame
Utils::Hook::Set<char*>(0x6431D1, BASEGAME); Utils::Hook::Set<const char*>(0x6431D1, BASEGAME);
// UI version string // UI version string
Utils::Hook::Set<char*>(0x43F73B, "IW4x: " VERSION); Utils::Hook::Set<const char*>(0x43F73B, "IW4x: " VERSION);
// console version string // console version string
Utils::Hook::Set<char*>(0x4B12BB, "IW4x " VERSION " (built " __DATE__ " " __TIME__ ")"); Utils::Hook::Set<const char*>(0x4B12BB, "IW4x " VERSION " (built " __DATE__ " " __TIME__ ")");
// version string // version string
Utils::Hook::Set<char*>(0x60BD56, "IW4x (" VERSION ")"); Utils::Hook::Set<const char*>(0x60BD56, "IW4x (" VERSION ")");
// version string color // version string color
static float buildLocColor[] = { 1.0f, 1.0f, 1.0f, 0.8f }; static float buildLocColor[] = { 1.0f, 1.0f, 1.0f, 0.8f };
@ -469,33 +469,33 @@ namespace Components
// console title // console title
if (ZoneBuilder::IsEnabled()) if (ZoneBuilder::IsEnabled())
{ {
Utils::Hook::Set<char*>(0x4289E8, "IW4x (" VERSION "): ZoneBuilder"); Utils::Hook::Set<const char*>(0x4289E8, "IW4x (" VERSION "): ZoneBuilder");
} }
else if (Dedicated::IsEnabled()) else if (Dedicated::IsEnabled())
{ {
Utils::Hook::Set<char*>(0x4289E8, "IW4x (" VERSION "): Dedicated"); Utils::Hook::Set<const char*>(0x4289E8, "IW4x (" VERSION "): Dedicated");
} }
else else
{ {
Utils::Hook::Set<char*>(0x4289E8, "IW4x (" VERSION "): Console"); Utils::Hook::Set<const char*>(0x4289E8, "IW4x (" VERSION "): Console");
} }
// window title // window title
Utils::Hook::Set<char*>(0x5076A0, "IW4x: Multiplayer"); Utils::Hook::Set<const char*>(0x5076A0, "IW4x: Multiplayer");
// sv_hostname // sv_hostname
Utils::Hook::Set<char*>(0x4D378B, "IW4Host"); Utils::Hook::Set<const char*>(0x4D378B, "IW4Host");
// shortversion // shortversion
Utils::Hook::Set<char*>(0x60BD91, SHORTVERSION); Utils::Hook::Set<const char*>(0x60BD91, SHORTVERSION);
// console logo // console logo
Utils::Hook::Set<char*>(0x428A66, BASEGAME "/images/logo.bmp"); Utils::Hook::Set<const char*>(0x428A66, BASEGAME "/images/logo.bmp");
// splash logo // splash logo
Utils::Hook::Set<char*>(0x475F9E, BASEGAME "/images/splash.bmp"); Utils::Hook::Set<const char*>(0x475F9E, BASEGAME "/images/splash.bmp");
Utils::Hook::Set<char*>(0x4876C6, "Successfully read stats data\n"); Utils::Hook::Set<const char*>(0x4876C6, "Successfully read stats data\n");
// Numerical ping (cg_scoreboardPingText 1) // Numerical ping (cg_scoreboardPingText 1)
Utils::Hook::Set<BYTE>(0x45888E, 1); Utils::Hook::Set<BYTE>(0x45888E, 1);
@ -596,21 +596,21 @@ namespace Components
// intro stuff // intro stuff
Utils::Hook::Nop(0x60BEE9, 5); // Don't show legals Utils::Hook::Nop(0x60BEE9, 5); // Don't show legals
Utils::Hook::Nop(0x60BEF6, 5); // Don't reset the intro dvar Utils::Hook::Nop(0x60BEF6, 5); // Don't reset the intro dvar
Utils::Hook::Set<char*>(0x60BED2, "unskippablecinematic IW_logo\n"); Utils::Hook::Set<const char*>(0x60BED2, "unskippablecinematic IW_logo\n");
Utils::Hook::Set<char*>(0x51C2A4, "%s\\" BASEGAME "\\video\\%s.bik"); Utils::Hook::Set<const char*>(0x51C2A4, "%s\\" BASEGAME "\\video\\%s.bik");
Utils::Hook::Set<DWORD>(0x51C2C2, 0x78A0AC); Utils::Hook::Set<DWORD>(0x51C2C2, 0x78A0AC);
// Redirect logs // Redirect logs
Utils::Hook::Set<char*>(0x5E44D8, "logs/games_mp.log"); Utils::Hook::Set<const char*>(0x5E44D8, "logs/games_mp.log");
Utils::Hook::Set<char*>(0x60A90C, "logs/console_mp.log"); Utils::Hook::Set<const char*>(0x60A90C, "logs/console_mp.log");
Utils::Hook::Set<char*>(0x60A918, "logs/console_mp.log"); Utils::Hook::Set<const char*>(0x60A918, "logs/console_mp.log");
// Rename config // Rename config
Utils::Hook::Set<char*>(0x461B4B, CLIENT_CONFIG); Utils::Hook::Set<const char*>(0x461B4B, CLIENT_CONFIG);
Utils::Hook::Set<char*>(0x47DCBB, CLIENT_CONFIG); Utils::Hook::Set<const char*>(0x47DCBB, CLIENT_CONFIG);
Utils::Hook::Set<char*>(0x6098F8, CLIENT_CONFIG); Utils::Hook::Set<const char*>(0x6098F8, CLIENT_CONFIG);
Utils::Hook::Set<char*>(0x60B279, CLIENT_CONFIG); Utils::Hook::Set<const char*>(0x60B279, CLIENT_CONFIG);
Utils::Hook::Set<char*>(0x60BBD4, CLIENT_CONFIG); Utils::Hook::Set<const char*>(0x60BBD4, CLIENT_CONFIG);
// Disable profile system // Disable profile system
// Utils::Hook::Nop(0x60BEB1, 5); // GamerProfile_InitAllProfiles - Causes an error, when calling a harrier killstreak. // Utils::Hook::Nop(0x60BEB1, 5); // GamerProfile_InitAllProfiles - Causes an error, when calling a harrier killstreak.

View File

@ -7,6 +7,6 @@ namespace Components
public: public:
RawFiles(); RawFiles();
static void* RawFiles::LoadModdableRawfileFunc(const char* filename); static void* LoadModdableRawfileFunc(const char* filename);
}; };
} }

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<const 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

@ -22,7 +22,7 @@ namespace Components
return this->token; return this->token;
} }
return ""; return const_cast<char*>("");
} }
template<> const char* UIScript::Token::get() template<> const char* UIScript::Token::get()

View File

@ -510,7 +510,7 @@ namespace Components
// Add branding asset // Add branding asset
void ZoneBuilder::Zone::addBranding() void ZoneBuilder::Zone::addBranding()
{ {
char* data = "FastFile built using the IW4x ZoneBuilder!"; const 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)
@ -1306,7 +1306,7 @@ namespace Components
// HACK: set language to 'techsets' to load from that dir // HACK: set language to 'techsets' to load from that dir
char* language = Utils::Hook::Get<char*>(0x649E740); char* language = Utils::Hook::Get<char*>(0x649E740);
Utils::Hook::Set<char*>(0x649E740, "techsets"); Utils::Hook::Set<const char*>(0x649E740, "techsets");
// load generated techset fastfiles // load generated techset fastfiles
auto list = Utils::IO::ListFiles("zone/techsets"); auto list = Utils::IO::ListFiles("zone/techsets");
@ -1366,7 +1366,7 @@ namespace Components
info.freeFlags = Game::DB_ZONE_MOD; info.freeFlags = Game::DB_ZONE_MOD;
Game::DB_LoadXAssets(&info, 1, true); Game::DB_LoadXAssets(&info, 1, true);
Utils::Hook::Set<char*>(0x649E740, "techsets"); Utils::Hook::Set<const char*>(0x649E740, "techsets");
i = 0; i = 0;
subCount++; subCount++;

View File

@ -693,7 +693,7 @@ namespace Game
void Vec3Normalize(vec3_t& vec) void Vec3Normalize(vec3_t& vec)
{ {
const auto length = std::sqrt(std::pow(vec[0], 2) + std::pow(vec[1], 2) + std::pow(vec[2], 2)); const float length = static_cast<float>(std::sqrt(std::pow(vec[0], 2) + std::pow(vec[1], 2) + std::pow(vec[2], 2)));
vec[0] /= length; vec[0] /= length;
vec[1] /= length; vec[1] /= length;
vec[2] /= length; vec[2] /= length;

View File

@ -24,7 +24,7 @@ namespace Steam
{ {
if (Components::Dedicated::IsEnabled() || Components::ZoneBuilder::IsEnabled()) // Dedi guid if (Components::Dedicated::IsEnabled() || Components::ZoneBuilder::IsEnabled()) // Dedi guid
{ {
idBits = *reinterpret_cast<unsigned __int64*>(static_cast<char*>("DEDICATE")); idBits = *reinterpret_cast<unsigned __int64*>(const_cast<char*>("DEDICATE"));
} }
else if (Components::Singleton::IsFirstInstance()) // ECDSA guid else if (Components::Singleton::IsFirstInstance()) // ECDSA guid
{ {

View File

@ -154,7 +154,7 @@ namespace Steam
gameID.type = 1; // k_EGameIDTypeGameMod gameID.type = 1; // k_EGameIDTypeGameMod
gameID.appID = Proxy::AppId & 0xFFFFFF; gameID.appID = Proxy::AppId & 0xFFFFFF;
char* modId = "IW4x"; char* modId = const_cast<char*>("IW4x");
gameID.modID = *reinterpret_cast<unsigned int*>(modId) | 0x80000000; gameID.modID = *reinterpret_cast<unsigned int*>(modId) | 0x80000000;
Interface clientUtils(Proxy::ClientEngine->GetIClientUtils(Proxy::SteamPipe)); Interface clientUtils(Proxy::ClientEngine->GetIClientUtils(Proxy::SteamPipe));
@ -194,7 +194,7 @@ namespace Steam
void Proxy::RunMod() void Proxy::RunMod()
{ {
char* command = "-proc "; const char* command = "-proc ";
char* parentProc = strstr(GetCommandLineA(), command); char* parentProc = strstr(GetCommandLineA(), command);
if (parentProc) if (parentProc)

View File

@ -111,7 +111,8 @@ namespace Steam
{ {
bool SteamAPI_Init() bool SteamAPI_Init()
{ {
Proxy::SetGame(10190); //The latest steam update has broke IW4x's steam integration. As of now the best way of dealing with this is to just disable it. This has been commented out so that if fixed, this may be easily enabled once again.
/*Proxy::SetGame(10190);
if (!Proxy::Inititalize()) if (!Proxy::Inititalize())
{ {
@ -122,7 +123,7 @@ namespace Steam
{ {
Proxy::SetMod("IW4x: Modern Warfare 2"); Proxy::SetMod("IW4x: Modern Warfare 2");
Proxy::RunGame(); Proxy::RunGame();
} }*/
return true; return true;
} }

View File

@ -4,27 +4,15 @@ namespace Utils
{ {
const char* Cache::Urls[] = const char* Cache::Urls[] =
{ {
"https://iw4x.org", "https://xlabs.dev",
"https://raw.githubusercontent.com/XLabsProject/iw4x-client"
"https://iw4xcachep26muba.onion.to", //Links to old onion site - deprecated
"https://iw4xcachep26muba.tor2web.xyz", //"https://iw4xcachep26muba.tor2web.xyz",
"https://iw4xcachep26muba.onion.ws", //"https://iw4xcachep26muba.onion.ws",
"https://iw4xcachep26muba.onion.sh", //"https://iw4xcachep26muba.onion.sh",
"https://iw4xcachep26muba.onion.pet", //"https://iw4xcachep26muba.onion.pet",
// Links below are dead
// Still, let's keep them in case they come back
"https://iw4xcachep26muba.onion.rip",
"https://iw4xcachep26muba.onion.nu",
"https://iw4xcachep26muba.onion.guide",
"https://iw4xcachep26muba.onion.casa",
"https://iw4xcachep26muba.hiddenservice.net",
"https://iw4xcachep26muba.onion.cab",
"https://iw4xcachep26muba.onion.link",
// Not registered yet
//"https://iw4xcachejnetuln.onion.to",
//"https://iw4xcachedjodc4y.onion.to",
}; };
std::string Cache::ValidUrl; std::string Cache::ValidUrl;
std::mutex Cache::CacheMutex; std::mutex Cache::CacheMutex;

View File

@ -18,7 +18,7 @@ namespace Utils
{ {
if (this->tokenString.empty()) if (this->tokenString.empty())
{ {
this->tokenString.append(reinterpret_cast<uint8_t*>("\0"), 1); this->tokenString.append(reinterpret_cast<uint8_t*>(const_cast<char *>("\0")), 1);
} }
else else
{ {
@ -31,7 +31,7 @@ namespace Utils
if (!i) if (!i)
{ {
// Prepend here, as /dev/urandom says so ;) https://github.com/IW4x/iw4x-client-node/wikis/technical-information#incrementing-the-token // Prepend here, as /dev/urandom says so ;) https://github.com/IW4x/iw4x-client-node/wikis/technical-information#incrementing-the-token
this->tokenString = std::basic_string<uint8_t>(reinterpret_cast<uint8_t*>("\0"), 1) + this->tokenString; this->tokenString = std::basic_string<uint8_t>(reinterpret_cast<uint8_t*>(const_cast<char*>("\0")), 1) + this->tokenString;
break; break;
} }
} }

View File

@ -2,9 +2,9 @@
namespace Utils namespace Utils
{ {
Library::Library(const std::string& buffer, bool _freeOnDestroy) : module(nullptr), freeOnDestroy(_freeOnDestroy) Library::Library(const std::string& buffer, bool _freeOnDestroy) : _module(nullptr), freeOnDestroy(_freeOnDestroy)
{ {
this->module = LoadLibraryExA(buffer.data(), nullptr, 0); this->_module = LoadLibraryExA(buffer.data(), nullptr, 0);
} }
Library::~Library() Library::~Library()
@ -22,7 +22,7 @@ namespace Utils
HMODULE Library::getModule() HMODULE Library::getModule()
{ {
return this->module; return this->_module;
} }
void Library::free() void Library::free()
@ -32,6 +32,6 @@ namespace Utils
FreeLibrary(this->getModule()); FreeLibrary(this->getModule());
} }
this->module = nullptr; this->_module = nullptr;
} }
} }

View File

@ -5,7 +5,7 @@ namespace Utils
class Library class Library
{ {
public: public:
Library() : module(nullptr), freeOnDestroy(false) {}; Library() : _module(nullptr), freeOnDestroy(false) {};
Library(const std::string& buffer, bool freeOnDestroy = true); Library(const std::string& buffer, bool freeOnDestroy = true);
~Library(); ~Library();
@ -26,7 +26,7 @@ namespace Utils
void free(); void free();
private: private:
HMODULE module; HMODULE _module;
bool freeOnDestroy; bool freeOnDestroy;
}; };
} }

View File

@ -149,7 +149,7 @@ namespace Utils
std::string FormatBandwidth(size_t bytes, int milliseconds) std::string FormatBandwidth(size_t bytes, int milliseconds)
{ {
static char* sizes[] = static const char* sizes[] =
{ {
"B", "B",
"KB", "KB",

View File

@ -13,7 +13,7 @@ namespace Utils
VAProvider() : currentBuffer(0) {} VAProvider() : currentBuffer(0) {}
~VAProvider() {} ~VAProvider() {}
char* get(const char* format, va_list ap) const char* get(const char* format, va_list ap)
{ {
++this->currentBuffer %= ARRAYSIZE(this->stringPool); ++this->currentBuffer %= ARRAYSIZE(this->stringPool);
auto entry = &this->stringPool[this->currentBuffer]; auto entry = &this->stringPool[this->currentBuffer];

View File

@ -15,7 +15,7 @@ namespace Utils
bool IsWineEnvironment(); bool IsWineEnvironment();
unsigned long GetParentProcessId(); unsigned long GetParentProcessId();
size_t GetModuleSize(HMODULE module); size_t GetModuleSize(HMODULE);
void* GetThreadStartAddress(HANDLE hThread); void* GetThreadStartAddress(HANDLE hThread);
HMODULE GetNTDLL(); HMODULE GetNTDLL();