commit
11a10ed35d
10
.editorconfig
Normal file
10
.editorconfig
Normal file
@ -0,0 +1,10 @@
|
||||
[*.{cpp,hpp}]
|
||||
end_of_line = crlf
|
||||
insert_final_newline = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
charset = utf-8
|
||||
brace_style = next_line
|
||||
namespace_indentation = all
|
||||
cpp_indent_namespace_contents = true
|
12
CHANGELOG.md
12
CHANGELOG.md
@ -4,6 +4,18 @@ 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/).
|
||||
|
||||
## r4226 - 2023-04-26
|
||||
|
||||
- Chat system will go back to using `SV_CMD_CAN_IGNORE` commands (#972)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix bug with how `sv_mapRotationCurrent` is parsed (#977)
|
||||
|
||||
### Known issues
|
||||
|
||||
- Sound issue fix is experimental as the bug is not fully understood.
|
||||
|
||||
## r4208 - 2023-04-22
|
||||
|
||||
### Changed
|
||||
|
@ -16,7 +16,7 @@ namespace Components
|
||||
const Game::dvar_t* Bots::sv_randomBotNames;
|
||||
const Game::dvar_t* Bots::sv_replaceBots;
|
||||
|
||||
std::size_t Bots::botDataIndex;
|
||||
std::size_t Bots::BotDataIndex;
|
||||
|
||||
struct BotMovementInfo
|
||||
{
|
||||
@ -121,8 +121,8 @@ namespace Components
|
||||
|
||||
if (!botNames.empty())
|
||||
{
|
||||
botDataIndex %= botNames.size();
|
||||
const auto index = botDataIndex++;
|
||||
BotDataIndex %= botNames.size();
|
||||
const auto index = BotDataIndex++;
|
||||
botName = botNames[index].first;
|
||||
clanName = botNames[index].second;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace Components
|
||||
static const Game::dvar_t* sv_randomBotNames;
|
||||
static const Game::dvar_t* sv_replaceBots;
|
||||
|
||||
static std::size_t botDataIndex;
|
||||
static std::size_t BotDataIndex;
|
||||
|
||||
static std::vector<botData> LoadBotNames();
|
||||
static int BuildConnectString(char* buffer, const char* connectString, int num, int, int protocol, int checksum, int statVer, int statStuff, int port);
|
||||
|
@ -101,7 +101,7 @@ namespace Components
|
||||
RegisterBrandingDvars();
|
||||
|
||||
// UI version string
|
||||
Utils::Hook::Set<const char*>(0x43F73B, "IW4x - " REVISION_STR);
|
||||
Utils::Hook::Set<const char*>(0x43F73B, "IW4x " REVISION_STR);
|
||||
|
||||
// Short version dvar
|
||||
Utils::Hook::Set<const char*>(0x60BD91, REVISION_STR);
|
||||
|
@ -56,13 +56,13 @@ namespace Components
|
||||
if (IsMuted(player))
|
||||
{
|
||||
SendChat = false;
|
||||
Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_RELIABLE, Utils::String::VA("%c \"You are muted\"", 0x65));
|
||||
Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"You are muted\"", 0x65));
|
||||
}
|
||||
|
||||
if (sv_disableChat.get<bool>())
|
||||
{
|
||||
SendChat = false;
|
||||
Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_RELIABLE, Utils::String::VA("%c \"Chat is disabled\"", 0x65));
|
||||
Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"Chat is disabled\"", 0x65));
|
||||
}
|
||||
|
||||
// Message might be empty after the special characters
|
||||
@ -297,7 +297,7 @@ namespace Components
|
||||
});
|
||||
|
||||
Logger::Print("{} was muted\n", client->name);
|
||||
Game::SV_GameSendServerCommand(client - Game::svs_clients, Game::SV_CMD_RELIABLE, Utils::String::VA("%c \"You were muted\"", 0x65));
|
||||
Game::SV_GameSendServerCommand(client - Game::svs_clients, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"You were muted\"", 0x65));
|
||||
}
|
||||
|
||||
void Chat::UnmuteClient(const Game::client_t* client)
|
||||
@ -305,7 +305,7 @@ namespace Components
|
||||
UnmuteInternal(client->steamID);
|
||||
|
||||
Logger::Print("{} was unmuted\n", client->name);
|
||||
Game::SV_GameSendServerCommand(client - Game::svs_clients, Game::SV_CMD_RELIABLE, Utils::String::VA("%c \"You were unmuted\"", 0x65));
|
||||
Game::SV_GameSendServerCommand(client - Game::svs_clients, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"You were unmuted\"", 0x65));
|
||||
}
|
||||
|
||||
void Chat::UnmuteInternal(const std::uint64_t id, bool everyone)
|
||||
@ -461,12 +461,12 @@ namespace Components
|
||||
|
||||
if (!name.empty())
|
||||
{
|
||||
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_RELIABLE, Utils::String::Format("{:c} \"{}: {}\"", 0x68, name, message));
|
||||
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}: {}\"", 0x68, name, message));
|
||||
Logger::Print(Game::CON_CHANNEL_SERVER, "{}: {}\n", name, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_RELIABLE, Utils::String::Format("{:c} \"Console: {}\"", 0x68, message));
|
||||
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"Console: {}\"", 0x68, message));
|
||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Console: {}\n", message);
|
||||
}
|
||||
});
|
||||
@ -489,12 +489,12 @@ namespace Components
|
||||
|
||||
if (!name.empty())
|
||||
{
|
||||
Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_RELIABLE, Utils::String::Format("{:c} \"{}: {}\"", 0x68, name.data(), message));
|
||||
Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}: {}\"", 0x68, name.data(), message));
|
||||
Logger::Print(Game::CON_CHANNEL_SERVER, "{} -> {}: {}\n", name, clientNum, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_RELIABLE, Utils::String::Format("{:c} \"Console: {}\"", 0x68, message));
|
||||
Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"Console: {}\"", 0x68, message));
|
||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Console -> {}: {}\n", clientNum, message);
|
||||
}
|
||||
});
|
||||
@ -510,7 +510,7 @@ namespace Components
|
||||
if (params->size() < 2) return;
|
||||
|
||||
const auto message = params->join(1);
|
||||
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_RELIABLE, Utils::String::Format("{:c} \"{}\"", 0x68, message));
|
||||
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}\"", 0x68, message));
|
||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Raw: {}\n", message);
|
||||
});
|
||||
|
||||
@ -528,7 +528,7 @@ namespace Components
|
||||
const auto clientNum = static_cast<int>(std::min<std::size_t>(parsedInput, Game::MAX_CLIENTS));
|
||||
|
||||
const auto message = params->join(2);
|
||||
Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_RELIABLE, Utils::String::Format("{:c} \"{}\"", 0x68, message));
|
||||
Game::SV_GameSendServerCommand(clientNum, Game::SV_CMD_CAN_IGNORE, Utils::String::Format("{:c} \"{}\"", 0x68, message));
|
||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Raw -> {}: {}\n", clientNum, message);
|
||||
});
|
||||
|
||||
@ -619,9 +619,6 @@ namespace Components
|
||||
Utils::Hook(0x4D00D4, PostSayStub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x4D0110, PostSayStub, HOOK_CALL).install()->quick();
|
||||
|
||||
// Patch G_SayTo to use SV_CMD_RELIABLE
|
||||
Utils::Hook::Set<std::uint8_t>(0x5DF7E3, Game::SV_CMD_RELIABLE);
|
||||
|
||||
// Change logic that does word splitting with new lines for chat messages to support fonticons
|
||||
Utils::Hook(0x592E10, CG_AddToTeamChat_Stub, HOOK_JUMP).install()->quick();
|
||||
|
||||
|
@ -97,9 +97,9 @@ namespace Components
|
||||
else if (IsWindow(GetWindow()) != FALSE)
|
||||
{
|
||||
#ifdef EXPERIMENTAL_BUILD
|
||||
SetWindowTextA(GetWindow(), Utils::String::Format("IW4x " REVISION_STR "-develop : %s", hostname));
|
||||
SetWindowTextA(GetWindow(), Utils::String::Format("IW4x " REVISION_STR "-develop : {}", hostname));
|
||||
#else
|
||||
SetWindowTextA(GetWindow(), Utils::String::Format("IW4x " REVISION_STR " : %s", hostname));
|
||||
SetWindowTextA(GetWindow(), Utils::String::Format("IW4x " REVISION_STR " : {}", hostname));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace Components
|
||||
|
||||
void Logger::Print_Stub(const int channel, const char* message, ...)
|
||||
{
|
||||
char buf[4096] = {0};
|
||||
char buf[4096]{};
|
||||
|
||||
va_list va;
|
||||
va_start(va, message);
|
||||
|
@ -126,7 +126,7 @@ namespace Components
|
||||
return mapRotationJson;
|
||||
}
|
||||
|
||||
void MapRotation::LoadRotation(const std::string& data)
|
||||
void MapRotation::ParseRotation(const std::string& data)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -134,12 +134,25 @@ namespace Components
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}: {} contains invalid data!\n", ex.what(), (*Game::sv_mapRotation)->name);
|
||||
Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}. {} contains invalid data!\n", ex.what(), (*Game::sv_mapRotation)->name);
|
||||
}
|
||||
|
||||
Logger::Debug("DedicatedRotation size after parsing is '{}'", DedicatedRotation.getEntriesSize());
|
||||
}
|
||||
|
||||
void MapRotation::RandomizeMapRotation()
|
||||
{
|
||||
if (SVRandomMapRotation.get<bool>())
|
||||
{
|
||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Randomizing the map rotation\n");
|
||||
DedicatedRotation.randomize();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::Debug("Map rotation was not randomized");
|
||||
}
|
||||
}
|
||||
|
||||
void MapRotation::LoadMapRotation()
|
||||
{
|
||||
static auto loaded = false;
|
||||
@ -155,14 +168,15 @@ namespace Components
|
||||
// People may have sv_mapRotation empty because they only use 'addMap' or 'addGametype'
|
||||
if (!mapRotation.empty())
|
||||
{
|
||||
Logger::Debug("sv_mapRotation is not empty. Parsing...");
|
||||
LoadRotation(mapRotation);
|
||||
Logger::Debug("{} is not empty. Parsing...", (*Game::sv_mapRotation)->name);
|
||||
ParseRotation(mapRotation);
|
||||
RandomizeMapRotation();
|
||||
}
|
||||
}
|
||||
|
||||
void MapRotation::AddMapRotationCommands()
|
||||
{
|
||||
Command::Add("addMap", [](Command::Params* params)
|
||||
Command::AddSV("addMap", [](Command::Params* params)
|
||||
{
|
||||
if (params->size() < 2)
|
||||
{
|
||||
@ -173,7 +187,7 @@ namespace Components
|
||||
DedicatedRotation.addEntry("map", params->get(1));
|
||||
});
|
||||
|
||||
Command::Add("addGametype", [](Command::Params* params)
|
||||
Command::AddSV("addGametype", [](Command::Params* params)
|
||||
{
|
||||
if (params->size() < 2)
|
||||
{
|
||||
@ -286,9 +300,13 @@ namespace Components
|
||||
assert(!data.empty());
|
||||
|
||||
// Ook, ook, eek
|
||||
Logger::Warning(Game::CON_CHANNEL_SERVER, "You are using deprecated {}", (*Game::sv_mapRotationCurrent)->name);
|
||||
Logger::Warning(Game::CON_CHANNEL_SERVER, "You are using deprecated {}\n", (*Game::sv_mapRotationCurrent)->name);
|
||||
|
||||
RotationData rotationCurrent;
|
||||
rotationCurrent.setHandler("map", ApplyMap);
|
||||
rotationCurrent.setHandler("gametype", ApplyGametype);
|
||||
rotationCurrent.setHandler("exec", ApplyExec);
|
||||
|
||||
try
|
||||
{
|
||||
Logger::Debug("Parsing {}", (*Game::sv_mapRotationCurrent)->name);
|
||||
@ -296,7 +314,7 @@ namespace Components
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}: {} contains invalid data!\n", ex.what(), (*Game::sv_mapRotationCurrent)->name);
|
||||
Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}. {} contains invalid data!\n", ex.what(), (*Game::sv_mapRotationCurrent)->name);
|
||||
}
|
||||
|
||||
Game::Dvar_SetString(*Game::sv_mapRotationCurrent, "");
|
||||
@ -337,19 +355,6 @@ namespace Components
|
||||
SVNextMap.set("");
|
||||
}
|
||||
|
||||
void MapRotation::RandomizeMapRotation()
|
||||
{
|
||||
if (SVRandomMapRotation.get<bool>())
|
||||
{
|
||||
Logger::Print(Game::CON_CHANNEL_SERVER, "Randomizing the map rotation\n");
|
||||
DedicatedRotation.randomize();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::Debug("Map rotation was not randomized");
|
||||
}
|
||||
}
|
||||
|
||||
void MapRotation::SV_MapRotate_f()
|
||||
{
|
||||
if (!ShouldRotate())
|
||||
@ -378,8 +383,6 @@ namespace Components
|
||||
return;
|
||||
}
|
||||
|
||||
RandomizeMapRotation();
|
||||
|
||||
ApplyRotation(DedicatedRotation);
|
||||
SetNextMap(DedicatedRotation);
|
||||
}
|
||||
@ -393,7 +396,7 @@ namespace Components
|
||||
|
||||
MapRotation::MapRotation()
|
||||
{
|
||||
AddMapRotationCommands();
|
||||
Events::OnSVInit(AddMapRotationCommands);
|
||||
Utils::Hook::Set<void(*)()>(0x4152E8, SV_MapRotate_f);
|
||||
|
||||
DedicatedRotation.setHandler("map", ApplyMap);
|
||||
@ -407,30 +410,35 @@ namespace Components
|
||||
{
|
||||
Logger::Debug("Testing map rotation parsing...");
|
||||
|
||||
const auto* normal = "map mp_highrise map mp_terminal map mp_firingrange map mp_trailerpark gametype dm map mp_shipment_long";
|
||||
const auto* normal = "exec war.cfg map mp_highrise map mp_terminal map mp_firingrange map mp_trailerpark gametype dm map mp_shipment_long";
|
||||
|
||||
RotationData rotation;
|
||||
rotation.setHandler("map", ApplyMap);
|
||||
rotation.setHandler("gametype", ApplyGametype);
|
||||
rotation.setHandler("exec", ApplyExec);
|
||||
|
||||
try
|
||||
{
|
||||
DedicatedRotation.parse(normal);
|
||||
rotation.parse(normal);
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}: parsing of 'normal' failed\n", ex.what());
|
||||
Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}. parsing of 'normal' failed\n", ex.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
DedicatedRotation.clear();
|
||||
rotation.clear();
|
||||
|
||||
const auto* mistake = "spdevmap mp_dome";
|
||||
auto success = false;
|
||||
|
||||
try
|
||||
{
|
||||
DedicatedRotation.parse(mistake);
|
||||
rotation.parse(mistake);
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
Logger::Debug("{}: parsing of 'normal' failed as expected", ex.what());
|
||||
Logger::Debug("{}. parsing of 'normal' failed as expected", ex.what());
|
||||
success = true;
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,8 @@ namespace Components
|
||||
// Holds the parsed data from sv_mapRotation
|
||||
static RotationData DedicatedRotation;
|
||||
|
||||
static void LoadRotation(const std::string& data);
|
||||
static void RandomizeMapRotation();
|
||||
static void ParseRotation(const std::string& data);
|
||||
static void LoadMapRotation();
|
||||
|
||||
// Use these commands before SV_MapRotate_f is called
|
||||
@ -103,7 +104,6 @@ namespace Components
|
||||
static void SetNextMap(RotationData& rotation); // Only call this after ApplyRotation
|
||||
static void SetNextMap(const char* value);
|
||||
static void ClearNextMap();
|
||||
static void RandomizeMapRotation();
|
||||
|
||||
static void SV_MapRotate_f();
|
||||
};
|
||||
|
@ -5,6 +5,7 @@ namespace Components
|
||||
Utils::Signal<Network::CallbackRaw> Network::StartupSignal;
|
||||
// Packet interception
|
||||
std::unordered_map<std::string, Network::networkCallback> Network::CL_Callbacks;
|
||||
std::unordered_map<std::string, Network::networkRawCallback> Network::CL_RawCallbacks;
|
||||
|
||||
Network::Address::Address()
|
||||
{
|
||||
@ -274,17 +275,34 @@ namespace Components
|
||||
CL_Callbacks[Utils::String::ToLower(command)] = callback;
|
||||
}
|
||||
|
||||
bool Network::CL_HandleCommand(Game::netadr_t* address, const char* command, const Game::msg_t* message)
|
||||
void Network::OnClientPacketRaw(const std::string& command, const networkRawCallback& callback)
|
||||
{
|
||||
CL_RawCallbacks[Utils::String::ToLower(command)] = callback;
|
||||
}
|
||||
|
||||
bool Network::CL_HandleCommand(Game::netadr_t* address, const char* command, Game::msg_t* message)
|
||||
{
|
||||
const auto command_ = Utils::String::ToLower(command);
|
||||
const auto handler = CL_Callbacks.find(command_);
|
||||
|
||||
const auto offset = command_.size() + 5;
|
||||
if (static_cast<std::size_t>(message->cursize) < offset || handler == CL_Callbacks.end())
|
||||
if (static_cast<std::size_t>(message->cursize) < offset)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const auto rawHandler = CL_RawCallbacks.find(command_); rawHandler != CL_RawCallbacks.end())
|
||||
{
|
||||
rawHandler->second(address, message);
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto handler = CL_Callbacks.find(command_);
|
||||
if (handler == CL_Callbacks.end())
|
||||
{
|
||||
// Normal handler was not found, return
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string data(reinterpret_cast<char*>(message->data) + offset, message->cursize - offset);
|
||||
|
||||
auto target = Address{ address };
|
||||
@ -360,9 +378,13 @@ namespace Components
|
||||
Utils::Hook::Set<std::uint8_t>(0x5AA5B6, 0xEB); // CL_SteamServerAuth
|
||||
Utils::Hook::Set<std::uint8_t>(0x5AA69F, 0xEB); // echo
|
||||
Utils::Hook::Set<std::uint8_t>(0x5AAA82, 0xEB); // SP
|
||||
Utils::Hook::Set<std::uint8_t>(0x5A9F77, 0xEB); // CL_WeNowCantHearSomeone
|
||||
Utils::Hook::Set<std::uint8_t>(0x5A9F18, 0xEB); // CL_VoiceConnectionTestPacket
|
||||
Utils::Hook::Set<std::uint8_t>(0x5A9FF3, 0xEB); // CL_HandleRelayPacket
|
||||
|
||||
// For security reasons check the sender of the 'print' OOB
|
||||
Utils::Hook::Set<std::uint8_t>(0x5AA729, 0xEB);
|
||||
|
||||
// Com_GetProtocol
|
||||
Utils::Hook::Set<std::uint32_t>(0x4FB501, PROTOCOL);
|
||||
|
||||
@ -381,9 +403,24 @@ namespace Components
|
||||
Utils::Hook::Set<std::uint8_t>(0x682170, 0xC3); // Telling LSP that we're playing a private match
|
||||
Utils::Hook::Nop(0x4FD448, 5); // Don't create lsp_socket
|
||||
|
||||
OnClientPacket("resolveAddress", [](const Address& address, [[maybe_unused]] const std::string& data)
|
||||
OnClientPacket("resolveAddress", []([[maybe_unused]] const Address& address, [[maybe_unused]] const std::string& data)
|
||||
{
|
||||
SendRaw(address, address.getString());
|
||||
});
|
||||
|
||||
OnClientPacket("print", []([[maybe_unused]] const Address& address, [[maybe_unused]] const std::string& data)
|
||||
{
|
||||
auto* clc = Game::CL_GetLocalClientConnection(0);
|
||||
if (!Game::NET_CompareBaseAdr(clc->serverAddress, *address.get()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[2048]{};
|
||||
|
||||
Game::I_strncpyz(clc->serverMessage, data.data(), sizeof(clc->serverMessage));
|
||||
Game::Com_sprintf(buffer, sizeof(buffer), "%s", data.data());
|
||||
Game::Com_PrintMessage(Game::CON_CHANNEL_CLIENT, buffer, 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ namespace Components
|
||||
typedef void(CallbackRaw)();
|
||||
|
||||
using networkCallback = std::function<void(Address&, const std::string&)>;
|
||||
using networkRawCallback = std::function<void(Game::netadr_t*, Game::msg_t* msg)>;
|
||||
|
||||
Network();
|
||||
|
||||
@ -73,17 +74,19 @@ namespace Components
|
||||
static void BroadcastAll(const std::string& data);
|
||||
|
||||
static void OnClientPacket(const std::string& command, const networkCallback& callback);
|
||||
static void OnClientPacketRaw(const std::string& command, const networkRawCallback& callback);
|
||||
|
||||
private:
|
||||
static Utils::Signal<CallbackRaw> StartupSignal;
|
||||
static std::unordered_map<std::string, networkCallback> CL_Callbacks;
|
||||
static std::unordered_map<std::string, networkRawCallback> CL_RawCallbacks;
|
||||
|
||||
static void NetworkStart();
|
||||
static void NetworkStartStub();
|
||||
|
||||
static void PacketErrorCheck();
|
||||
|
||||
static bool CL_HandleCommand(Game::netadr_t* address, const char* command, const Game::msg_t* message);
|
||||
static bool CL_HandleCommand(Game::netadr_t* address, const char* command, Game::msg_t* message);
|
||||
|
||||
static void CL_HandleCommandStub();
|
||||
};
|
||||
|
@ -110,12 +110,6 @@ namespace Components
|
||||
bool RCon::RateLimitCheck(const Network::Address& address, const int time)
|
||||
{
|
||||
const auto ip = address.getIP();
|
||||
|
||||
if (!RateLimit.contains(ip.full))
|
||||
{
|
||||
RateLimit[ip.full] = 0;
|
||||
}
|
||||
|
||||
const auto lastTime = RateLimit[ip.full];
|
||||
|
||||
if (lastTime && (time - lastTime) < RconTimeout.get<int>())
|
||||
|
@ -241,7 +241,7 @@ namespace Components
|
||||
void Voice::CL_WriteVoicePacket_Hk(const int localClientNum)
|
||||
{
|
||||
const auto connstate = Game::CL_GetLocalClientConnectionState(localClientNum);
|
||||
const auto clc = Game::CL_GetLocalClientConnection(localClientNum);
|
||||
const auto* clc = Game::CL_GetLocalClientConnection(localClientNum);
|
||||
const auto* vc = Game::CL_GetLocalClientVoiceCommunication(localClientNum);
|
||||
if (clc->demoplaying || (connstate < Game::CA_LOADING))
|
||||
{
|
||||
@ -315,8 +315,14 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
void Voice::CL_VoicePacket_Hk(const int localClientNum, Game::msg_t* msg)
|
||||
void Voice::CL_VoicePacket(Game::netadr_t* address, Game::msg_t* msg)
|
||||
{
|
||||
auto* clc = Game::CL_GetLocalClientConnection(0);
|
||||
if (!Game::NET_CompareBaseAdr(clc->serverAddress, *address))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto numPackets = Game::MSG_ReadByte(msg);
|
||||
if (numPackets < 0 || numPackets > MAX_SERVER_QUEUED_VOICE_PACKETS)
|
||||
{
|
||||
@ -342,7 +348,7 @@ namespace Components
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CL_IsPlayerMuted_Hk(nullptr, localClientNum, voicePacket.talker))
|
||||
if (!CL_IsPlayerMuted_Hk(nullptr, 0, voicePacket.talker))
|
||||
{
|
||||
if ((*Game::cl_voice)->current.enabled)
|
||||
{
|
||||
@ -395,7 +401,10 @@ namespace Components
|
||||
// Write voice packets to the server instead of other clients
|
||||
Utils::Hook(0x487935, CL_WriteVoicePacket_Hk, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x5AD945, CL_WriteVoicePacket_Hk, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x5A9E06, CL_VoicePacket_Hk, HOOK_CALL).install()->quick();
|
||||
|
||||
// Disable 'v' OOB handler and use our own
|
||||
Utils::Hook::Set<std::uint8_t>(0x5A9E02, 0xEB);
|
||||
Network::OnClientPacketRaw("v", CL_VoicePacket);
|
||||
|
||||
Utils::Hook(0x4AE740, CL_IsPlayerTalking_Hk, HOOK_JUMP).install()->quick();
|
||||
Utils::Hook(0x4B6250, CL_IsPlayerMuted_Hk, HOOK_JUMP).install()->quick();
|
||||
|
@ -46,7 +46,7 @@ namespace Components
|
||||
static void CL_TogglePlayerMute(int localClientNum, int muteClientIndex);
|
||||
|
||||
static void CL_WriteVoicePacket_Hk(int localClientNum);
|
||||
static void CL_VoicePacket_Hk(int localClientNum, Game::msg_t* msg);
|
||||
static void CL_VoicePacket(Game::netadr_t* address, Game::msg_t* msg);
|
||||
|
||||
static void UI_Mute_player(int clientNum, int localClientNum);
|
||||
static void UI_Mute_Player_Stub();
|
||||
|
@ -12,6 +12,7 @@ namespace Game
|
||||
Com_PrintError_t Com_PrintError = Com_PrintError_t(0x4F8C70);
|
||||
Com_PrintWarning_t Com_PrintWarning = Com_PrintWarning_t(0x4E0200);
|
||||
Com_PrintMessage_t Com_PrintMessage = Com_PrintMessage_t(0x4AA830);
|
||||
Com_sprintf_t Com_sprintf = Com_sprintf_t(0x413DE0);
|
||||
Com_EndParseSession_t Com_EndParseSession = Com_EndParseSession_t(0x4B80B0);
|
||||
Com_BeginParseSession_t Com_BeginParseSession = Com_BeginParseSession_t(0x4AAB80);
|
||||
Com_ParseOnLine_t Com_ParseOnLine = Com_ParseOnLine_t(0x4C0350);
|
||||
|
@ -29,6 +29,9 @@ namespace Game
|
||||
typedef void(*Com_PrintMessage_t)(int channel, const char* msg, int error);
|
||||
extern Com_PrintMessage_t Com_PrintMessage;
|
||||
|
||||
typedef int(*Com_sprintf_t)(char* dest, int size, const char* fmt, ...);
|
||||
extern Com_sprintf_t Com_sprintf;
|
||||
|
||||
typedef void(*Com_EndParseSession_t)();
|
||||
extern Com_EndParseSession_t Com_EndParseSession;
|
||||
|
||||
|
@ -109,6 +109,7 @@ namespace Game
|
||||
|
||||
NET_AdrToString_t NET_AdrToString = NET_AdrToString_t(0x469880);
|
||||
NET_CompareAdr_t NET_CompareAdr = NET_CompareAdr_t(0x4D0AA0);
|
||||
NET_CompareBaseAdr_t NET_CompareBaseAdr = NET_CompareBaseAdr_t(0x455510);
|
||||
NET_DeferPacketToClient_t NET_DeferPacketToClient = NET_DeferPacketToClient_t(0x4C8AA0);
|
||||
NET_ErrorString_t NET_ErrorString = NET_ErrorString_t(0x4E7720);
|
||||
NET_Init_t NET_Init = NET_Init_t(0x491860);
|
||||
|
@ -269,12 +269,15 @@ namespace Game
|
||||
typedef void(*NetadrToSockadr_t)(netadr_t *a, sockaddr *s);
|
||||
extern NetadrToSockadr_t NetadrToSockadr;
|
||||
|
||||
typedef const char* (*NET_AdrToString_t)(netadr_t adr);
|
||||
typedef const char*(*NET_AdrToString_t)(netadr_t adr);
|
||||
extern NET_AdrToString_t NET_AdrToString;
|
||||
|
||||
typedef bool(*NET_CompareAdr_t)(netadr_t a, netadr_t b);
|
||||
extern NET_CompareAdr_t NET_CompareAdr;
|
||||
|
||||
typedef int(*NET_CompareBaseAdr_t)(netadr_t a, netadr_t b);
|
||||
extern NET_CompareBaseAdr_t NET_CompareBaseAdr;
|
||||
|
||||
typedef void(*NET_DeferPacketToClient_t)(netadr_t*, msg_t*);
|
||||
extern NET_DeferPacketToClient_t NET_DeferPacketToClient;
|
||||
|
||||
|
@ -8,7 +8,7 @@ namespace Utils::String
|
||||
const char* VA(const char* fmt, ...)
|
||||
{
|
||||
static VAProvider<4, 256> globalProvider;
|
||||
static thread_local VAProvider<8, 1024> provider;
|
||||
static thread_local VAProvider<8, 256> provider;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
Loading…
Reference in New Issue
Block a user