[General]: Fix some things (#667)
This commit is contained in:
parent
79758e1752
commit
01a629d02b
@ -21,7 +21,6 @@
|
||||
| `--copy-to=PATH` | Optional, copy the DLL to a custom folder after build, define the path here if wanted. |
|
||||
| `--copy-pdb` | Copy debug information for binaries as well to the path given via --copy-to. |
|
||||
| `--force-unit-tests` | Always compile unit tests. |
|
||||
| `--force-exception-handler` | Install custom unhandled exception handler even for Debug builds. |
|
||||
| `--disable-binary-check` | Do not perform integrity checks on the exe. |
|
||||
|
||||
## Command line arguments
|
||||
|
@ -76,11 +76,6 @@ newoption {
|
||||
description = "Always compile unit tests."
|
||||
}
|
||||
|
||||
newoption {
|
||||
trigger = "force-exception-handler",
|
||||
description = "Install custom unhandled exception handler even for Debug builds."
|
||||
}
|
||||
|
||||
newoption {
|
||||
trigger = "disable-binary-check",
|
||||
description = "Do not perform integrity checks on the exe."
|
||||
@ -257,9 +252,6 @@ workspace "iw4x"
|
||||
if _OPTIONS["force-unit-tests"] then
|
||||
defines {"FORCE_UNIT_TESTS"}
|
||||
end
|
||||
if _OPTIONS["force-exception-handler"] then
|
||||
defines {"FORCE_EXCEPTION_HANDLER"}
|
||||
end
|
||||
if _OPTIONS["disable-binary-check"] then
|
||||
defines {"DISABLE_BINARY_CHECK"}
|
||||
end
|
||||
|
@ -9,128 +9,128 @@ namespace Components
|
||||
|
||||
bool Loader::IsPregame()
|
||||
{
|
||||
return Loader::Pregame;
|
||||
return Pregame;
|
||||
}
|
||||
|
||||
bool Loader::IsPostgame()
|
||||
{
|
||||
return Loader::Postgame;
|
||||
return Postgame;
|
||||
}
|
||||
|
||||
bool Loader::IsUninitializing()
|
||||
{
|
||||
return Loader::Uninitializing;
|
||||
return Uninitializing;
|
||||
}
|
||||
|
||||
void Loader::Initialize()
|
||||
{
|
||||
Loader::Pregame = true;
|
||||
Loader::Postgame = false;
|
||||
Loader::Uninitializing = false;
|
||||
Pregame = true;
|
||||
Postgame = false;
|
||||
Uninitializing = false;
|
||||
Utils::Memory::GetAllocator()->clear();
|
||||
|
||||
Loader::Register(new Flags());
|
||||
Loader::Register(new Singleton());
|
||||
// Install our exception handler as early as posssible to get better debug dumps from startup crashes
|
||||
Loader::Register(new Exception());
|
||||
Loader::Register(new Auth());
|
||||
Loader::Register(new Bans());
|
||||
Loader::Register(new Dvar());
|
||||
Loader::Register(new Bots());
|
||||
Loader::Register(new Lean());
|
||||
Loader::Register(new Maps());
|
||||
Loader::Register(new News());
|
||||
Loader::Register(new Node());
|
||||
Loader::Register(new RCon());
|
||||
Loader::Register(new Stats());
|
||||
Loader::Register(new Menus());
|
||||
Loader::Register(new Toast());
|
||||
Loader::Register(new Party());
|
||||
Loader::Register(new Zones());
|
||||
Loader::Register(new D3D9Ex());
|
||||
Loader::Register(new Logger());
|
||||
Loader::Register(new Weapon());
|
||||
Loader::Register(new Window());
|
||||
Loader::Register(new Command());
|
||||
Loader::Register(new Console());
|
||||
Loader::Register(new Friends());
|
||||
Loader::Register(new IPCPipe());
|
||||
Loader::Register(new MapDump());
|
||||
Loader::Register(new ModList());
|
||||
Loader::Register(new Network());
|
||||
Loader::Register(new NetworkDebug());
|
||||
Loader::Register(new Session());
|
||||
Loader::Register(new Theatre());
|
||||
Loader::Register(new ClanTags());
|
||||
Loader::Register(new Download());
|
||||
Loader::Register(new Playlist());
|
||||
Loader::Register(new RawFiles());
|
||||
Loader::Register(new Renderer());
|
||||
Loader::Register(new UIFeeder());
|
||||
Loader::Register(new UIScript());
|
||||
Loader::Register(new Changelog());
|
||||
Loader::Register(new Dedicated());
|
||||
Loader::Register(new Discovery());
|
||||
Loader::Register(new FastFiles());
|
||||
Loader::Register(new Gametypes());
|
||||
Loader::Register(new Materials());
|
||||
Loader::Register(new Scheduler());
|
||||
Loader::Register(new Threading());
|
||||
Loader::Register(new CardTitles());
|
||||
Loader::Register(new FileSystem());
|
||||
Loader::Register(new ModelSurfs());
|
||||
Loader::Register(new PlayerName());
|
||||
Loader::Register(new QuickPatch());
|
||||
Loader::Register(new Security());
|
||||
Loader::Register(new ServerInfo());
|
||||
Loader::Register(new ServerList());
|
||||
Loader::Register(new SlowMotion());
|
||||
Loader::Register(new ArenaLength());
|
||||
Loader::Register(new StringTable());
|
||||
Loader::Register(new ZoneBuilder());
|
||||
Loader::Register(new AssetHandler());
|
||||
Loader::Register(new Localization());
|
||||
Loader::Register(new ServerCommands());
|
||||
Loader::Register(new StructuredData());
|
||||
Loader::Register(new ConnectProtocol());
|
||||
Loader::Register(new StartupMessages());
|
||||
Loader::Register(new SoundMutexFix());
|
||||
Loader::Register(new Gamepad());
|
||||
Loader::Register(new Chat());
|
||||
Loader::Register(new TextRenderer());
|
||||
Loader::Register(new PlayerMovement());
|
||||
Loader::Register(new Elevators());
|
||||
Loader::Register(new ClientCommand());
|
||||
Loader::Register(new VisionFile());
|
||||
Loader::Register(new Branding());
|
||||
Loader::Register(new Debug());
|
||||
Loader::Register(new RawMouse());
|
||||
Loader::Register(new Bullet());
|
||||
Loader::Register(new MapRotation());
|
||||
Loader::Register(new Ceg());
|
||||
Loader::Register(new UserInfo());
|
||||
Loader::Register(new Events());
|
||||
Loader::Register(new Voice());
|
||||
Loader::Register(new Vote());
|
||||
Register(new Auth());
|
||||
Register(new Command());
|
||||
Register(new Dvar());
|
||||
Register(new Exception()); // Install our exception handler as early as posssible to get better debug dumps from startup crashes
|
||||
Register(new Flags());
|
||||
Register(new Network());
|
||||
Register(new Logger());
|
||||
Register(new Singleton());
|
||||
Register(new UIScript());
|
||||
Register(new ZoneBuilder());
|
||||
|
||||
Register(new ArenaLength());
|
||||
Register(new AssetHandler());
|
||||
Register(new Bans());
|
||||
Register(new Bots());
|
||||
Register(new Branding());
|
||||
Register(new Bullet());
|
||||
Register(new CardTitles());
|
||||
Register(new Ceg());
|
||||
Register(new Changelog());
|
||||
Register(new Chat());
|
||||
Register(new ClanTags());
|
||||
Register(new ClientCommand());
|
||||
Register(new ConnectProtocol());
|
||||
Register(new Console());
|
||||
Register(new D3D9Ex());
|
||||
Register(new Debug());
|
||||
Register(new Dedicated());
|
||||
Register(new Discovery());
|
||||
Register(new Download());
|
||||
Register(new Elevators());
|
||||
Register(new Events());
|
||||
Register(new FastFiles());
|
||||
Register(new FileSystem());
|
||||
Register(new Friends());
|
||||
Register(new Gamepad());
|
||||
Register(new Gametypes());
|
||||
Register(new IPCPipe());
|
||||
Register(new Lean());
|
||||
Register(new Localization());
|
||||
Register(new MapDump());
|
||||
Register(new MapRotation());
|
||||
Register(new Maps());
|
||||
Register(new Materials());
|
||||
Register(new Menus());
|
||||
Register(new ModList());
|
||||
Register(new ModelSurfs());
|
||||
Register(new NetworkDebug());
|
||||
Register(new News());
|
||||
Register(new Node());
|
||||
Register(new Party());
|
||||
Register(new PlayerMovement());
|
||||
Register(new PlayerName());
|
||||
Register(new Playlist());
|
||||
Register(new QuickPatch());
|
||||
Register(new RCon());
|
||||
Register(new RawFiles());
|
||||
Register(new RawMouse());
|
||||
Register(new Renderer());
|
||||
Register(new Scheduler());
|
||||
Register(new Security());
|
||||
Register(new ServerCommands());
|
||||
Register(new ServerInfo());
|
||||
Register(new ServerList());
|
||||
Register(new Session());
|
||||
Register(new SlowMotion());
|
||||
Register(new SoundMutexFix());
|
||||
Register(new StartupMessages());
|
||||
Register(new Stats());
|
||||
Register(new StringTable());
|
||||
Register(new StructuredData());
|
||||
Register(new TextRenderer());
|
||||
Register(new Theatre());
|
||||
Register(new Threading());
|
||||
Register(new Toast());
|
||||
Register(new UIFeeder());
|
||||
Register(new UserInfo());
|
||||
Register(new VisionFile());
|
||||
Register(new Voice());
|
||||
Register(new Vote());
|
||||
Register(new Weapon());
|
||||
Register(new Window());
|
||||
Register(new Zones());
|
||||
|
||||
Loader::Register(new GSC());
|
||||
Register(new GSC());
|
||||
|
||||
Loader::Pregame = false;
|
||||
Pregame = false;
|
||||
|
||||
// Make sure preDestroy is called when the game shuts down
|
||||
Scheduler::OnGameShutdown(Loader::PreDestroy);
|
||||
Scheduler::OnGameShutdown(PreDestroy);
|
||||
}
|
||||
|
||||
void Loader::Uninitialize()
|
||||
{
|
||||
Loader::Uninitializing = true;
|
||||
Loader::PreDestroyNoPostGame();
|
||||
Uninitializing = true;
|
||||
PreDestroyNoPostGame();
|
||||
|
||||
std::reverse(Loader::Components.begin(), Loader::Components.end());
|
||||
for (auto component : Loader::Components)
|
||||
std::reverse(Components.begin(), Components.end());
|
||||
for (auto& component : Components)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!Loader::IsPerformingUnitTests())
|
||||
if (!IsPerformingUnitTests())
|
||||
{
|
||||
Logger::Print("Unregister component: {}\n", component->getName());
|
||||
}
|
||||
@ -138,21 +138,21 @@ namespace Components
|
||||
delete component;
|
||||
}
|
||||
|
||||
Loader::Components.clear();
|
||||
Components.clear();
|
||||
Utils::Memory::GetAllocator()->clear();
|
||||
Loader::Uninitializing = false;
|
||||
Uninitializing = false;
|
||||
}
|
||||
|
||||
void Loader::PreDestroy()
|
||||
{
|
||||
if (!Loader::Postgame)
|
||||
if (!Postgame)
|
||||
{
|
||||
Loader::Postgame = true;
|
||||
Postgame = true;
|
||||
|
||||
auto components = Loader::Components;
|
||||
auto components = Components;
|
||||
|
||||
std::reverse(components.begin(), components.end());
|
||||
for (auto component : components)
|
||||
for (auto& component : components)
|
||||
{
|
||||
component->preDestroy();
|
||||
}
|
||||
@ -161,17 +161,17 @@ namespace Components
|
||||
|
||||
void Loader::PreDestroyNoPostGame()
|
||||
{
|
||||
if (!Loader::Postgame)
|
||||
if (!Postgame)
|
||||
{
|
||||
auto components = Loader::Components;
|
||||
auto components = Components;
|
||||
|
||||
std::reverse(components.begin(), components.end());
|
||||
for (auto component : components)
|
||||
for (auto& component : components)
|
||||
{
|
||||
component->preDestroy();
|
||||
}
|
||||
|
||||
Loader::Postgame = true;
|
||||
Postgame = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,7 +181,7 @@ namespace Components
|
||||
|
||||
Logger::Print("Performing unit tests for components:\n");
|
||||
|
||||
for (const auto component : Loader::Components)
|
||||
for (const auto& component : Components)
|
||||
{
|
||||
#if defined(FORCE_UNIT_TESTS)
|
||||
Logger::Debug("Testing '{}'...\n", component->getName());
|
||||
@ -210,12 +210,12 @@ namespace Components
|
||||
if (component)
|
||||
{
|
||||
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
|
||||
if (!Loader::IsPerformingUnitTests())
|
||||
if (!IsPerformingUnitTests())
|
||||
{
|
||||
Logger::Print("Component registered: {}\n", component->getName());
|
||||
}
|
||||
#endif
|
||||
Loader::Components.push_back(component);
|
||||
Components.push_back(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ namespace Components
|
||||
template <typename T>
|
||||
static T* GetInstance()
|
||||
{
|
||||
for (auto& component : Loader::Components)
|
||||
for (auto& component : Components)
|
||||
{
|
||||
if (typeid(*component) == typeid(T))
|
||||
{
|
||||
@ -61,87 +61,89 @@ namespace Components
|
||||
};
|
||||
}
|
||||
|
||||
#include "Modules/Scheduler.hpp"
|
||||
// Priority
|
||||
#include "Modules/Auth.hpp"
|
||||
#include "Modules/Bans.hpp"
|
||||
#include "Modules/Dvar.hpp"
|
||||
#include "Modules/Bots.hpp"
|
||||
#include "Modules/Lean.hpp"
|
||||
#include "Modules/Maps.hpp"
|
||||
#include "Modules/News.hpp"
|
||||
#include "Modules/Flags.hpp"
|
||||
#include "Modules/Menus.hpp"
|
||||
#include "Modules/Toast.hpp"
|
||||
#include "Modules/Zones.hpp"
|
||||
#include "Modules/D3D9Ex.hpp"
|
||||
#include "Modules/Weapon.hpp"
|
||||
#include "Modules/Window.hpp"
|
||||
#include "Modules/Command.hpp"
|
||||
#include "Modules/Console.hpp"
|
||||
#include "Modules/UIScript.hpp"
|
||||
#include "Modules/ModList.hpp"
|
||||
#include "Modules/Dvar.hpp"
|
||||
#include "Modules/Exception.hpp"
|
||||
#include "Modules/Flags.hpp"
|
||||
#include "Modules/Network.hpp"
|
||||
#include "Modules/NetworkDebug.hpp"
|
||||
#include "Modules/Theatre.hpp"
|
||||
#include "Modules/QuickPatch.hpp"
|
||||
#include "Modules/Security.hpp"
|
||||
#include "Modules/Node.hpp"
|
||||
#include "Modules/RCon.hpp"
|
||||
#include "Modules/Party.hpp" // Destroys the order, but requires network classes :D
|
||||
#include "Modules/Logger.hpp"
|
||||
#include "Modules/Friends.hpp"
|
||||
#include "Modules/IPCPipe.hpp"
|
||||
#include "Modules/MapDump.hpp"
|
||||
#include "Modules/Session.hpp"
|
||||
#include "Modules/ClanTags.hpp"
|
||||
#include "Modules/Download.hpp"
|
||||
#include "Modules/Playlist.hpp"
|
||||
#include "Modules/RawFiles.hpp"
|
||||
#include "Modules/Renderer.hpp"
|
||||
#include "Modules/UIFeeder.hpp"
|
||||
#include "Modules/Singleton.hpp"
|
||||
#include "Modules/UIScript.hpp"
|
||||
#include "Modules/ZoneBuilder.hpp"
|
||||
|
||||
#include "Modules/ArenaLength.hpp"
|
||||
#include "Modules/AssetHandler.hpp"
|
||||
#include "Modules/Bans.hpp"
|
||||
#include "Modules/Bots.hpp"
|
||||
#include "Modules/Branding.hpp"
|
||||
#include "Modules/Bullet.hpp"
|
||||
#include "Modules/CardTitles.hpp"
|
||||
#include "Modules/Ceg.hpp"
|
||||
#include "Modules/Changelog.hpp"
|
||||
#include "Modules/Chat.hpp"
|
||||
#include "Modules/ClanTags.hpp"
|
||||
#include "Modules/ClientCommand.hpp"
|
||||
#include "Modules/ConnectProtocol.hpp"
|
||||
#include "Modules/Console.hpp"
|
||||
#include "Modules/D3D9Ex.hpp"
|
||||
#include "Modules/Debug.hpp"
|
||||
#include "Modules/Dedicated.hpp"
|
||||
#include "Modules/Discovery.hpp"
|
||||
#include "Modules/Exception.hpp"
|
||||
#include "Modules/Download.hpp"
|
||||
#include "Modules/Elevators.hpp"
|
||||
#include "Modules/Events.hpp"
|
||||
#include "Modules/FastFiles.hpp"
|
||||
#include "Modules/Gametypes.hpp"
|
||||
#include "Modules/Materials.hpp"
|
||||
#include "Modules/Singleton.hpp"
|
||||
#include "Modules/Threading.hpp"
|
||||
#include "Modules/CardTitles.hpp"
|
||||
#include "Modules/FileSystem.hpp"
|
||||
#include "Modules/Friends.hpp"
|
||||
#include "Modules/Gamepad.hpp"
|
||||
#include "Modules/Gametypes.hpp"
|
||||
#include "Modules/IPCPipe.hpp"
|
||||
#include "Modules/Lean.hpp"
|
||||
#include "Modules/Localization.hpp"
|
||||
#include "Modules/MapDump.hpp"
|
||||
#include "Modules/MapRotation.hpp"
|
||||
#include "Modules/Maps.hpp"
|
||||
#include "Modules/Materials.hpp"
|
||||
#include "Modules/Menus.hpp"
|
||||
#include "Modules/ModList.hpp"
|
||||
#include "Modules/ModelSurfs.hpp"
|
||||
#include "Modules/NetworkDebug.hpp"
|
||||
#include "Modules/News.hpp"
|
||||
#include "Modules/Node.hpp"
|
||||
#include "Modules/Party.hpp"
|
||||
#include "Modules/PlayerMovement.hpp"
|
||||
#include "Modules/PlayerName.hpp"
|
||||
#include "Modules/Playlist.hpp"
|
||||
#include "Modules/QuickPatch.hpp"
|
||||
#include "Modules/RCon.hpp"
|
||||
#include "Modules/RawFiles.hpp"
|
||||
#include "Modules/RawMouse.hpp"
|
||||
#include "Modules/Renderer.hpp"
|
||||
#include "Modules/Scheduler.hpp"
|
||||
#include "Modules/Security.hpp"
|
||||
#include "Modules/ServerCommands.hpp"
|
||||
#include "Modules/ServerInfo.hpp"
|
||||
#include "Modules/ServerList.hpp"
|
||||
#include "Modules/Session.hpp"
|
||||
#include "Modules/SlowMotion.hpp"
|
||||
#include "Modules/ArenaLength.hpp"
|
||||
#include "Modules/StringTable.hpp"
|
||||
#include "Modules/ZoneBuilder.hpp"
|
||||
#include "Modules/AssetHandler.hpp"
|
||||
#include "Modules/Localization.hpp"
|
||||
#include "Modules/ServerCommands.hpp"
|
||||
#include "Modules/StructuredData.hpp"
|
||||
#include "Modules/ConnectProtocol.hpp"
|
||||
#include "Modules/SoundMutexFix.hpp"
|
||||
#include "Modules/StartupMessages.hpp"
|
||||
#include "Modules/Stats.hpp"
|
||||
#include "Modules/SoundMutexFix.hpp"
|
||||
#include "Modules/Chat.hpp"
|
||||
#include "Modules/StringTable.hpp"
|
||||
#include "Modules/StructuredData.hpp"
|
||||
#include "Modules/TextRenderer.hpp"
|
||||
#include "Modules/PlayerMovement.hpp"
|
||||
#include "Modules/Elevators.hpp"
|
||||
#include "Modules/ClientCommand.hpp"
|
||||
#include "Modules/VisionFile.hpp"
|
||||
#include "Modules/Gamepad.hpp"
|
||||
#include "Modules/Branding.hpp"
|
||||
#include "Modules/Debug.hpp"
|
||||
#include "Modules/RawMouse.hpp"
|
||||
#include "Modules/Bullet.hpp"
|
||||
#include "Modules/MapRotation.hpp"
|
||||
#include "Modules/Ceg.hpp"
|
||||
#include "Modules/Theatre.hpp"
|
||||
#include "Modules/Threading.hpp"
|
||||
#include "Modules/Toast.hpp"
|
||||
#include "Modules/UIFeeder.hpp"
|
||||
#include "Modules/UserInfo.hpp"
|
||||
#include "Modules/Events.hpp"
|
||||
#include "Modules/VisionFile.hpp"
|
||||
#include "Modules/Voice.hpp"
|
||||
#include "Modules/Vote.hpp"
|
||||
#include "Modules/Weapon.hpp"
|
||||
#include "Modules/Window.hpp"
|
||||
#include "Modules/Zones.hpp"
|
||||
|
||||
#include "Modules/GSC/GSC.hpp"
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Components
|
||||
{
|
||||
std::string CardTitles::CustomTitles[18];
|
||||
char CardTitles::CustomTitles[Game::MAX_CLIENTS][18];
|
||||
Dvar::Var CardTitles::CustomTitle;
|
||||
|
||||
CClient* CardTitles::GetClientByIndex(std::uint32_t index)
|
||||
@ -10,35 +10,34 @@ namespace Components
|
||||
return &reinterpret_cast<CClient*>(0x8E77B0)[index];
|
||||
}
|
||||
|
||||
std::int32_t CardTitles::GetPlayerCardClientInfo(std::int32_t lookupResult, Game::PlayerCardData* data)
|
||||
int CardTitles::GetPlayerCardClientInfo(int lookupResult, Game::PlayerCardData* data)
|
||||
{
|
||||
std::int32_t returnResult = lookupResult;
|
||||
auto result = lookupResult;
|
||||
|
||||
std::string username = Dvar::Var("name").get<std::string>();
|
||||
|
||||
if (data->name == username)
|
||||
const auto* username = Dvar::Var("name").get<const char*>();
|
||||
if (std::strcmp(data->name, username) == 0)
|
||||
{
|
||||
returnResult += 0xFE000000;
|
||||
result += 0xFE000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::size_t clientNum = 0; clientNum < Game::MAX_CLIENTS; ++clientNum)
|
||||
for (std::size_t i = 0; i < Game::MAX_CLIENTS; ++i)
|
||||
{
|
||||
CClient* c = GetClientByIndex(clientNum);
|
||||
CClient* c = GetClientByIndex(i);
|
||||
if (c != nullptr)
|
||||
{
|
||||
if (!std::strcmp(data->name, c->Name))
|
||||
{
|
||||
// Since a 4 byte integer is overkill for a row num: We can use it to store the customprefix + clientNum and use a 2 byte integer for the row number
|
||||
returnResult += 0xFF000000;
|
||||
returnResult += clientNum * 0x10000;
|
||||
result += 0xFF000000;
|
||||
result += i * 0x10000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnResult;
|
||||
return result;
|
||||
}
|
||||
|
||||
void __declspec(naked) CardTitles::GetPlayerCardClientInfoStub()
|
||||
@ -71,7 +70,7 @@ namespace Components
|
||||
std::uint8_t prefix = (request->tableRow >> (8 * 3)) & 0xFF;
|
||||
std::uint8_t data = (request->tableRow >> (8 * 2)) & 0xFF;
|
||||
|
||||
if (data >= ARRAYSIZE(CardTitles::CustomTitles)) return nullptr;
|
||||
if (data >= Game::MAX_CLIENTS) return nullptr;
|
||||
|
||||
if (request->tablename == "mp/cardTitleTable.csv"s)
|
||||
{
|
||||
@ -82,10 +81,10 @@ namespace Components
|
||||
{
|
||||
if (prefix == 0xFE)
|
||||
{
|
||||
if (!CardTitles::CustomTitle.get<std::string>().empty())
|
||||
if (!CustomTitle.get<std::string>().empty())
|
||||
{
|
||||
// 0xFF in front of the title to skip localization. Or else it will wait for a couple of seconds for the asset of type localize
|
||||
const char* title = Utils::String::VA("\x15%s", CardTitles::CustomTitle.get<const char*>());
|
||||
const auto* title = Utils::String::VA("\x15%s", CustomTitle.get<const char*>());
|
||||
|
||||
// prepare return value
|
||||
operand->internals.stringVal.string = title;
|
||||
@ -96,9 +95,9 @@ namespace Components
|
||||
}
|
||||
else if (prefix == 0xFF)
|
||||
{
|
||||
if (!CardTitles::CustomTitles[data].empty())
|
||||
if (CustomTitles[data][0] != '\0')
|
||||
{
|
||||
const char* title = Utils::String::VA("\x15%s", CardTitles::CustomTitles[data].data());
|
||||
const auto* title = Utils::String::VA("\x15%s", CustomTitles[data]);
|
||||
|
||||
// prepare return value
|
||||
operand->internals.stringVal.string = title;
|
||||
@ -156,11 +155,11 @@ namespace Components
|
||||
{
|
||||
std::string list;
|
||||
|
||||
for (std::size_t i = 0; i < Game::MAX_CLIENTS; i++)
|
||||
for (std::size_t i = 0; i < Game::MAX_CLIENTS; ++i)
|
||||
{
|
||||
char playerTitle[18];
|
||||
char playerTitle[18]{};
|
||||
|
||||
if (Game::svs_clients[i].header.state >= Game::CS_CONNECTED)
|
||||
if (Game::svs_clients[i].userinfo[0] != '\0')
|
||||
{
|
||||
strncpy_s(playerTitle, Game::Info_ValueForKey(Game::svs_clients[i].userinfo, "customTitle"), _TRUNCATE);
|
||||
}
|
||||
@ -180,10 +179,17 @@ namespace Components
|
||||
{
|
||||
for (std::size_t i = 0; i < Game::MAX_CLIENTS; ++i)
|
||||
{
|
||||
const char* playerTitle = Game::Info_ValueForKey(msg, std::to_string(i).c_str());
|
||||
const auto index = std::to_string(i);
|
||||
const auto* playerTitle = Game::Info_ValueForKey(msg, index.data());
|
||||
|
||||
if (playerTitle) CardTitles::CustomTitles[i] = playerTitle;
|
||||
else CardTitles::CustomTitles[i].clear();
|
||||
if (playerTitle[0] == '\0')
|
||||
{
|
||||
CustomTitles[i][0] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::I_strncpyz(CustomTitles[i], playerTitle, sizeof(CustomTitles[0]) / sizeof(char));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,16 +197,18 @@ namespace Components
|
||||
{
|
||||
Scheduler::Once([]
|
||||
{
|
||||
CardTitles::CustomTitle = Dvar::Register<const char*>("customTitle", "", Game::DVAR_USERINFO | Game::DVAR_ARCHIVE, "Custom card title");
|
||||
CustomTitle = Dvar::Register<const char*>("customTitle", "", Game::DVAR_USERINFO | Game::DVAR_ARCHIVE, "Custom card title");
|
||||
}, Scheduler::Pipeline::MAIN);
|
||||
|
||||
std::memset(&CustomTitles, 0, sizeof(char[Game::MAX_CLIENTS][18]));
|
||||
|
||||
ServerCommands::OnCommand(21, [](Command::Params* params)
|
||||
{
|
||||
if (params->get(1) == "customTitles"s && !Dedicated::IsEnabled())
|
||||
if (std::strcmp(params->get(1), "customTitles") == 0)
|
||||
{
|
||||
if (params->size() == 3)
|
||||
{
|
||||
CardTitles::ParseCustomTitles(params->get(2));
|
||||
ParseCustomTitles(params->get(2));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -209,10 +217,10 @@ namespace Components
|
||||
|
||||
});
|
||||
|
||||
Utils::Hook(0x62EB26, CardTitles::GetPlayerCardClientInfoStub).install()->quick();
|
||||
Utils::Hook(0x62EB26, GetPlayerCardClientInfoStub).install()->quick();
|
||||
|
||||
// Table lookup stuff
|
||||
Utils::Hook(0x62DCC1, CardTitles::TableLookupByRowHookStub).install()->quick();
|
||||
Utils::Hook(0x62DCC1, TableLookupByRowHookStub).install()->quick();
|
||||
Utils::Hook::Nop(0x62DCC6, 1);
|
||||
}
|
||||
}
|
||||
|
@ -14,27 +14,27 @@ namespace Components
|
||||
|
||||
struct CClient
|
||||
{
|
||||
std::uint32_t IsValid; // 0x0000
|
||||
std::uint32_t IsValid2; // 0x0004
|
||||
std::uint32_t ClientNumber; // 0x0008
|
||||
char Name[16]; // 0x000C
|
||||
std::uint32_t Team; // 0x001C
|
||||
std::uint32_t Team2; // 0x0020
|
||||
std::uint32_t Rank; // 0x0024 (rank - 1)
|
||||
std::uint32_t Prestige; // 0x0028
|
||||
std::uint32_t Perks; // 0x002C
|
||||
std::uint32_t Kills; // 0x0030
|
||||
std::uint32_t Score; // 0x0034
|
||||
std::uint32_t IsValid; // 0x0000
|
||||
std::uint32_t IsValid2; // 0x0004
|
||||
std::uint32_t ClientNumber; // 0x0008
|
||||
char Name[16]; // 0x000C
|
||||
std::uint32_t Team; // 0x001C
|
||||
std::uint32_t Team2; // 0x0020
|
||||
std::uint32_t Rank; // 0x0024 (rank - 1)
|
||||
std::uint32_t Prestige; // 0x0028
|
||||
std::uint32_t Perks; // 0x002C
|
||||
std::uint32_t Kills; // 0x0030
|
||||
std::uint32_t Score; // 0x0034
|
||||
std::uint8_t _0x0038[968];
|
||||
std::uint32_t ViewAngles; // 0x0400
|
||||
std::uint32_t ViewAngles; // 0x0400
|
||||
std::uint8_t _0x040C[136];
|
||||
std::uint32_t IsShooting; // 0x0494
|
||||
std::uint32_t IsShooting; // 0x0494
|
||||
std::uint8_t _0x0498[4];
|
||||
std::uint32_t IsZoomed; // 0x049C
|
||||
std::uint32_t IsZoomed; // 0x049C
|
||||
std::uint8_t _0x04A0[68];
|
||||
std::uint32_t weaponID; // 0x04E4
|
||||
std::uint32_t weaponID; // 0x04E4
|
||||
std::uint8_t _0x04E8[24];
|
||||
std::uint32_t weaponID2; // 0x0500
|
||||
std::uint32_t weaponID2; // 0x0500
|
||||
std::uint8_t _0x0504[40];
|
||||
std::uint8_t _padding[8];
|
||||
};
|
||||
@ -44,19 +44,20 @@ namespace Components
|
||||
public:
|
||||
AssertOffset(Game::PlayerCardData, Game::PlayerCardData::name, 0x1C);
|
||||
|
||||
static Dvar::Var CustomTitle;
|
||||
static std::string CustomTitles[18];
|
||||
|
||||
static void SendCustomTitlesToClients();
|
||||
static void ParseCustomTitles(const char* msg);
|
||||
|
||||
CardTitles();
|
||||
|
||||
private:
|
||||
static Dvar::Var CustomTitle;
|
||||
static char CustomTitles[Game::MAX_CLIENTS][18];
|
||||
|
||||
static CClient* GetClientByIndex(std::uint32_t index);
|
||||
static std::int32_t GetPlayerCardClientInfo(std::int32_t lookupResult, Game::PlayerCardData* data);
|
||||
static int GetPlayerCardClientInfo(int lookupResult, Game::PlayerCardData* data);
|
||||
static void GetPlayerCardClientInfoStub();
|
||||
static const char* TableLookupByRowHook(Game::Operand* operand, tablelookuprequest_s* request);
|
||||
static void TableLookupByRowHookStub();
|
||||
|
||||
static void ParseCustomTitles(const char* msg);
|
||||
};
|
||||
}
|
||||
|
@ -186,24 +186,24 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
template<> Dvar::Var Dvar::Register(const char* dvarName, bool value, Flag flag, const char* description)
|
||||
template<> Dvar::Var Dvar::Register(const char* dvarName, bool value, std::uint16_t flag, const char* description)
|
||||
{
|
||||
return Game::Dvar_RegisterBool(dvarName, value, flag.val, description);
|
||||
return Game::Dvar_RegisterBool(dvarName, value, flag, description);
|
||||
}
|
||||
|
||||
template<> Dvar::Var Dvar::Register(const char* dvarName, const char* value, Flag flag, const char* description)
|
||||
template<> Dvar::Var Dvar::Register(const char* dvarName, const char* value, std::uint16_t flag, const char* description)
|
||||
{
|
||||
return Game::Dvar_RegisterString(dvarName, value, flag.val, description);
|
||||
return Game::Dvar_RegisterString(dvarName, value, flag, description);
|
||||
}
|
||||
|
||||
template<> Dvar::Var Dvar::Register(const char* dvarName, int value, int min, int max, Flag flag, const char* description)
|
||||
template<> Dvar::Var Dvar::Register(const char* dvarName, int value, int min, int max, std::uint16_t flag, const char* description)
|
||||
{
|
||||
return Game::Dvar_RegisterInt(dvarName, value, min, max, flag.val, description);
|
||||
return Game::Dvar_RegisterInt(dvarName, value, min, max, flag, description);
|
||||
}
|
||||
|
||||
template<> Dvar::Var Dvar::Register(const char* dvarName, float value, float min, float max, Flag flag, const char* description)
|
||||
template<> Dvar::Var Dvar::Register(const char* dvarName, float value, float min, float max, std::uint16_t flag, const char* description)
|
||||
{
|
||||
return Game::Dvar_RegisterFloat(dvarName, value, min, max, flag.val, description);
|
||||
return Game::Dvar_RegisterFloat(dvarName, value, min, max, flag, description);
|
||||
}
|
||||
|
||||
void Dvar::ResetDvarsValue()
|
||||
|
@ -5,15 +5,6 @@ namespace Components
|
||||
class Dvar : public Component
|
||||
{
|
||||
public:
|
||||
class Flag
|
||||
{
|
||||
public:
|
||||
Flag(Game::DvarFlags flag) : val(flag) {}
|
||||
Flag(std::uint16_t flag) : Flag(static_cast<Game::DvarFlags>(flag)) {}
|
||||
|
||||
Game::DvarFlags val;
|
||||
};
|
||||
|
||||
class Var
|
||||
{
|
||||
public:
|
||||
@ -44,8 +35,8 @@ namespace Components
|
||||
~Dvar();
|
||||
|
||||
// Only strings and bools use this type of declaration
|
||||
template<typename T> static Var Register(const char* dvarName, T value, Flag flag, const char* description);
|
||||
template<typename T> static Var Register(const char* dvarName, T value, T min, T max, Flag flag, const char* description);
|
||||
template<typename T> static Var Register(const char* dvarName, T value, std::uint16_t flag, const char* description);
|
||||
template<typename T> static Var Register(const char* dvarName, T value, T min, T max, std::uint16_t flag, const char* description);
|
||||
|
||||
static void ResetDvarsValue();
|
||||
|
||||
|
@ -7,20 +7,10 @@ namespace Components
|
||||
Utils::Hook Exception::SetFilterHook;
|
||||
int Exception::MiniDumpType;
|
||||
|
||||
__declspec(noreturn) void Exception::ErrorLongJmp(jmp_buf _Buf, int _Value)
|
||||
{
|
||||
if (!*reinterpret_cast<DWORD*>(0x1AD7EB4))
|
||||
{
|
||||
TerminateProcess(GetCurrentProcess(), 1337);
|
||||
}
|
||||
|
||||
longjmp(_Buf, _Value);
|
||||
}
|
||||
|
||||
__declspec(noreturn) void Exception::LongJmp(jmp_buf _Buf, int _Value)
|
||||
__declspec(noreturn) void Exception::LongJmp_Internal_Stub(jmp_buf env, int status)
|
||||
{
|
||||
AssetHandler::ResetBypassState();
|
||||
longjmp(_Buf, _Value);
|
||||
Game::longjmp_internal(env, status);
|
||||
}
|
||||
|
||||
void Exception::SuspendProcess()
|
||||
@ -76,7 +66,7 @@ namespace Components
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = GlobalLock(hMem);
|
||||
auto* lock = GlobalLock(hMem);
|
||||
if (lock != nullptr)
|
||||
{
|
||||
std::memcpy(lock, error.data(), error.size() + 1);
|
||||
@ -107,17 +97,15 @@ namespace Components
|
||||
errorStr = Utils::String::VA("Fatal error (0x%08X) at 0x%08X.\nCopy exception address to clipboard?", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
|
||||
}
|
||||
|
||||
//Exception::SuspendProcess();
|
||||
|
||||
// Message should be copied to the keyboard if no button is pressed
|
||||
if (MessageBoxA(nullptr, errorStr.data(), nullptr, MB_YESNO | MB_ICONERROR) == IDYES)
|
||||
{
|
||||
Exception::CopyMessageToClipboard(Utils::String::VA("0x%08X", ExceptionInfo->ExceptionRecord->ExceptionAddress));
|
||||
CopyMessageToClipboard(Utils::String::VA("0x%08X", ExceptionInfo->ExceptionRecord->ExceptionAddress));
|
||||
}
|
||||
|
||||
if (Flags::HasFlag("bigminidumps"))
|
||||
{
|
||||
Exception::SetMiniDumpType(true, false);
|
||||
SetMiniDumpType(true, false);
|
||||
}
|
||||
|
||||
// Current executable name
|
||||
@ -134,23 +122,22 @@ namespace Components
|
||||
_localtime64_s(<ime, &time);
|
||||
strftime(filenameFriendlyTime, sizeof(filenameFriendlyTime) - 1, "%Y%m%d%H%M%S", <ime);
|
||||
|
||||
// Combine with queuedMinidumpsFolder
|
||||
char filename[MAX_PATH] = { 0 };
|
||||
Utils::IO::CreateDir("minidumps");
|
||||
// Combine with queued MinidumpsFolder
|
||||
char filename[MAX_PATH]{};
|
||||
CreateDirectoryA("minidumps", nullptr);
|
||||
PathCombineA(filename, "minidumps\\", Utils::String::VA("%s-" VERSION "-%s.dmp", exeFileName, filenameFriendlyTime));
|
||||
|
||||
DWORD fileShare = FILE_SHARE_READ | FILE_SHARE_WRITE;
|
||||
constexpr auto fileShare = FILE_SHARE_READ | FILE_SHARE_WRITE;
|
||||
HANDLE hFile = CreateFileA(filename, GENERIC_WRITE | GENERIC_READ, fileShare, nullptr, (fileShare & FILE_SHARE_WRITE) > 0 ? OPEN_ALWAYS : OPEN_EXISTING, NULL, nullptr);
|
||||
MINIDUMP_EXCEPTION_INFORMATION ex = { GetCurrentThreadId(), ExceptionInfo, FALSE };
|
||||
if (!MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, static_cast<MINIDUMP_TYPE>(Exception::MiniDumpType), &ex, nullptr, nullptr))
|
||||
if (!MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, static_cast<MINIDUMP_TYPE>(MiniDumpType), &ex, nullptr, nullptr))
|
||||
{
|
||||
MessageBoxA(nullptr, Utils::String::VA("There was an error creating the minidump (%s)! Hit OK to close the program.", Utils::GetLastWindowsError().data()), "Minidump Error", MB_OK | MB_ICONERROR);
|
||||
MessageBoxA(nullptr, Utils::String::Format("There was an error creating the minidump ({})! Hit OK to close the program.", Utils::GetLastWindowsError()), "ERROR", MB_OK | MB_ICONERROR);
|
||||
OutputDebugStringA("Failed to create new minidump!");
|
||||
Utils::OutputDebugLastError();
|
||||
TerminateProcess(GetCurrentProcess(), ExceptionInfo->ExceptionRecord->ExceptionCode);
|
||||
}
|
||||
|
||||
//if (ExceptionInfo->ExceptionRecord->ExceptionFlags == EXCEPTION_NONCONTINUABLE)
|
||||
{
|
||||
TerminateProcess(GetCurrentProcess(), ExceptionInfo->ExceptionRecord->ExceptionCode);
|
||||
}
|
||||
@ -158,54 +145,39 @@ namespace Components
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI Exception::SetUnhandledExceptionFilterStub(LPTOP_LEVEL_EXCEPTION_FILTER)
|
||||
{
|
||||
Exception::SetFilterHook.uninstall();
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER retval = SetUnhandledExceptionFilter(&Exception::ExceptionFilter);
|
||||
Exception::SetFilterHook.install();
|
||||
return retval;
|
||||
}
|
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER Exception::Hook()
|
||||
{
|
||||
return SetUnhandledExceptionFilter(&Exception::ExceptionFilter);
|
||||
}
|
||||
|
||||
void Exception::SetMiniDumpType(bool codeseg, bool dataseg)
|
||||
{
|
||||
Exception::MiniDumpType = MiniDumpIgnoreInaccessibleMemory;
|
||||
Exception::MiniDumpType |= MiniDumpWithHandleData;
|
||||
Exception::MiniDumpType |= MiniDumpScanMemory;
|
||||
Exception::MiniDumpType |= MiniDumpWithProcessThreadData;
|
||||
Exception::MiniDumpType |= MiniDumpWithFullMemoryInfo;
|
||||
Exception::MiniDumpType |= MiniDumpWithThreadInfo;
|
||||
//Exception::MiniDumpType |= MiniDumpWithModuleHeaders;
|
||||
MiniDumpType = MiniDumpIgnoreInaccessibleMemory;
|
||||
MiniDumpType |= MiniDumpWithHandleData;
|
||||
MiniDumpType |= MiniDumpScanMemory;
|
||||
MiniDumpType |= MiniDumpWithProcessThreadData;
|
||||
MiniDumpType |= MiniDumpWithFullMemoryInfo;
|
||||
MiniDumpType |= MiniDumpWithThreadInfo;
|
||||
|
||||
if (codeseg)
|
||||
{
|
||||
Exception::MiniDumpType |= MiniDumpWithCodeSegs;
|
||||
MiniDumpType |= MiniDumpWithCodeSegs;
|
||||
}
|
||||
|
||||
if (dataseg)
|
||||
{
|
||||
Exception::MiniDumpType |= MiniDumpWithDataSegs;
|
||||
MiniDumpType |= MiniDumpWithDataSegs;
|
||||
}
|
||||
}
|
||||
|
||||
Exception::Exception()
|
||||
{
|
||||
Exception::SetMiniDumpType(Flags::HasFlag("bigminidumps"), Flags::HasFlag("reallybigminidumps"));
|
||||
|
||||
#if !defined(DEBUG) || defined(FORCE_EXCEPTION_HANDLER)
|
||||
Exception::SetFilterHook.initialize(SetUnhandledExceptionFilter, Exception::SetUnhandledExceptionFilterStub, HOOK_JUMP);
|
||||
Exception::SetFilterHook.install();
|
||||
SetMiniDumpType(Flags::HasFlag("bigminidumps"), Flags::HasFlag("reallybigminidumps"));
|
||||
|
||||
SetUnhandledExceptionFilter(&Exception::ExceptionFilter);
|
||||
#endif
|
||||
|
||||
//Utils::Hook(0x4B241F, Exception::ErrorLongJmp, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x6B8898, Exception::LongJmp, HOOK_JUMP).install()->quick();
|
||||
Utils::Hook(0x4B241F, LongJmp_Internal_Stub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x61DB44, LongJmp_Internal_Stub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x61F17D, LongJmp_Internal_Stub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x61F248, LongJmp_Internal_Stub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x61F5E7, LongJmp_Internal_Stub, HOOK_CALL).install()->quick();
|
||||
|
||||
#ifdef _DEBUG
|
||||
#ifdef MAP_TEST
|
||||
Command::Add("mapTest", [](Command::Params* params)
|
||||
{
|
||||
Game::UI_UpdateArenas();
|
||||
@ -227,6 +199,6 @@ namespace Components
|
||||
|
||||
Exception::~Exception()
|
||||
{
|
||||
Exception::SetFilterHook.uninstall();
|
||||
SetFilterHook.uninstall();
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,7 @@ namespace Components
|
||||
private:
|
||||
static void SuspendProcess();
|
||||
static LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS ExceptionInfo);
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilterStub(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter);
|
||||
static __declspec(noreturn) void ErrorLongJmp(jmp_buf _Buf, int _Value);
|
||||
static __declspec(noreturn) void LongJmp(jmp_buf _Buf, int _Value);
|
||||
static __declspec(noreturn) void LongJmp_Internal_Stub(jmp_buf env, int status);
|
||||
|
||||
static void CopyMessageToClipboard(const std::string& error);
|
||||
|
||||
|
@ -319,7 +319,7 @@ namespace Components
|
||||
auto clientCount = 0;
|
||||
auto maxClientCount = *Game::svs_clientCount;
|
||||
const auto securityLevel = Dvar::Var("sv_securityLevel").get<int>();
|
||||
const auto password = Dvar::Var("g_password").get<std::string>();
|
||||
const auto* password = (*Game::g_password)->current.string;
|
||||
|
||||
if (maxClientCount)
|
||||
{
|
||||
@ -352,7 +352,7 @@ namespace Components
|
||||
info.set("shortversion", SHORTVERSION);
|
||||
info.set("checksum", std::to_string(Game::Sys_Milliseconds()));
|
||||
info.set("mapname", Dvar::Var("mapname").get<std::string>());
|
||||
info.set("isPrivate", password.empty() ? "0" : "1");
|
||||
info.set("isPrivate", *password ? "1" : "0");
|
||||
info.set("hc", (Dvar::Var("g_hardcore").get<bool>() ? "1" : "0"));
|
||||
info.set("securityLevel", std::to_string(securityLevel));
|
||||
info.set("sv_running", (Dedicated::IsRunning() ? "1" : "0"));
|
||||
|
@ -9,26 +9,26 @@ namespace Components
|
||||
void Playlist::LoadPlaylist()
|
||||
{
|
||||
// Check if playlist already loaded
|
||||
if (Utils::Hook::Get<bool>(0x1AD3680)) return;
|
||||
if (*Game::s_havePlaylists) return;
|
||||
|
||||
// Don't load playlists when dedi and no party
|
||||
if (Dedicated::IsEnabled() && !Dvar::Var("party_enable").get<bool>())
|
||||
{
|
||||
Utils::Hook::Set<bool>(0x1AD3680, true); // Set received to true
|
||||
*Game::s_havePlaylists = true;
|
||||
Dvar::Var("xblive_privateserver").set(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Dvar::Var("xblive_privateserver").set(false);
|
||||
|
||||
auto playlistFilename = Dvar::Var("playlistFilename").get<std::string>();
|
||||
const auto playlistFilename = Dvar::Var("playlistFilename").get<std::string>();
|
||||
FileSystem::File playlist(playlistFilename);
|
||||
|
||||
if (playlist.exists())
|
||||
{
|
||||
Logger::Print("Parsing playlist '{}'...\n", playlist.getName());
|
||||
Game::Playlist_ParsePlaylists(playlist.getBuffer().data());
|
||||
Utils::Hook::Set<bool>(0x1AD3680, true); // Playlist loaded
|
||||
*Game::s_havePlaylists = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -36,18 +36,18 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
DWORD Playlist::StorePlaylistStub(const char** buffer)
|
||||
char* Playlist::Com_ParseOnLine_Hk(const char** data_p)
|
||||
{
|
||||
Playlist::MapRelocation.clear();
|
||||
Playlist::CurrentPlaylistBuffer = Utils::Compression::ZLib::Compress(*buffer);
|
||||
return Utils::Hook::Call<DWORD(const char**)>(0x4C0350)(buffer);
|
||||
MapRelocation.clear();
|
||||
CurrentPlaylistBuffer = Utils::Compression::ZLib::Compress(*data_p);
|
||||
return Game::Com_ParseOnLine(data_p);
|
||||
}
|
||||
|
||||
void Playlist::PlaylistRequest(const Network::Address& address, [[maybe_unused]] const std::string& data)
|
||||
{
|
||||
const auto password = Dvar::Var("g_password").get<std::string>();
|
||||
const auto* password = (*Game::g_password)->current.string;
|
||||
|
||||
if (password.length())
|
||||
if (*password)
|
||||
{
|
||||
if (password != data)
|
||||
{
|
||||
@ -58,7 +58,7 @@ namespace Components
|
||||
|
||||
Logger::Print("Received playlist request, sending currently stored buffer.\n");
|
||||
|
||||
std::string compressedList = Playlist::CurrentPlaylistBuffer;
|
||||
std::string compressedList = CurrentPlaylistBuffer;
|
||||
|
||||
Proto::Party::Playlist list;
|
||||
list.set_hash(Utils::Cryptography::JenkinsOneAtATime::Compute(compressedList));
|
||||
@ -67,51 +67,48 @@ namespace Components
|
||||
Network::SendCommand(address, "playlistResponse", list.SerializeAsString());
|
||||
}
|
||||
|
||||
void Playlist::PlaylistReponse(const Network::Address& address, [[maybe_unused]] const std::string& data)
|
||||
void Playlist::PlaylistResponse(const Network::Address& address, [[maybe_unused]] const std::string& data)
|
||||
{
|
||||
if (Party::PlaylistAwaiting())
|
||||
if (!Party::PlaylistAwaiting())
|
||||
{
|
||||
if (address == Party::Target())
|
||||
{
|
||||
Proto::Party::Playlist list;
|
||||
Logger::Print("Received stray playlist response, ignoring it.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (address != Party::Target())
|
||||
{
|
||||
Logger::Print("Received playlist from someone else than our target host, ignoring it.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Proto::Party::Playlist list;
|
||||
|
||||
if (!list.ParseFromString(data))
|
||||
{
|
||||
Party::PlaylistError(Utils::String::VA("Received playlist response from %s, but it is invalid.", address.getCString()));
|
||||
Playlist::ReceivedPlaylistBuffer.clear();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Generate buffer and hash
|
||||
const auto& compressedData = list.buffer();
|
||||
const auto hash = Utils::Cryptography::JenkinsOneAtATime::Compute(compressedData);
|
||||
|
||||
//Validate hashes
|
||||
if (hash != list.hash())
|
||||
{
|
||||
Party::PlaylistError(Utils::String::VA("Received playlist response from %s, but the checksum did not match (%X != %X).", address.getCString(), list.hash(), hash));
|
||||
Playlist::ReceivedPlaylistBuffer.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Decompress buffer
|
||||
Playlist::ReceivedPlaylistBuffer = Utils::Compression::ZLib::Decompress(compressedData);
|
||||
|
||||
// Load and continue connection
|
||||
Logger::Print("Received playlist, loading and continuing connection...\n");
|
||||
Game::Playlist_ParsePlaylists(Playlist::ReceivedPlaylistBuffer.data());
|
||||
Party::PlaylistContinue();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::Print("Received playlist from someone else than our target host, ignoring it.\n");
|
||||
}
|
||||
if (!list.ParseFromString(data))
|
||||
{
|
||||
Party::PlaylistError(std::format("Received playlist response from {}, but it is invalid.", address.getString()));
|
||||
ReceivedPlaylistBuffer.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::Print("Received stray playlist response, ignoring it.\n");
|
||||
// Generate buffer and hash
|
||||
const auto& compressedData = list.buffer();
|
||||
const auto hash = Utils::Cryptography::JenkinsOneAtATime::Compute(compressedData);
|
||||
|
||||
// Validate hashes
|
||||
if (hash != list.hash())
|
||||
{
|
||||
Party::PlaylistError(std::format("Received playlist response from {}, but the checksum did not match ({} != {}).", address.getString(), list.hash(), hash));
|
||||
ReceivedPlaylistBuffer.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Decompress buffer
|
||||
ReceivedPlaylistBuffer = Utils::Compression::ZLib::Decompress(compressedData);
|
||||
|
||||
// Load and continue connection
|
||||
Logger::Print("Received playlist, loading and continuing connection...\n");
|
||||
Game::Playlist_ParsePlaylists(ReceivedPlaylistBuffer.data());
|
||||
Party::PlaylistContinue();
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,27 +117,27 @@ namespace Components
|
||||
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);
|
||||
Playlist::MapRelocation[dest] = src;
|
||||
MapRelocation[dest] = src;
|
||||
}
|
||||
|
||||
void Playlist::SetMapName(const char* cvar, const char* value)
|
||||
void Playlist::SetMapName(const char* dvarName, const char* value)
|
||||
{
|
||||
auto i = Playlist::MapRelocation.find(value);
|
||||
if (i != Playlist::MapRelocation.end())
|
||||
auto i = MapRelocation.find(value);
|
||||
if (i != MapRelocation.end())
|
||||
{
|
||||
value = i->second.data();
|
||||
}
|
||||
|
||||
Game::Dvar_SetStringByName(cvar, value);
|
||||
Game::Dvar_SetStringByName(dvarName, value);
|
||||
}
|
||||
|
||||
int Playlist::GetMapIndex(const char* mapname)
|
||||
{
|
||||
auto i = Playlist::MapRelocation.find(mapname);
|
||||
if (i != Playlist::MapRelocation.end())
|
||||
auto i = MapRelocation.find(mapname);
|
||||
if (i != MapRelocation.end())
|
||||
{
|
||||
mapname = i->second.data();
|
||||
}
|
||||
@ -153,7 +150,7 @@ namespace Components
|
||||
// Default playlists
|
||||
Utils::Hook::Set<const char*>(0x60B06E, "playlists_default.info");
|
||||
|
||||
// disable playlist download function
|
||||
// Disable playlist download function
|
||||
Utils::Hook::Set<BYTE>(0x4D4790, 0xC3);
|
||||
|
||||
// Load playlist, but don't delete it
|
||||
@ -161,34 +158,34 @@ namespace Components
|
||||
Utils::Hook::Nop(0x4D6E67, 5);
|
||||
Utils::Hook::Nop(0x4D6E71, 2);
|
||||
|
||||
// playlist dvar 'validity check'
|
||||
// Disable Playlist_ValidatePlaylistNum
|
||||
Utils::Hook::Set<BYTE>(0x4B1170, 0xC3);
|
||||
|
||||
// disable playlist checking
|
||||
Utils::Hook::Set<BYTE>(0x5B69E9, 0xEB); // too new
|
||||
Utils::Hook::Set<BYTE>(0x5B696E, 0xEB); // too old
|
||||
// Disable playlist checking
|
||||
Utils::Hook::Set<BYTE>(0x5B69E9, 0xEB); // Too new
|
||||
Utils::Hook::Set<BYTE>(0x5B696E, 0xEB); // Too old
|
||||
|
||||
//Got playlists is true
|
||||
// Got playlists is true
|
||||
//Utils::Hook::Set<bool>(0x1AD3680, true);
|
||||
|
||||
Utils::Hook(0x497DB5, Playlist::GetMapIndex, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x42A19D, Playlist::MapNameCopy, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x4A6FEE, Playlist::SetMapName, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x497DB5, GetMapIndex, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x42A19D, MapNameCopy, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x4A6FEE, SetMapName, HOOK_CALL).install()->quick();
|
||||
|
||||
// Store playlist buffer on load
|
||||
Utils::Hook(0x42961C, Playlist::StorePlaylistStub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x42961C, Com_ParseOnLine_Hk, HOOK_CALL).install()->quick(); // Playlist_ParsePlaylists
|
||||
|
||||
//if (Dedicated::IsDedicated())
|
||||
{
|
||||
// Custom playlist loading
|
||||
Utils::Hook(0x420B5A, Playlist::LoadPlaylist, HOOK_JUMP).install()->quick();
|
||||
Utils::Hook(0x420B5A, LoadPlaylist, HOOK_JUMP).install()->quick();
|
||||
|
||||
// disable playlist.ff loading function
|
||||
Utils::Hook::Set<BYTE>(0x4D6E60, 0xC3);
|
||||
// disable playlist.ff loading function (Win_LoadPlaylistFastfile)
|
||||
Utils::Hook::Set<std::uint8_t>(0x4D6E60, 0xC3);
|
||||
}
|
||||
|
||||
Network::OnClientPacket("getPlaylist", PlaylistRequest);
|
||||
Network::OnClientPacket("playlistResponse", PlaylistReponse);
|
||||
Network::OnClientPacket("playlistResponse", PlaylistResponse);
|
||||
Network::OnClientPacket("playlistInvalidPassword", PlaylistInvalidPassword);
|
||||
}
|
||||
}
|
||||
|
@ -17,14 +17,14 @@ namespace Components
|
||||
static std::string CurrentPlaylistBuffer;
|
||||
static std::unordered_map<const void*, std::string> MapRelocation;
|
||||
|
||||
static DWORD StorePlaylistStub(const char** buffer);
|
||||
static char* Com_ParseOnLine_Hk(const char** data_p);
|
||||
|
||||
static void PlaylistRequest(const Network::Address& address, const std::string& data);
|
||||
static void PlaylistReponse(const Network::Address& address, const std::string& data);
|
||||
static void PlaylistResponse(const Network::Address& address, const std::string& data);
|
||||
static void PlaylistInvalidPassword(const Network::Address& address, const std::string& data);
|
||||
|
||||
static void MapNameCopy(char *dest, const char *src, int destsize);
|
||||
static void SetMapName(const char* cvar, const char* value);
|
||||
static void MapNameCopy(char* dest, const char* src, int destsize);
|
||||
static void SetMapName(const char* dvarName, const char* value);
|
||||
static int GetMapIndex(const char* mapname);
|
||||
};
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ namespace Components
|
||||
Utils::InfoString ServerInfo::GetInfo()
|
||||
{
|
||||
auto maxClientCount = *Game::svs_clientCount;
|
||||
const auto password = Dvar::Var("g_password").get<std::string>();
|
||||
const auto* password = (*Game::g_password)->current.string;
|
||||
|
||||
if (!maxClientCount)
|
||||
{
|
||||
@ -145,7 +145,7 @@ namespace Components
|
||||
info.set("shortversion", SHORTVERSION);
|
||||
info.set("version", (*Game::version)->current.string);
|
||||
info.set("mapname", (*Game::sv_mapname)->current.string);
|
||||
info.set("isPrivate", password.empty() ? "0" : "1");
|
||||
info.set("isPrivate", *password ? "1" : "0");
|
||||
info.set("checksum", Utils::String::VA("%X", Utils::Cryptography::JenkinsOneAtATime::Compute(Utils::String::VA("%u", Game::Sys_Milliseconds()))));
|
||||
info.set("aimAssist", (Gamepad::sv_allowAimAssist.get<bool>() ? "1" : "0"));
|
||||
info.set("voiceChat", (Voice::SV_VoiceEnabled() ? "1" : "0"));
|
||||
|
@ -17,7 +17,7 @@ namespace Components
|
||||
{
|
||||
printf("%s", "IW4x " VERSION " (built " __DATE__ " " __TIME__ ")\n");
|
||||
printf("%d\n", REVISION);
|
||||
ExitProcess(0);
|
||||
std::exit(0);
|
||||
}
|
||||
|
||||
Console::FreeNativeConsole();
|
||||
@ -28,7 +28,7 @@ namespace Components
|
||||
|
||||
if (!FirstInstance && !ConnectProtocol::Used() && MessageBoxA(nullptr, "Do you want to start another instance?\nNot all features will be available!", "Game already running", MB_ICONEXCLAMATION | MB_YESNO) == IDNO)
|
||||
{
|
||||
ExitProcess(0);
|
||||
std::exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ BOOL APIENTRY DllMain(HINSTANCE /*hinstDLL*/, DWORD fdwReason, LPVOID /*lpvReser
|
||||
if (fdwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
SetProcessDEPPolicy(PROCESS_DEP_ENABLE);
|
||||
Steam::Proxy::RunMod();
|
||||
|
||||
std::srand(std::uint32_t(std::time(nullptr)) ^ ~(GetTickCount() * GetCurrentProcessId()));
|
||||
|
||||
@ -72,6 +71,7 @@ BOOL APIENTRY DllMain(HINSTANCE /*hinstDLL*/, DWORD fdwReason, LPVOID /*lpvReser
|
||||
}
|
||||
#endif
|
||||
|
||||
Steam::Proxy::RunMod();
|
||||
// Install entry point hook
|
||||
Utils::Hook(0x6BAC0F, Main::EntryPoint, HOOK_JUMP).install()->quick();
|
||||
}
|
||||
|
@ -31,6 +31,8 @@ namespace Game
|
||||
|
||||
int* com_errorPrintsCount = reinterpret_cast<int*>(0x1AD7910);
|
||||
|
||||
int* errorcode = reinterpret_cast<int*>(0x1AD7EB4);
|
||||
|
||||
char* Com_GetParseThreadInfo()
|
||||
{
|
||||
if (Sys_IsMainThread())
|
||||
|
@ -35,7 +35,7 @@ namespace Game
|
||||
typedef void(*Com_BeginParseSession_t)(const char* filename);
|
||||
extern Com_BeginParseSession_t Com_BeginParseSession;
|
||||
|
||||
typedef char* (*Com_ParseOnLine_t)(const char** data_p);
|
||||
typedef char*(*Com_ParseOnLine_t)(const char** data_p);
|
||||
extern Com_ParseOnLine_t Com_ParseOnLine;
|
||||
|
||||
typedef void(*Com_SkipRestOfLine_t)(const char** data);
|
||||
@ -71,6 +71,8 @@ namespace Game
|
||||
|
||||
extern int* com_errorPrintsCount;
|
||||
|
||||
extern int* errorcode;
|
||||
|
||||
extern char* Com_GetParseThreadInfo();
|
||||
extern void Com_SetParseNegativeNumbers(int parse);
|
||||
|
||||
|
@ -52,6 +52,7 @@ namespace Game
|
||||
const dvar_t** g_allowVote = reinterpret_cast<const dvar_t**>(0x19BD644);
|
||||
const dvar_t** g_oldVoting = reinterpret_cast<const dvar_t**>(0x1A45DEC);
|
||||
const dvar_t** g_gametype = reinterpret_cast<const dvar_t**>(0x1A45DC8);
|
||||
const dvar_t** g_password = reinterpret_cast<const dvar_t**>(0x18835C0);
|
||||
|
||||
const dvar_t** version = reinterpret_cast<const dvar_t**>(0x1AD7930);
|
||||
|
||||
|
@ -108,6 +108,7 @@ namespace Game
|
||||
extern const dvar_t** g_allowVote;
|
||||
extern const dvar_t** g_oldVoting;
|
||||
extern const dvar_t** g_gametype;
|
||||
extern const dvar_t** g_password;
|
||||
|
||||
extern const dvar_t** version;
|
||||
|
||||
|
@ -268,6 +268,8 @@ namespace Game
|
||||
LargeLocalBeginRight_t LargeLocalBeginRight = LargeLocalBeginRight_t(0x644140);
|
||||
LargeLocalReset_t LargeLocalReset = LargeLocalReset_t(0x430630);
|
||||
|
||||
longjmp_internal_t longjmp_internal = longjmp_internal_t(0x6B8898);
|
||||
|
||||
CmdArgs* cmd_args = reinterpret_cast<CmdArgs*>(0x1AAC5D0);
|
||||
CmdArgs* sv_cmd_args = reinterpret_cast<CmdArgs*>(0x1ACF8A0);
|
||||
|
||||
@ -405,6 +407,8 @@ namespace Game
|
||||
|
||||
punctuation_s* default_punctuations = reinterpret_cast<punctuation_s*>(0x797F80);
|
||||
|
||||
bool* s_havePlaylists = reinterpret_cast<bool*>(0x1AD3680);
|
||||
|
||||
const char* TableLookup(StringTable* stringtable, int row, int column)
|
||||
{
|
||||
if (!stringtable || !stringtable->values || row >= stringtable->rowCount || column >= stringtable->columnCount) return "";
|
||||
|
@ -593,6 +593,9 @@ namespace Game
|
||||
typedef void(*LargeLocalReset_t)();
|
||||
extern LargeLocalReset_t LargeLocalReset;
|
||||
|
||||
typedef void(*longjmp_internal_t)(jmp_buf env, int status);
|
||||
extern longjmp_internal_t longjmp_internal;
|
||||
|
||||
constexpr std::size_t STATIC_MAX_LOCAL_CLIENTS = 1;
|
||||
constexpr std::size_t MAX_LOCAL_CLIENTS = 1;
|
||||
constexpr std::size_t MAX_CLIENTS = 18;
|
||||
@ -739,6 +742,8 @@ namespace Game
|
||||
|
||||
extern punctuation_s* default_punctuations;
|
||||
|
||||
extern bool* s_havePlaylists;
|
||||
|
||||
constexpr auto MAX_MSGLEN = 0x20000;
|
||||
|
||||
ScreenPlacement* ScrPlace_GetFullPlacement();
|
||||
|
Loading…
Reference in New Issue
Block a user