[Dedicated] Fix
This commit is contained in:
parent
144ba7efd3
commit
52c9602473
@ -115,6 +115,9 @@ namespace Components
|
||||
Loader::Register(new Events());
|
||||
|
||||
Loader::Pregame = false;
|
||||
|
||||
// Make sure preDestroy is called when the game shuts down
|
||||
Scheduler::OnGameShutdown(Loader::PreDestroy);
|
||||
}
|
||||
|
||||
void Loader::Uninitialize()
|
||||
|
@ -7,6 +7,12 @@ namespace Components
|
||||
Dvar::Var Branding::CGDrawVersionY;
|
||||
Game::dvar_t** Branding::Version = reinterpret_cast<Game::dvar_t**>(0x1AD7930);
|
||||
|
||||
#ifdef _DEBUG
|
||||
constexpr auto* BUILD_TYPE = "IW4x_DEV MP";
|
||||
#else
|
||||
constexpr auto* BUILD_TYPE = "IW4x MP";
|
||||
#endif
|
||||
|
||||
void Branding::CG_DrawVersion()
|
||||
{
|
||||
// Default values
|
||||
@ -45,15 +51,9 @@ namespace Components
|
||||
|
||||
const char* Branding::GetVersionString()
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
const auto* buildType = "IW4x_DEV MP";
|
||||
#else
|
||||
const auto* buildType = "IW4x MP";
|
||||
#endif
|
||||
|
||||
// IW4x is technically a beta
|
||||
const auto* result = Utils::String::VA("%s %s build %s %s",
|
||||
buildType, "(Beta)", Branding::GetBuildNumber(), reinterpret_cast<const char*>(0x7170A0));
|
||||
BUILD_TYPE, "(Beta)", Branding::GetBuildNumber(), reinterpret_cast<const char*>(0x7170A0));
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -103,6 +103,11 @@ namespace Components
|
||||
// Short version dvar
|
||||
Utils::Hook::Set<const char*>(0x60BD91, SHORTVERSION);
|
||||
|
||||
// Com_Init_Try_Block_Function
|
||||
Utils::Hook::Set<const char*>(0x60BAF4, BUILD_TYPE);
|
||||
Utils::Hook::Set<const char*>(0x60BAEf, SHORTVERSION);
|
||||
Utils::Hook::Set<const char*>(0x60BAE5, __DATE__);
|
||||
|
||||
Utils::Hook(0x4B12B0, Branding::GetBuildNumber, HOOK_JUMP).install()->quick();
|
||||
|
||||
// Version string color
|
||||
|
@ -410,7 +410,7 @@ namespace Components
|
||||
{
|
||||
cg_chatWidth = Dvar::Register<int>("cg_chatWidth", 52, 1, std::numeric_limits<int>::max(), Game::DVAR_ARCHIVE, "The normalized maximum width of a chat message");
|
||||
sv_disableChat = Dvar::Register<bool>("sv_disableChat", false, Game::dvar_flag::DVAR_NONE, "Disable chat messages from clients");
|
||||
Scheduler::Once(Chat::AddChatCommands, Scheduler::Pipeline::MAIN);
|
||||
Scheduler::OnGameInitialized(AddChatCommands, Scheduler::Pipeline::SERVER);
|
||||
|
||||
// Intercept chat sending
|
||||
Utils::Hook(0x4D000B, PreSayStub, HOOK_CALL).install()->quick();
|
||||
|
@ -84,7 +84,7 @@ namespace Components
|
||||
{
|
||||
if (Loader::IsPregame())
|
||||
{
|
||||
MessageBoxA(nullptr, "Registering server commands in pregamestate is illegal!", nullptr, MB_ICONERROR);
|
||||
MessageBoxA(nullptr, "Registering server commands in pregame state is illegal!", nullptr, MB_ICONERROR);
|
||||
|
||||
#ifdef DEBUG
|
||||
__debugbreak();
|
||||
@ -103,7 +103,7 @@ namespace Components
|
||||
Command::AddRaw(name, Game::Cbuf_AddServerText);
|
||||
}
|
||||
|
||||
FunctionMapSV.insert_or_assign(command, std::move(callback));
|
||||
FunctionMapSV.insert_or_assign(command, callback);
|
||||
}
|
||||
|
||||
void Command::AddRaw(const char* name, void(*callback)(), bool key)
|
||||
|
@ -53,9 +53,8 @@ namespace Components
|
||||
|
||||
static void Add(const char* name, const std::function<void()>& callback);
|
||||
static void Add(const char* name, const std::function<void(Command::Params*)>& callback);
|
||||
static void AddSV(const char* name, const std::function<void(Command::Params*)>& callback);
|
||||
static void AddRaw(const char* name, void(*callback)(), bool key = false);
|
||||
static void AddRawSV(const char* name, void(*callback)());
|
||||
static void AddSV(const char* name, const std::function<void(Command::Params*)>& callback);
|
||||
static void Execute(std::string command, bool sync = true);
|
||||
|
||||
static Game::cmd_function_t* Find(const std::string& command);
|
||||
@ -64,6 +63,8 @@ namespace Components
|
||||
static std::unordered_map<std::string, std::function<void(Command::Params*)>> FunctionMap;
|
||||
static std::unordered_map<std::string, std::function<void(Command::Params*)>> FunctionMapSV;
|
||||
|
||||
static void AddRawSV(const char* name, void(*callback)());
|
||||
|
||||
static void MainCallback();
|
||||
static void MainCallbackSV();
|
||||
};
|
||||
|
@ -232,7 +232,7 @@ namespace Components
|
||||
// Only skip intro here, invocation will be done later.
|
||||
Utils::Hook::Set<BYTE>(0x60BECF, 0xEB);
|
||||
|
||||
Scheduler::Once([]()
|
||||
Scheduler::Once([]
|
||||
{
|
||||
Command::Execute("openmenu popup_reconnectingtoparty", false);
|
||||
}, Scheduler::Pipeline::CLIENT, 8s);
|
||||
|
@ -140,9 +140,6 @@ namespace Components
|
||||
|
||||
void Dedicated::AddDedicatedCommands()
|
||||
{
|
||||
Dvar::Register<const char*>("sv_sayName", "^7Console", Game::dvar_flag::DVAR_NONE, "The name to pose as for 'say' commands");
|
||||
Dvar::Register<const char*>("sv_motd", "", Game::dvar_flag::DVAR_NONE, "A custom message of the day for servers");
|
||||
|
||||
// Say command
|
||||
Command::AddSV("say", [](Command::Params* params)
|
||||
{
|
||||
@ -214,7 +211,7 @@ namespace Components
|
||||
if (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled())
|
||||
{
|
||||
// Make sure all callbacks are handled
|
||||
Scheduler::Loop(Steam::SteamAPI_RunCallbacks, Scheduler::Pipeline::MAIN);
|
||||
Scheduler::Loop(Steam::SteamAPI_RunCallbacks, Scheduler::Pipeline::SERVER);
|
||||
|
||||
Dedicated::SVLanOnly = Dvar::Register<bool>("sv_lanOnly", false,
|
||||
Game::dvar_flag::DVAR_NONE, "Don't act as node");
|
||||
@ -282,7 +279,13 @@ namespace Components
|
||||
|
||||
if (!ZoneBuilder::IsEnabled())
|
||||
{
|
||||
Scheduler::Once(Dedicated::AddDedicatedCommands, Scheduler::Pipeline::MAIN);
|
||||
Scheduler::Once([]
|
||||
{
|
||||
Dvar::Register<const char*>("sv_sayName", "^7Console", Game::dvar_flag::DVAR_NONE, "The name to pose as for 'say' commands");
|
||||
Dvar::Register<const char*>("sv_motd", "", Game::dvar_flag::DVAR_NONE, "A custom message of the day for servers");
|
||||
}, Scheduler::Pipeline::MAIN);
|
||||
|
||||
Scheduler::OnGameInitialized(Dedicated::AddDedicatedCommands, Scheduler::Pipeline::SERVER);
|
||||
|
||||
// Post initialization point
|
||||
Utils::Hook(0x60BFBF, Dedicated::PostInitializationStub, HOOK_JUMP).install()->quick();
|
||||
@ -295,13 +298,8 @@ namespace Components
|
||||
}, Scheduler::Pipeline::SERVER, 10s);
|
||||
|
||||
// Heartbeats
|
||||
Scheduler::Loop([]
|
||||
{
|
||||
if (Dvar::Var("sv_maxclients").get<int>() > 0)
|
||||
{
|
||||
Dedicated::Heartbeat();
|
||||
}
|
||||
}, Scheduler::Pipeline::SERVER, 2min);
|
||||
Scheduler::Once(Dedicated::Heartbeat, Scheduler::Pipeline::SERVER);
|
||||
Scheduler::Loop(Dedicated::Heartbeat, Scheduler::Pipeline::SERVER, 2min);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -961,7 +961,7 @@ namespace Components
|
||||
|
||||
}, Scheduler::Pipeline::MAIN);
|
||||
|
||||
Events::OnVMShutdown([]()
|
||||
Events::OnVMShutdown([]
|
||||
{
|
||||
Download::ScriptDownloads.clear();
|
||||
});
|
||||
|
@ -213,6 +213,8 @@ namespace Components
|
||||
Game::dvar_t* Dvar::Dvar_RegisterName(const char* name, const char* /*default*/, unsigned __int16 flags, const char* description)
|
||||
{
|
||||
// Name watcher
|
||||
if (!Dedicated::IsEnabled() && !ZoneBuilder::IsEnabled())
|
||||
{
|
||||
Scheduler::Loop([]
|
||||
{
|
||||
static std::string lastValidName = "Unknown Soldier";
|
||||
@ -232,7 +234,8 @@ namespace Components
|
||||
lastValidName = name;
|
||||
Friends::UpdateName();
|
||||
}
|
||||
}, Scheduler::MAIN, 3s); // Don't need to do this every frame
|
||||
}, Scheduler::CLIENT, 3s); // Don't need to do this every frame
|
||||
}
|
||||
|
||||
std::string username = "Unknown Soldier";
|
||||
|
||||
|
@ -569,7 +569,9 @@ namespace Components
|
||||
FastFiles::AddZonePath("zone\\patch\\");
|
||||
FastFiles::AddZonePath("zone\\dlc\\");
|
||||
|
||||
Scheduler::Loop([]()
|
||||
if (!Dedicated::IsEnabled() && !ZoneBuilder::IsEnabled())
|
||||
{
|
||||
Scheduler::Loop([]
|
||||
{
|
||||
if (FastFiles::Current().empty() || !Dvar::Var("ui_zoneDebug").get<bool>()) return;
|
||||
|
||||
@ -589,8 +591,9 @@ namespace Components
|
||||
fastfileLoadProgress = 0.0f;
|
||||
}
|
||||
|
||||
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), std::numeric_limits<int>::max(), font, 5.0f, static_cast<float>(Renderer::Height() - 5), 1.0f, 1.0f, 0.0f, color, Game::ITEM_TEXTSTYLE_NORMAL);
|
||||
}, Scheduler::Pipeline::RENDERER);
|
||||
}
|
||||
|
||||
Command::Add("loadzone", [](Command::Params* params)
|
||||
{
|
||||
|
@ -724,7 +724,7 @@ namespace Components
|
||||
Friends::UpdateState();
|
||||
|
||||
Friends::UpdateFriends();
|
||||
}, Scheduler::Pipeline::MAIN);
|
||||
}, Scheduler::Pipeline::CLIENT);
|
||||
}
|
||||
|
||||
Friends::~Friends()
|
||||
|
@ -246,24 +246,7 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
Logger::Logger()
|
||||
{
|
||||
Dvar::Register<bool>("iw4x_onelog", false, Game::dvar_flag::DVAR_LATCH | Game::dvar_flag::DVAR_ARCHIVE, "Only write the game log to the 'userraw' OS folder");
|
||||
Utils::Hook(0x642139, Logger::BuildOSPathStub, HOOK_JUMP).install()->quick();
|
||||
|
||||
Logger::PipeOutput(nullptr);
|
||||
|
||||
Scheduler::Loop(Logger::Frame, Scheduler::Pipeline::MAIN);
|
||||
|
||||
Utils::Hook(0x4B0218, Logger::GameLogStub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(Game::Com_PrintMessage, Logger::PrintMessageStub, HOOK_JUMP).install()->quick();
|
||||
|
||||
if (Loader::IsPerformingUnitTests())
|
||||
{
|
||||
Utils::Hook(Game::Com_Printf, Logger::PrintStub, HOOK_JUMP).install()->quick();
|
||||
}
|
||||
|
||||
Scheduler::Once([]
|
||||
void Logger::AddServerCommands()
|
||||
{
|
||||
Command::AddSV("log_add", [](Command::Params* params)
|
||||
{
|
||||
@ -285,22 +268,22 @@ namespace Components
|
||||
if (Utils::String::VA("%i", num) == std::string(params->get(1)) && static_cast<unsigned int>(num) < Logger::LoggingAddresses[0].size())
|
||||
{
|
||||
auto addr = Logger::LoggingAddresses[0].begin() + num;
|
||||
Logger::Print("Address %s removed\n", addr->getCString());
|
||||
Logger::Print("Address {} removed\n", addr->getCString());
|
||||
Logger::LoggingAddresses[0].erase(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Network::Address addr(params->get(1));
|
||||
|
||||
auto i = std::find(Logger::LoggingAddresses[0].begin(), Logger::LoggingAddresses[0].end(), addr);
|
||||
const auto i = std::find(Logger::LoggingAddresses[0].begin(), Logger::LoggingAddresses[0].end(), addr);
|
||||
if (i != Logger::LoggingAddresses[0].end())
|
||||
{
|
||||
Logger::LoggingAddresses[0].erase(i);
|
||||
Logger::Print("Address %s removed\n", addr.getCString());
|
||||
Logger::Print("Address {} removed\n", addr.getCString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::Print("Address %s not found!\n", addr.getCString());
|
||||
Logger::Print("Address {} not found!\n", addr.getCString());
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -312,7 +295,7 @@ namespace Components
|
||||
|
||||
for (unsigned int i = 0; i < Logger::LoggingAddresses[0].size(); ++i)
|
||||
{
|
||||
Logger::Print("#%03d: %5s\n", i, Logger::LoggingAddresses[0][i].getCString());
|
||||
Logger::Print("{}: {}\n", i, Logger::LoggingAddresses[0][i].getCString());
|
||||
}
|
||||
});
|
||||
|
||||
@ -320,7 +303,7 @@ namespace Components
|
||||
{
|
||||
if (params->size() < 2) return;
|
||||
|
||||
Network::Address addr(params->get(1));
|
||||
const Network::Address addr(params->get(1));
|
||||
|
||||
if (std::find(Logger::LoggingAddresses[1].begin(), Logger::LoggingAddresses[1].end(), addr) == Logger::LoggingAddresses[1].end())
|
||||
{
|
||||
@ -335,23 +318,23 @@ namespace Components
|
||||
int num = atoi(params->get(1));
|
||||
if (Utils::String::VA("%i", num) == std::string(params->get(1)) && static_cast<unsigned int>(num) < Logger::LoggingAddresses[1].size())
|
||||
{
|
||||
auto addr = Logger::LoggingAddresses[1].begin() + num;
|
||||
Logger::Print("Address %s removed\n", addr->getCString());
|
||||
const auto addr = Logger::LoggingAddresses[1].begin() + num;
|
||||
Logger::Print("Address {} removed\n", addr->getCString());
|
||||
Logger::LoggingAddresses[1].erase(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Network::Address addr(params->get(1));
|
||||
const Network::Address addr(params->get(1));
|
||||
|
||||
auto i = std::find(Logger::LoggingAddresses[1].begin(), Logger::LoggingAddresses[1].end(), addr);
|
||||
const auto i = std::find(Logger::LoggingAddresses[1].begin(), Logger::LoggingAddresses[1].end(), addr);
|
||||
if (i != Logger::LoggingAddresses[1].end())
|
||||
{
|
||||
Logger::LoggingAddresses[1].erase(i);
|
||||
Logger::Print("Address %s removed\n", addr.getCString());
|
||||
Logger::Print("Address {} removed\n", addr.getCString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::Print("Address %s not found!\n", addr.getCString());
|
||||
Logger::Print("Address {} not found!\n", addr.getCString());
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -361,12 +344,31 @@ namespace Components
|
||||
Logger::Print("# ID: Address\n");
|
||||
Logger::Print("-------------\n");
|
||||
|
||||
for (unsigned int i = 0; i < Logger::LoggingAddresses[1].size(); ++i)
|
||||
for (std::size_t i = 0; i < Logger::LoggingAddresses[1].size(); ++i)
|
||||
{
|
||||
Logger::Print("#%03d: %5s\n", i, Logger::LoggingAddresses[1][i].getCString());
|
||||
Logger::Print("{}: {}\n", i, Logger::LoggingAddresses[1][i].getCString());
|
||||
}
|
||||
});
|
||||
}, Scheduler::Pipeline::MAIN);
|
||||
}
|
||||
|
||||
Logger::Logger()
|
||||
{
|
||||
Dvar::Register<bool>("iw4x_onelog", false, Game::dvar_flag::DVAR_LATCH | Game::dvar_flag::DVAR_ARCHIVE, "Only write the game log to the 'userraw' OS folder");
|
||||
Utils::Hook(0x642139, Logger::BuildOSPathStub, HOOK_JUMP).install()->quick();
|
||||
|
||||
Logger::PipeOutput(nullptr);
|
||||
|
||||
Scheduler::Loop(Logger::Frame, Scheduler::Pipeline::SERVER);
|
||||
|
||||
Utils::Hook(0x4B0218, Logger::GameLogStub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(Game::Com_PrintMessage, Logger::PrintMessageStub, HOOK_JUMP).install()->quick();
|
||||
|
||||
if (Loader::IsPerformingUnitTests())
|
||||
{
|
||||
Utils::Hook(Game::Com_Printf, Logger::PrintStub, HOOK_JUMP).install()->quick();
|
||||
}
|
||||
|
||||
Scheduler::OnGameInitialized(Logger::AddServerCommands, Scheduler::Pipeline::SERVER);
|
||||
}
|
||||
|
||||
Logger::~Logger()
|
||||
|
@ -23,99 +23,99 @@ namespace Components
|
||||
static void WarningInternal(int channel, std::string_view fmt, std::format_args&& args);
|
||||
static void DebugInternal(bool verbose, const std::source_location& srcLoc, std::string_view fmt, std::format_args&& args);
|
||||
|
||||
static inline void Print(std::string_view fmt)
|
||||
__forceinline static void Print(std::string_view fmt)
|
||||
{
|
||||
PrintInternal(Game::CON_CHANNEL_DONT_FILTER, fmt, std::make_format_args(0));
|
||||
}
|
||||
|
||||
static inline void Print(int channel, std::string_view fmt)
|
||||
__forceinline static void Print(int channel, std::string_view fmt)
|
||||
{
|
||||
PrintInternal(channel, fmt, std::make_format_args(0));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static inline void Print(std::string_view fmt, Args&&... args)
|
||||
__forceinline static void Print(std::string_view fmt, Args&&... args)
|
||||
{
|
||||
PrintInternal(Game::CON_CHANNEL_DONT_FILTER, fmt, std::make_format_args(args...));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static inline void Print(int channel, std::string_view fmt, Args&&... args)
|
||||
__forceinline static void Print(int channel, std::string_view fmt, Args&&... args)
|
||||
{
|
||||
PrintInternal(channel, fmt, std::make_format_args(args...));
|
||||
}
|
||||
|
||||
static inline void Error(Game::errorParm_t error, std::string_view fmt)
|
||||
__forceinline static void Error(Game::errorParm_t error, std::string_view fmt)
|
||||
{
|
||||
ErrorInternal(error, fmt, std::make_format_args(0));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static inline void Error(Game::errorParm_t error, std::string_view fmt, Args&&... args)
|
||||
__forceinline static void Error(Game::errorParm_t error, std::string_view fmt, Args&&... args)
|
||||
{
|
||||
ErrorInternal(error, fmt, std::make_format_args(args...));
|
||||
}
|
||||
|
||||
static inline void Warning(int channel, std::string_view fmt)
|
||||
__forceinline static void Warning(int channel, std::string_view fmt)
|
||||
{
|
||||
WarningInternal(channel, fmt, std::make_format_args(0));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static inline void Warning(int channel, std::string_view fmt, Args&&... args)
|
||||
__forceinline static void Warning(int channel, std::string_view fmt, Args&&... args)
|
||||
{
|
||||
WarningInternal(channel, fmt, std::make_format_args(args...));
|
||||
}
|
||||
|
||||
static inline void PrintError(int channel, std::string_view fmt)
|
||||
__forceinline static void PrintError(int channel, std::string_view fmt)
|
||||
{
|
||||
PrintErrorInternal(channel, fmt, std::make_format_args(0));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static inline void PrintError(int channel, std::string_view fmt, Args&&... args)
|
||||
__forceinline static void PrintError(int channel, std::string_view fmt, Args&&... args)
|
||||
{
|
||||
PrintErrorInternal(channel, fmt, std::make_format_args(args...));
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
static inline void DebugInfo([[maybe_unused]] std::string_view fmt)
|
||||
__forceinline static void DebugInfo([[maybe_unused]] std::string_view fmt)
|
||||
{
|
||||
DebugInternal(true, std::source_location::current(), fmt, std::make_format_args(0));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static inline void DebugInfo([[maybe_unused]] std::string_view fmt, [[maybe_unused]] Args&&... args)
|
||||
__forceinline static void DebugInfo([[maybe_unused]] std::string_view fmt, [[maybe_unused]] Args&&... args)
|
||||
{
|
||||
DebugInternal(true, std::source_location::current(), fmt, std::make_format_args(args...));
|
||||
}
|
||||
|
||||
static inline void Debug([[maybe_unused]] std::string_view fmt)
|
||||
__forceinline static void Debug([[maybe_unused]] std::string_view fmt)
|
||||
{
|
||||
DebugInternal(false, std::source_location::current(), fmt, std::make_format_args(0));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static inline void Debug([[maybe_unused]] std::string_view fmt, [[maybe_unused]] Args&&... args)
|
||||
__forceinline static void Debug([[maybe_unused]] std::string_view fmt, [[maybe_unused]] Args&&... args)
|
||||
{
|
||||
DebugInternal(false, std::source_location::current(), fmt, std::make_format_args(args...));
|
||||
}
|
||||
#else
|
||||
static inline void DebugInfo([[maybe_unused]] std::string_view fmt)
|
||||
__forceinline static void DebugInfo([[maybe_unused]] std::string_view fmt)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static inline void DebugInfo([[maybe_unused]] std::string_view fmt, [[maybe_unused]] Args&&... args)
|
||||
__forceinline static void DebugInfo([[maybe_unused]] std::string_view fmt, [[maybe_unused]] Args&&... args)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void Debug([[maybe_unused]] std::string_view fmt)
|
||||
__forceinline static void Debug([[maybe_unused]] std::string_view fmt)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static inline void Debug([[maybe_unused]] std::string_view fmt, [[maybe_unused]] Args&&... args)
|
||||
__forceinline static void Debug([[maybe_unused]] std::string_view fmt, [[maybe_unused]] Args&&... args)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@ -136,5 +136,7 @@ namespace Components
|
||||
static void RedirectOSPath(const char* file, char* folder);
|
||||
|
||||
static void NetworkLog(const char* data, bool gLog);
|
||||
|
||||
static void AddServerCommands();
|
||||
};
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ namespace Components
|
||||
std::vector<std::pair<std::string, std::string>> Maps::DependencyList;
|
||||
std::vector<std::string> Maps::CurrentDependencies;
|
||||
|
||||
Dvar::Var Maps::RListSModels;
|
||||
|
||||
bool Maps::SPMap;
|
||||
std::vector<Maps::DLC> Maps::DlcPacks;
|
||||
|
||||
@ -775,7 +777,7 @@ namespace Components
|
||||
Scheduler::Once([]
|
||||
{
|
||||
Dvar::Register<bool>("isDlcInstalled_All", false, Game::DVAR_EXTERNAL | Game::DVAR_WRITEPROTECTED, "");
|
||||
Dvar::Register<bool>("r_listSModels", false, Game::DVAR_NONE, "Display a list of visible SModels");
|
||||
Maps::RListSModels = Dvar::Register<bool>("r_listSModels", false, Game::DVAR_NONE, "Display a list of visible SModels");
|
||||
|
||||
Maps::AddDlc({ 1, "Stimulus Pack", {"mp_complex", "mp_compact", "mp_storm", "mp_overgrown", "mp_crash"} });
|
||||
Maps::AddDlc({ 2, "Resurgence Pack", {"mp_abandon", "mp_vacant", "mp_trailerpark", "mp_strike", "mp_fuel2"} });
|
||||
@ -882,7 +884,7 @@ namespace Components
|
||||
Utils::Hook(0x5A9D51, Maps::LoadMapLoadscreenStub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x5B34DD, Maps::LoadMapLoadscreenStub, HOOK_CALL).install()->quick();
|
||||
|
||||
Command::Add("delayReconnect", [](Command::Params*)
|
||||
Command::Add("delayReconnect", []([[maybe_unused]] Command::Params* params)
|
||||
{
|
||||
Scheduler::Once([]
|
||||
{
|
||||
@ -913,10 +915,16 @@ namespace Components
|
||||
// Allow hiding specific smodels
|
||||
Utils::Hook(0x50E67C, Maps::HideModelStub, HOOK_CALL).install()->quick();
|
||||
|
||||
if (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Client only
|
||||
Scheduler::Loop([]
|
||||
{
|
||||
auto*& gameWorld = *reinterpret_cast<Game::GfxWorld**>(0x66DEE94);
|
||||
if (!Game::CL_IsCgameInitialized() || !gameWorld || !Dvar::Var("r_listSModels").get<bool>()) return;
|
||||
if (!Game::CL_IsCgameInitialized() || !gameWorld || !Maps::RListSModels.get<bool>()) return;
|
||||
|
||||
std::map<std::string, int> models;
|
||||
for (unsigned int i = 0; i < gameWorld->dpvs.smodelCount; ++i)
|
||||
|
@ -83,6 +83,8 @@ namespace Components
|
||||
static std::vector<std::pair<std::string, std::string>> DependencyList;
|
||||
static std::vector<std::string> CurrentDependencies;
|
||||
|
||||
static Dvar::Var RListSModels;
|
||||
|
||||
static void GetBSPName(char* buffer, size_t size, const char* format, const char* mapname);
|
||||
static void LoadAssetRestrict(Game::XAssetType type, Game::XAssetHeader asset, const std::string& name, bool* restrict);
|
||||
static void LoadMapZones(Game::XZoneInfo *zoneInfo, unsigned int zoneCount, int sync);
|
||||
|
@ -146,7 +146,7 @@ namespace Components
|
||||
|
||||
if (!address.isValid()) return;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> _(Node::Mutex);
|
||||
std::lock_guard _(Node::Mutex);
|
||||
for (auto& session : Node::Nodes)
|
||||
{
|
||||
if (session.address == address) return;
|
||||
@ -160,7 +160,7 @@ namespace Components
|
||||
|
||||
std::vector<Node::Entry> Node::GetNodes()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Node::Mutex);
|
||||
std::lock_guard _(Node::Mutex);
|
||||
|
||||
return Node::Nodes;
|
||||
}
|
||||
@ -197,7 +197,7 @@ namespace Components
|
||||
if (!frameLimit.elapsed(std::chrono::milliseconds(interval))) return;
|
||||
frameLimit.update();
|
||||
|
||||
std::lock_guard<std::recursive_mutex> _(Node::Mutex);
|
||||
std::lock_guard _(Node::Mutex);
|
||||
Dvar::Var queryLimit("net_serverQueryLimit");
|
||||
|
||||
int sentRequests = 0;
|
||||
@ -220,7 +220,7 @@ namespace Components
|
||||
|
||||
void Node::Synchronize()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Node::Mutex);
|
||||
std::lock_guard _(Node::Mutex);
|
||||
for (auto& node : Node::Nodes)
|
||||
{
|
||||
//if (node.isValid()) // Comment out to simulate 'syncnodes' behaviour
|
||||
@ -237,7 +237,7 @@ namespace Components
|
||||
|
||||
Logger::DebugInfo("Received response from {}\n", address.getCString());
|
||||
|
||||
std::lock_guard<std::recursive_mutex> _(Node::Mutex);
|
||||
std::lock_guard _(Node::Mutex);
|
||||
|
||||
for (int i = 0; i < list.nodes_size(); ++i)
|
||||
{
|
||||
@ -282,9 +282,9 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
void Node::SendList(Network::Address address)
|
||||
void Node::SendList(const Network::Address& address)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Node::Mutex);
|
||||
std::lock_guard _(Node::Mutex);
|
||||
|
||||
// need to keep the message size below 1404 bytes else recipient will just drop it
|
||||
std::vector<std::string> nodeListReponseMessages;
|
||||
@ -320,11 +320,13 @@ namespace Components
|
||||
auto i = 0;
|
||||
for (const auto& nodeListData : nodeListReponseMessages)
|
||||
{
|
||||
Scheduler::Once([&]
|
||||
Scheduler::Once([=]
|
||||
{
|
||||
Logger::DebugInfo("Sending {} nodeListResponse length to {}\n", nodeListData.length(), address.getCString());
|
||||
#ifdef DEBUG_NODE
|
||||
Logger::Debug("Sending {} nodeListResponse length to {}\n", nodeListData.length(), address.getCString());
|
||||
#endif
|
||||
Session::Send(address, "nodeListResponse", nodeListData);
|
||||
}, Scheduler::Pipeline::MAIN, NODE_SEND_RATE * i++);
|
||||
}, Scheduler::Pipeline::SERVER, NODE_SEND_RATE * i++);
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,16 +346,16 @@ namespace Components
|
||||
Node::StoreNodes(false);
|
||||
}, Scheduler::Pipeline::ASYNC);
|
||||
|
||||
Scheduler::Loop(Node::RunFrame, Scheduler::Pipeline::MAIN);
|
||||
Scheduler::Loop(Node::RunFrame, Scheduler::Pipeline::SERVER);
|
||||
|
||||
Session::Handle("nodeListResponse", Node::HandleResponse);
|
||||
Session::Handle("nodeListRequest", [](Network::Address address, const std::string&)
|
||||
Session::Handle("nodeListRequest", [](const Network::Address& address, const std::string&)
|
||||
{
|
||||
Node::SendList(address);
|
||||
});
|
||||
|
||||
// Load stored nodes
|
||||
auto loadNodes = []()
|
||||
auto loadNodes = []
|
||||
{
|
||||
Node::LoadNodePreset();
|
||||
Node::LoadNodes();
|
||||
@ -374,7 +376,7 @@ namespace Components
|
||||
{
|
||||
Logger::Print("Nodes: {}\n", Node::Nodes.size());
|
||||
|
||||
std::lock_guard<std::recursive_mutex> _(Node::Mutex);
|
||||
std::lock_guard _(Node::Mutex);
|
||||
for (auto& node : Node::Nodes)
|
||||
{
|
||||
Logger::Print("{}\t({})\n", node.address.getCString(), node.isValid() ? "Valid" : "Invalid");
|
||||
@ -390,7 +392,7 @@ namespace Components
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Node::Mutex);
|
||||
std::lock_guard _(Node::Mutex);
|
||||
Node::StoreNodes(true);
|
||||
Node::Nodes.clear();
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ namespace Components
|
||||
|
||||
static void HandleResponse(Network::Address address, const std::string& data);
|
||||
|
||||
static void SendList(Network::Address address);
|
||||
static void SendList(const Network::Address& address);
|
||||
|
||||
static void LoadNodePreset();
|
||||
static void LoadNodes();
|
||||
|
@ -286,6 +286,8 @@ namespace Components
|
||||
Party::Connect(Party::Container.target);
|
||||
});
|
||||
|
||||
if (!Dedicated::IsEnabled() && !ZoneBuilder::IsEnabled())
|
||||
{
|
||||
Scheduler::Loop([]
|
||||
{
|
||||
if (Party::Container.valid)
|
||||
@ -307,6 +309,7 @@ namespace Components
|
||||
}
|
||||
|
||||
}, Scheduler::Pipeline::CLIENT);
|
||||
}
|
||||
|
||||
// Basic info handler
|
||||
Network::OnPacket("getInfo", [](const Network::Address& address, [[maybe_unused]] const std::string& data)
|
||||
|
@ -263,9 +263,6 @@ namespace Components
|
||||
|
||||
Utils::Hook(0x4FA448, QuickPatch::Dvar_RegisterConMinicon, HOOK_CALL).install()->quick();
|
||||
|
||||
// Make sure preDestroy is called when the game shuts down
|
||||
Scheduler::OnGameShutdown(Loader::PreDestroy);
|
||||
|
||||
// protocol version (workaround for hacks)
|
||||
Utils::Hook::Set<int>(0x4FB501, PROTOCOL);
|
||||
|
||||
|
@ -15,7 +15,7 @@ namespace Components
|
||||
|
||||
std::queue<std::pair<Network::Address, std::string>> Session::SignatureQueue;
|
||||
|
||||
void Session::Send(Network::Address target, const std::string& command, const std::string& data)
|
||||
void Session::Send(const Network::Address& target, const std::string& command, const std::string& data)
|
||||
{
|
||||
#ifdef DISABLE_SESSION
|
||||
class DelayedResend
|
||||
@ -26,27 +26,27 @@ namespace Components
|
||||
std::string data;
|
||||
};
|
||||
|
||||
DelayedResend* delayData = new DelayedResend;
|
||||
auto* delayData = new DelayedResend;
|
||||
delayData->target = target;
|
||||
delayData->command = command;
|
||||
delayData->data = data;
|
||||
|
||||
Network::SendCommand(target, command, data);
|
||||
|
||||
Scheduler::Once([delayData]()
|
||||
Scheduler::Once([delayData]
|
||||
{
|
||||
Network::SendCommand(delayData->target, delayData->command, delayData->data);
|
||||
delete delayData;
|
||||
}, Scheduler::Pipeline::MAIN, 500ms + std::chrono::milliseconds(rand() % 200));
|
||||
}, Scheduler::Pipeline::SERVER, 500ms + std::chrono::milliseconds(std::rand() % 200));
|
||||
#else
|
||||
std::lock_guard<std::recursive_mutex> _(Session::Mutex);
|
||||
std::lock_guard _(Session::Mutex);
|
||||
|
||||
auto queue = Session::PacketQueue.find(target);
|
||||
if (queue == Session::PacketQueue.end())
|
||||
{
|
||||
Session::PacketQueue[target] = std::queue<std::shared_ptr<Session::Packet>>();
|
||||
queue = Session::PacketQueue.find(target);
|
||||
if (queue == Session::PacketQueue.end()) Logger::Error("Failed to enqueue session packet!\n");
|
||||
if (queue == Session::PacketQueue.end()) Logger::Error(Game::ERR_FATAL, "Failed to enqueue session packet!\n");
|
||||
}
|
||||
|
||||
std::shared_ptr<Session::Packet> packet = std::make_shared<Session::Packet>();
|
||||
@ -63,14 +63,14 @@ namespace Components
|
||||
#ifdef DISABLE_SESSION
|
||||
Network::OnPacket(packet, callback);
|
||||
#else
|
||||
std::lock_guard<std::recursive_mutex> _(Session::Mutex);
|
||||
std::lock_guard _(Session::Mutex);
|
||||
Session::PacketHandlers[packet] = callback;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Session::RunFrame()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Session::Mutex);
|
||||
std::lock_guard _(Session::Mutex);
|
||||
|
||||
for (auto queue = Session::PacketQueue.begin(); queue != Session::PacketQueue.end();)
|
||||
{
|
||||
@ -155,7 +155,7 @@ namespace Components
|
||||
Session::Frame frame;
|
||||
frame.challenge = Utils::Cryptography::Rand::GenerateChallenge();
|
||||
|
||||
std::lock_guard<std::recursive_mutex> _(Session::Mutex);
|
||||
std::lock_guard _(Session::Mutex);
|
||||
Session::Sessions[address] = frame;
|
||||
|
||||
Network::SendCommand(address, "sessionAck", frame.challenge);
|
||||
@ -163,13 +163,13 @@ namespace Components
|
||||
|
||||
Network::OnPacket("sessionAck", [](const Network::Address& address, [[maybe_unused]] const std::string& data)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Session::Mutex);
|
||||
std::lock_guard _(Session::Mutex);
|
||||
Session::SignatureQueue.push({ address, data });
|
||||
});
|
||||
|
||||
Network::OnPacket("sessionFin", [](Network::Address& address, [[maybe_unused]] const std::string& data)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Session::Mutex);
|
||||
std::lock_guard _(Session::Mutex);
|
||||
|
||||
auto frame = Session::Sessions.find(address);
|
||||
if (frame == Session::Sessions.end()) return;
|
||||
@ -195,7 +195,7 @@ namespace Components
|
||||
|
||||
Session::~Session()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Session::Mutex);
|
||||
std::lock_guard _(Session::Mutex);
|
||||
Session::PacketHandlers.clear();
|
||||
Session::PacketQueue.clear();
|
||||
Session::SignatureQueue = std::queue<std::pair<Network::Address, std::string>>();
|
||||
|
@ -34,7 +34,7 @@ namespace Components
|
||||
bool unitTest() override;
|
||||
void preDestroy() override;
|
||||
|
||||
static void Send(Network::Address target, const std::string& command, const std::string& data = "");
|
||||
static void Send(const Network::Address& target, const std::string& command, const std::string& data = "");
|
||||
static void Handle(const std::string& packet, const Network::NetworkCallback& callback);
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user