Implement the stuff B3 needs.
This commit is contained in:
parent
69db2c0734
commit
3b8e47fecc
@ -4,6 +4,7 @@ namespace Components
|
||||
{
|
||||
std::vector<Game::cmd_function_t*> Command::Functions;
|
||||
std::map<std::string, wink::slot<Command::Callback>> Command::FunctionMap;
|
||||
std::map<std::string, wink::slot<Command::Callback>> Command::FunctionMapSV;
|
||||
|
||||
char* Command::Params::operator[](size_t index)
|
||||
{
|
||||
@ -12,12 +13,26 @@ namespace Components
|
||||
return "";
|
||||
}
|
||||
|
||||
return Game::cmd_argv[this->CommandId][index];
|
||||
if (this->IsSV)
|
||||
{
|
||||
return Game::cmd_argv_sv[this->CommandId][index];
|
||||
}
|
||||
else
|
||||
{
|
||||
return Game::cmd_argv[this->CommandId][index];
|
||||
}
|
||||
}
|
||||
|
||||
size_t Command::Params::Length()
|
||||
{
|
||||
return Game::cmd_argc[this->CommandId];
|
||||
if (this->IsSV)
|
||||
{
|
||||
return Game::cmd_argc_sv[this->CommandId];
|
||||
}
|
||||
else
|
||||
{
|
||||
return Game::cmd_argc[this->CommandId];
|
||||
}
|
||||
}
|
||||
|
||||
std::string Command::Params::Join(size_t startIndex)
|
||||
@ -39,6 +54,28 @@ namespace Components
|
||||
Game::Cmd_AddCommand(name, Command::MainCallback, Command::Allocate(), 0);
|
||||
}
|
||||
|
||||
void Command::AddSV(const char* name, Command::Callback* callback)
|
||||
{
|
||||
Command::FunctionMapSV[Utils::StrToLower(name)] = callback;
|
||||
Game::Cmd_AddServerCommand(name, Command::MainCallbackSV, Command::Allocate());
|
||||
|
||||
// If the main command is registered as Cbuf_AddServerText, the command will be redirected to the SV handler
|
||||
Command::AddRaw(name, Game::Cbuf_AddServerText);
|
||||
}
|
||||
|
||||
void Command::AddRaw(const char* name, void(*callback)())
|
||||
{
|
||||
Game::Cmd_AddCommand(name, callback, Command::Allocate(), 0);
|
||||
}
|
||||
|
||||
void Command::AddRawSV(const char* name, void(*callback)())
|
||||
{
|
||||
Game::Cmd_AddServerCommand(name, callback, Command::Allocate());
|
||||
|
||||
// If the main command is registered as Cbuf_AddServerText, the command will be redirected to the SV handler
|
||||
Command::AddRaw(name, Game::Cbuf_AddServerText);
|
||||
}
|
||||
|
||||
void Command::Execute(std::string command, bool sync)
|
||||
{
|
||||
command.append("\n"); // Make sure it's terminated
|
||||
@ -63,7 +100,7 @@ namespace Components
|
||||
|
||||
void Command::MainCallback()
|
||||
{
|
||||
Command::Params params(*Game::cmd_id);
|
||||
Command::Params params(false, *Game::cmd_id);
|
||||
|
||||
std::string command = Utils::StrToLower(params[0]);
|
||||
|
||||
@ -73,6 +110,18 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
void Command::MainCallbackSV()
|
||||
{
|
||||
Command::Params params(true, *Game::cmd_id_sv);
|
||||
|
||||
std::string command = Utils::StrToLower(params[0]);
|
||||
|
||||
if (Command::FunctionMapSV.find(command) != Command::FunctionMapSV.end())
|
||||
{
|
||||
Command::FunctionMapSV[command](params);
|
||||
}
|
||||
}
|
||||
|
||||
Command::Command()
|
||||
{
|
||||
// TODO: Add commands here?
|
||||
@ -86,5 +135,7 @@ namespace Components
|
||||
}
|
||||
|
||||
Command::Functions.clear();
|
||||
Command::FunctionMap.clear();
|
||||
Command::FunctionMapSV.clear();
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,9 @@ namespace Components
|
||||
class Params
|
||||
{
|
||||
public:
|
||||
Params(DWORD id) : CommandId(id) {};
|
||||
Params(const Params &obj) { this->CommandId = obj.CommandId; };
|
||||
Params() : Params(*Game::cmd_id) {};
|
||||
Params(bool sv, DWORD id) : CommandId(id), IsSV(sv) {};
|
||||
Params(const Params &obj) : CommandId(obj.CommandId), IsSV(obj.IsSV) {};
|
||||
Params() : Params(false, *Game::cmd_id) {};
|
||||
|
||||
char* operator[](size_t index);
|
||||
size_t Length();
|
||||
@ -16,6 +16,7 @@ namespace Components
|
||||
std::string Join(size_t startIndex);
|
||||
|
||||
private:
|
||||
bool IsSV;
|
||||
DWORD CommandId;
|
||||
};
|
||||
|
||||
@ -26,12 +27,17 @@ namespace Components
|
||||
const char* GetName() { return "Command"; };
|
||||
|
||||
static void Add(const char* name, Callback* callback);
|
||||
static void AddSV(const char* name, Callback* callback);
|
||||
static void AddRaw(const char* name, void(*callback)());
|
||||
static void AddRawSV(const char* name, void(*callback)());
|
||||
static void Execute(std::string command, bool sync = true);
|
||||
|
||||
private:
|
||||
static Game::cmd_function_t* Allocate();
|
||||
static std::vector<Game::cmd_function_t*> Functions;
|
||||
static std::map<std::string, wink::slot<Callback>> FunctionMap;
|
||||
static std::map<std::string, wink::slot<Callback>> FunctionMapSV;
|
||||
static void MainCallback();
|
||||
static void MainCallbackSV();
|
||||
};
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ namespace Components
|
||||
wink::signal<wink::slot<Dedicated::Callback>> Dedicated::FrameSignal;
|
||||
wink::signal<wink::slot<Dedicated::Callback>> Dedicated::FrameOnceSignal;
|
||||
|
||||
bool Dedicated::SendChat;
|
||||
|
||||
bool Dedicated::IsDedicated()
|
||||
{
|
||||
return Flags::HasFlag("dedicated");
|
||||
@ -58,6 +60,62 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
const char* Dedicated::EvaluateSay(char* text)
|
||||
{
|
||||
Dedicated::SendChat = true;
|
||||
|
||||
if (text[1] == '/')
|
||||
{
|
||||
Dedicated::SendChat = false;
|
||||
text[1] = text[0];
|
||||
++text;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
void __declspec(naked) Dedicated::PreSayStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, [esp + 100h + 10h]
|
||||
|
||||
push eax
|
||||
call EvaluateSay
|
||||
add esp, 4h
|
||||
|
||||
mov [esp + 100h + 10h], eax
|
||||
|
||||
jmp Colors::CleanStrStub
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) Dedicated::PostSayStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
// eax is used by the callee
|
||||
push eax
|
||||
|
||||
xor eax, eax
|
||||
mov al, Dedicated::SendChat
|
||||
|
||||
test al, al
|
||||
jnz return
|
||||
|
||||
// Don't send the chat
|
||||
pop eax
|
||||
retn
|
||||
|
||||
return:
|
||||
pop eax
|
||||
|
||||
// Jump to the target
|
||||
push 5DF620h
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
void Dedicated::MapRotate()
|
||||
{
|
||||
if (!Dedicated::IsDedicated() && Dvar::Var("sv_dontrotate").Get<bool>())
|
||||
@ -228,6 +286,11 @@ namespace Components
|
||||
// Dedicated frame handler
|
||||
Utils::Hook(0x4B0F81, Dedicated::FrameStub, HOOK_CALL).Install()->Quick();
|
||||
|
||||
// Intercept chat sending
|
||||
Utils::Hook(0x4D000B, Dedicated::PreSayStub, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x4D00D4, Dedicated::PostSayStub, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x4D0110, Dedicated::PostSayStub, HOOK_CALL).Install()->Quick();
|
||||
|
||||
if (!ZoneBuilder::IsEnabled())
|
||||
{
|
||||
// Post initialization point
|
||||
@ -248,6 +311,93 @@ namespace Components
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
Dvar::OnInit([] ()
|
||||
{
|
||||
Dvar::Register<const char*>("sv_sayName", "^7Console", Game::dvar_flag::DVAR_FLAG_NONE, "The name to pose as for 'say' commands");
|
||||
|
||||
// Say command
|
||||
Command::AddSV("say", [] (Command::Params params)
|
||||
{
|
||||
if (params.Length() < 2) return;
|
||||
|
||||
std::string message = params.Join(1);
|
||||
std::string name = Dvar::Var("sv_sayName").Get<std::string>();
|
||||
|
||||
if (!name.empty())
|
||||
{
|
||||
Game::SV_GameSendServerCommand(-1, 0, Utils::VA("%c \"%s: %s\"", 104, name.data(), message.data()));
|
||||
Game::Com_Printf(15, "%s: %s\n", name.data(), message.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::SV_GameSendServerCommand(-1, 0, Utils::VA("%c \"Console: %s\"", 104, message.data()));
|
||||
Game::Com_Printf(15, "Console: %s\n", message.data());
|
||||
}
|
||||
});
|
||||
|
||||
// Tell command
|
||||
Command::AddSV("tell", [] (Command::Params params)
|
||||
{
|
||||
if (params.Length() < 3) return;
|
||||
|
||||
int client = atoi(params[1]);
|
||||
std::string message = params.Join(2);
|
||||
std::string name = Dvar::Var("sv_sayName").Get<std::string>();
|
||||
|
||||
if (!name.empty())
|
||||
{
|
||||
Game::SV_GameSendServerCommand(client, 0, Utils::VA("%c \"%s: %s\"", 104, name.data(), message.data()));
|
||||
Game::Com_Printf(15, "%s -> %i: %s\n", name.data(), client, message.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::SV_GameSendServerCommand(client, 0, Utils::VA("%c \"Console: %s\"", 104, message.data()));
|
||||
Game::Com_Printf(15, "Console -> %i: %s\n", client, message.data());
|
||||
}
|
||||
});
|
||||
|
||||
// Sayraw command
|
||||
Command::AddSV("sayraw", [] (Command::Params params)
|
||||
{
|
||||
if (params.Length() < 2) return;
|
||||
|
||||
std::string message = params.Join(1);
|
||||
Game::SV_GameSendServerCommand(-1, 0, Utils::VA("%c \"%s\"", 104, message.data()));
|
||||
Game::Com_Printf(15, "Raw: %s\n", message.data());
|
||||
});
|
||||
|
||||
// Tellraw command
|
||||
Command::AddSV("tellraw", [] (Command::Params params)
|
||||
{
|
||||
if (params.Length() < 3) return;
|
||||
|
||||
int client = atoi(params[1]);
|
||||
std::string message = params.Join(2);
|
||||
Game::SV_GameSendServerCommand(client, 0, Utils::VA("%c \"%s\"", 104, message.data()));
|
||||
Game::Com_Printf(15, "Raw -> %i: %s\n", client, message.data());
|
||||
});
|
||||
|
||||
// ! command
|
||||
Command::AddSV("!", [] (Command::Params params)
|
||||
{
|
||||
if (params.Length() != 2) return;
|
||||
|
||||
int client = -1;
|
||||
if (std::string(params[1]) != "all")
|
||||
{
|
||||
client = atoi(params[1]);
|
||||
|
||||
if (client >= *reinterpret_cast<int*>(0x31D938C))
|
||||
{
|
||||
Game::Com_Printf(0, "Invalid player.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Game::SV_GameSendServerCommand(client, 0, Utils::VA("%c \"\"", 106));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,18 @@ namespace Components
|
||||
static wink::signal<wink::slot<Callback>> FrameSignal;
|
||||
static wink::signal<wink::slot<Callback>> FrameOnceSignal;
|
||||
|
||||
static bool SendChat;
|
||||
|
||||
static void MapRotate();
|
||||
static void FrameStub();
|
||||
static void InitDedicatedServer();
|
||||
|
||||
static void PostInitialization();
|
||||
static void PostInitializationStub();
|
||||
|
||||
static const char* EvaluateSay(char* text);
|
||||
|
||||
static void PreSayStub();
|
||||
static void PostSayStub();
|
||||
};
|
||||
}
|
||||
|
@ -88,6 +88,8 @@ namespace Components
|
||||
Utils::Hook::Set<void*>(0x4D90B7, Maps::WorldMP);
|
||||
}
|
||||
|
||||
AntiCheat::EmptyHash();
|
||||
|
||||
_snprintf(buffer, size, format, mapname);
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ namespace Game
|
||||
// C-Style casts are fine here, that's where we're doing our dirty stuff anyways...
|
||||
BG_LoadWeaponDef_LoadObj_t BG_LoadWeaponDef_LoadObj = (BG_LoadWeaponDef_LoadObj_t)0x57B5F0;
|
||||
|
||||
Cbuf_AddServerText_t Cbuf_AddServerText = (Cbuf_AddServerText_t)0x4BB9B0;
|
||||
Cbuf_AddText_t Cbuf_AddText = (Cbuf_AddText_t)0x404B20;
|
||||
|
||||
CL_GetClientName_t CL_GetClientName = (CL_GetClientName_t)0x4563D0;
|
||||
@ -12,6 +13,7 @@ namespace Game
|
||||
CL_ConnectFromParty_t CL_ConnectFromParty = (CL_ConnectFromParty_t)0x433D30;
|
||||
|
||||
Cmd_AddCommand_t Cmd_AddCommand = (Cmd_AddCommand_t)0x470090;
|
||||
Cmd_AddServerCommand_t Cmd_AddServerCommand = (Cmd_AddServerCommand_t)0x4DCE00;
|
||||
Cmd_ExecuteSingleCommand_t Cmd_ExecuteSingleCommand = (Cmd_ExecuteSingleCommand_t)0x609540;
|
||||
|
||||
Com_Error_t Com_Error = (Com_Error_t)0x4B22D0;
|
||||
@ -130,6 +132,7 @@ namespace Game
|
||||
Steam_JoinLobby_t Steam_JoinLobby = (Steam_JoinLobby_t)0x49CF70;
|
||||
|
||||
SV_GameClientNum_Score_t SV_GameClientNum_Score = (SV_GameClientNum_Score_t)0x469AC0;
|
||||
SV_GameSendServerCommand_t SV_GameSendServerCommand = (SV_GameSendServerCommand_t)0x4BC3A0;
|
||||
|
||||
Sys_IsMainThread_t Sys_IsMainThread = (Sys_IsMainThread_t)0x4C37D0;
|
||||
Sys_SendPacket_t Sys_SendPacket = (Sys_SendPacket_t)0x60FDC0;
|
||||
@ -147,6 +150,10 @@ namespace Game
|
||||
DWORD* cmd_argc = (DWORD*)0x1AAC614;
|
||||
char*** cmd_argv = (char***)0x1AAC634;
|
||||
|
||||
DWORD* cmd_id_sv = (DWORD*)0x1ACF8A0;
|
||||
DWORD* cmd_argc_sv = (DWORD*)0x1ACF8E4;
|
||||
char*** cmd_argv_sv = (char***)0x1ACF904;
|
||||
|
||||
source_t **sourceFiles = (source_t **)0x7C4A98;
|
||||
keywordHash_t **menuParseKeywordHash = (keywordHash_t **)0x63AE928;
|
||||
|
||||
|
@ -3,6 +3,9 @@ namespace Game
|
||||
typedef void*(__cdecl * BG_LoadWeaponDef_LoadObj_t)(const char* filename);
|
||||
extern BG_LoadWeaponDef_LoadObj_t BG_LoadWeaponDef_LoadObj;
|
||||
|
||||
typedef void(__cdecl * Cbuf_AddServerText_t)();
|
||||
extern Cbuf_AddServerText_t Cbuf_AddServerText;
|
||||
|
||||
typedef void(__cdecl * Cbuf_AddText_t)(int localClientNum, const char *text);
|
||||
extern Cbuf_AddText_t Cbuf_AddText;
|
||||
|
||||
@ -18,6 +21,9 @@ namespace Game
|
||||
typedef void(__cdecl * Cmd_AddCommand_t)(const char* name, void(*callback), cmd_function_t* data, char);
|
||||
extern Cmd_AddCommand_t Cmd_AddCommand;
|
||||
|
||||
typedef void(__cdecl * Cmd_AddServerCommand_t)(const char* name, void(*callback), cmd_function_t* data);
|
||||
extern Cmd_AddServerCommand_t Cmd_AddServerCommand;
|
||||
|
||||
typedef void(__cdecl * Cmd_ExecuteSingleCommand_t)(int controller, int a2, const char* cmd);
|
||||
extern Cmd_ExecuteSingleCommand_t Cmd_ExecuteSingleCommand;
|
||||
|
||||
@ -302,6 +308,9 @@ namespace Game
|
||||
typedef int(__cdecl* SV_GameClientNum_Score_t)(int clientID);
|
||||
extern SV_GameClientNum_Score_t SV_GameClientNum_Score;
|
||||
|
||||
typedef void(__cdecl * SV_GameSendServerCommand_t)(int clientNum, /*svscmd_type*/int type, const char* text);
|
||||
extern SV_GameSendServerCommand_t SV_GameSendServerCommand;
|
||||
|
||||
typedef bool(__cdecl * Sys_IsMainThread_t)();
|
||||
extern Sys_IsMainThread_t Sys_IsMainThread;
|
||||
|
||||
@ -327,6 +336,10 @@ namespace Game
|
||||
extern DWORD* cmd_argc;
|
||||
extern char*** cmd_argv;
|
||||
|
||||
extern DWORD* cmd_id_sv;
|
||||
extern DWORD* cmd_argc_sv;
|
||||
extern char*** cmd_argv_sv;
|
||||
|
||||
extern int* svs_numclients;
|
||||
extern client_t* svs_clients;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user