[Events] Group game events callbacks in one module (#306)
This commit is contained in:
parent
e754e9d56a
commit
0a852c6431
3
.github/CODEOWNERS
vendored
Normal file
3
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-3.0
|
||||||
|
|
||||||
|
* @XLabsProject/Developers
|
@ -112,6 +112,7 @@ namespace Components
|
|||||||
Loader::Register(new MapRotation());
|
Loader::Register(new MapRotation());
|
||||||
Loader::Register(new Ceg());
|
Loader::Register(new Ceg());
|
||||||
Loader::Register(new UserInfo());
|
Loader::Register(new UserInfo());
|
||||||
|
Loader::Register(new Events());
|
||||||
|
|
||||||
Loader::Pregame = false;
|
Loader::Pregame = false;
|
||||||
}
|
}
|
||||||
|
@ -143,3 +143,4 @@ namespace Components
|
|||||||
#include "Modules/MapRotation.hpp"
|
#include "Modules/MapRotation.hpp"
|
||||||
#include "Modules/Ceg.hpp"
|
#include "Modules/Ceg.hpp"
|
||||||
#include "Modules/UserInfo.hpp"
|
#include "Modules/UserInfo.hpp"
|
||||||
|
#include "Modules/Events.hpp"
|
||||||
|
@ -309,21 +309,6 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Should be called when a client drops from the server
|
|
||||||
* but not "between levels" (Quake-III-Arena)
|
|
||||||
*/
|
|
||||||
void Bots::ClientDisconnect_Hk(const int clientNum)
|
|
||||||
{
|
|
||||||
g_botai[clientNum].active = false;
|
|
||||||
|
|
||||||
// Clear the overrides for UserInfo
|
|
||||||
UserInfo::ClearClientOverrides(clientNum);
|
|
||||||
|
|
||||||
// Call original function
|
|
||||||
Utils::Hook::Call<void(int)>(0x4AA430)(clientNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bots::Bots()
|
Bots::Bots()
|
||||||
{
|
{
|
||||||
AssertOffset(Game::client_s, bIsTestClient, 0x41AF0);
|
AssertOffset(Game::client_s, bIsTestClient, 0x41AF0);
|
||||||
@ -340,7 +325,10 @@ namespace Components
|
|||||||
Utils::Hook(0x441B80, Bots::G_SelectWeaponIndex_Hk, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x441B80, Bots::G_SelectWeaponIndex_Hk, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
// Reset BotMovementInfo.active when client is dropped
|
// Reset BotMovementInfo.active when client is dropped
|
||||||
Utils::Hook(0x625235, Bots::ClientDisconnect_Hk, HOOK_CALL).install()->quick();
|
Events::OnClientDisconnect([](const int clientNum)
|
||||||
|
{
|
||||||
|
g_botai[clientNum].active = false;
|
||||||
|
});
|
||||||
|
|
||||||
// Zero the bot command array
|
// Zero the bot command array
|
||||||
for (auto i = 0u; i < std::extent_v<decltype(g_botai)>; i++)
|
for (auto i = 0u; i < std::extent_v<decltype(g_botai)>; i++)
|
||||||
@ -393,9 +381,9 @@ namespace Components
|
|||||||
Bots::AddMethods();
|
Bots::AddMethods();
|
||||||
|
|
||||||
// In case a loaded mod didn't call "BotStop" before the VM shutdown
|
// In case a loaded mod didn't call "BotStop" before the VM shutdown
|
||||||
Script::OnVMShutdown([]
|
Events::OnVMShutdown([]
|
||||||
{
|
{
|
||||||
for (auto i = 0u; i < std::extent_v<decltype(g_botai)>; i++)
|
for (std::size_t i = 0; i < std::extent_v<decltype(g_botai)>; i++)
|
||||||
{
|
{
|
||||||
g_botai[i].active = false;
|
g_botai[i].active = false;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,5 @@ namespace Components
|
|||||||
|
|
||||||
static void G_SelectWeaponIndex(int clientNum, int iWeaponIndex);
|
static void G_SelectWeaponIndex(int clientNum, int iWeaponIndex);
|
||||||
static void G_SelectWeaponIndex_Hk();
|
static void G_SelectWeaponIndex_Hk();
|
||||||
|
|
||||||
static void ClientDisconnect_Hk(int clientNum);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -961,7 +961,7 @@ namespace Components
|
|||||||
|
|
||||||
}, Scheduler::Pipeline::MAIN);
|
}, Scheduler::Pipeline::MAIN);
|
||||||
|
|
||||||
Script::OnVMShutdown([]()
|
Events::OnVMShutdown([]()
|
||||||
{
|
{
|
||||||
Download::ScriptDownloads.clear();
|
Download::ScriptDownloads.clear();
|
||||||
});
|
});
|
||||||
|
@ -377,6 +377,9 @@ namespace Components
|
|||||||
|
|
||||||
// If the game closed abruptly, the dvars would not have been restored
|
// If the game closed abruptly, the dvars would not have been restored
|
||||||
Scheduler::Once(Dvar::ResetDvarsValue, Scheduler::Pipeline::MAIN);
|
Scheduler::Once(Dvar::ResetDvarsValue, Scheduler::Pipeline::MAIN);
|
||||||
|
|
||||||
|
// Reset archive dvars when client leaves a server
|
||||||
|
Events::OnSteamDisconnect(Dvar::ResetDvarsValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dvar::~Dvar()
|
Dvar::~Dvar()
|
||||||
|
58
src/Components/Modules/Events.cpp
Normal file
58
src/Components/Modules/Events.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include <STDInclude.hpp>
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
Utils::Signal<Events::ClientCallback> Events::ClientDisconnectSignal;
|
||||||
|
Utils::Signal<Events::Callback> Events::SteamDisconnectSignal;
|
||||||
|
Utils::Signal<Events::Callback> Events::ShutdownSystemSignal;
|
||||||
|
|
||||||
|
void Events::OnClientDisconnect(const Utils::Slot<ClientCallback>& callback)
|
||||||
|
{
|
||||||
|
ClientDisconnectSignal.connect(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::OnSteamDisconnect(const Utils::Slot<Callback>& callback)
|
||||||
|
{
|
||||||
|
SteamDisconnectSignal.connect(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::OnVMShutdown(const Utils::Slot<Callback>& callback)
|
||||||
|
{
|
||||||
|
ShutdownSystemSignal.connect(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should be called when a client drops from the server
|
||||||
|
* but not "between levels" (Quake-III-Arena)
|
||||||
|
*/
|
||||||
|
void Events::ClientDisconnect_Hk(const int clientNum)
|
||||||
|
{
|
||||||
|
ClientDisconnectSignal(clientNum);
|
||||||
|
|
||||||
|
Utils::Hook::Call<void(int)>(0x4AA430)(clientNum); // ClientDisconnect
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::SteamDisconnect_Hk()
|
||||||
|
{
|
||||||
|
SteamDisconnectSignal();
|
||||||
|
|
||||||
|
Utils::Hook::Call<void()>(0x467CC0)(); // LiveSteam_Client_SteamDisconnect
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::Scr_ShutdownSystem_Hk(unsigned char sys)
|
||||||
|
{
|
||||||
|
ShutdownSystemSignal();
|
||||||
|
|
||||||
|
Utils::Hook::Call<void(unsigned char)>(0x421EE0)(sys); // Scr_ShutdownSystem
|
||||||
|
}
|
||||||
|
|
||||||
|
Events::Events()
|
||||||
|
{
|
||||||
|
Utils::Hook(0x625235, ClientDisconnect_Hk, HOOK_CALL).install()->quick(); // SV_FreeClient
|
||||||
|
|
||||||
|
Utils::Hook(0x403582, SteamDisconnect_Hk, HOOK_CALL).install()->quick(); // CL_Disconnect
|
||||||
|
|
||||||
|
Utils::Hook(0x47548B, Scr_ShutdownSystem_Hk, HOOK_CALL).install()->quick(); // G_LoadGame
|
||||||
|
Utils::Hook(0x4D06BA, Scr_ShutdownSystem_Hk, HOOK_CALL).install()->quick(); // G_ShutdownGame
|
||||||
|
}
|
||||||
|
}
|
30
src/Components/Modules/Events.hpp
Normal file
30
src/Components/Modules/Events.hpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
class Events : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef void(ClientCallback)(int clientNum);
|
||||||
|
typedef void(Callback)();
|
||||||
|
|
||||||
|
Events();
|
||||||
|
|
||||||
|
// Server side
|
||||||
|
static void OnClientDisconnect(const Utils::Slot<ClientCallback>& callback);
|
||||||
|
|
||||||
|
// Client side
|
||||||
|
static void OnSteamDisconnect(const Utils::Slot<Callback>& callback);
|
||||||
|
|
||||||
|
static void OnVMShutdown(const Utils::Slot<Callback>& callback);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Utils::Signal<ClientCallback> ClientDisconnectSignal;
|
||||||
|
static Utils::Signal<Callback> SteamDisconnectSignal;
|
||||||
|
static Utils::Signal<Callback> ShutdownSystemSignal;
|
||||||
|
|
||||||
|
static void ClientDisconnect_Hk(int clientNum);
|
||||||
|
static void SteamDisconnect_Hk();
|
||||||
|
static void Scr_ShutdownSystem_Hk(unsigned char sys);
|
||||||
|
};
|
||||||
|
}
|
@ -457,22 +457,6 @@ namespace Components
|
|||||||
Friends::CurrentFriend = index;
|
Friends::CurrentFriend = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) void Friends::DisconnectStub()
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
pushad
|
|
||||||
|
|
||||||
call Friends::ClearServer
|
|
||||||
call Dvar::ResetDvarsValue
|
|
||||||
|
|
||||||
popad
|
|
||||||
|
|
||||||
push 467CC0h
|
|
||||||
retn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Friends::AddFriend(SteamID user)
|
void Friends::AddFriend(SteamID user)
|
||||||
{
|
{
|
||||||
if (Steam::Proxy::ClientFriends && Steam::Proxy::SteamFriends)
|
if (Steam::Proxy::ClientFriends && Steam::Proxy::SteamFriends)
|
||||||
@ -622,7 +606,8 @@ namespace Components
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Update state when connecting/disconnecting
|
// Update state when connecting/disconnecting
|
||||||
Utils::Hook(0x403582, Friends::DisconnectStub, HOOK_CALL).install()->quick();
|
Events::OnSteamDisconnect(Friends::ClearServer);
|
||||||
|
|
||||||
Utils::Hook(0x4CD023, Friends::SetServer, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x4CD023, Friends::SetServer, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
// Show blue icons on the minimap
|
// Show blue icons on the minimap
|
||||||
|
@ -77,7 +77,6 @@ namespace Components
|
|||||||
static std::recursive_mutex Mutex;
|
static std::recursive_mutex Mutex;
|
||||||
static std::vector<Friend> FriendsList;
|
static std::vector<Friend> FriendsList;
|
||||||
|
|
||||||
static void DisconnectStub();
|
|
||||||
static void ClearServer();
|
static void ClearServer();
|
||||||
static void SetServer();
|
static void SetServer();
|
||||||
|
|
||||||
|
@ -14,8 +14,6 @@ namespace Components
|
|||||||
const char* Script::ReplacedPos = nullptr;
|
const char* Script::ReplacedPos = nullptr;
|
||||||
int Script::LastFrameTime = -1;
|
int Script::LastFrameTime = -1;
|
||||||
|
|
||||||
Utils::Signal<Script::Callback> Script::VMShutdownSignal;
|
|
||||||
|
|
||||||
void Script::FunctionError()
|
void Script::FunctionError()
|
||||||
{
|
{
|
||||||
const auto* funcName = Game::SL_ConvertToString(Script::FunctionName);
|
const auto* funcName = Game::SL_ConvertToString(Script::FunctionName);
|
||||||
@ -411,20 +409,6 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::OnVMShutdown(Utils::Slot<Script::Callback> callback)
|
|
||||||
{
|
|
||||||
Script::ScriptBaseProgramNum.clear();
|
|
||||||
Script::VMShutdownSignal.connect(std::move(callback));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Script::ScrShutdownSystemStub(unsigned char sys)
|
|
||||||
{
|
|
||||||
Script::VMShutdownSignal();
|
|
||||||
|
|
||||||
// Scr_ShutdownSystem
|
|
||||||
Utils::Hook::Call<void(unsigned char)>(0x421EE0)(sys);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Script::SetExpFogStub()
|
unsigned int Script::SetExpFogStub()
|
||||||
{
|
{
|
||||||
if (Game::Scr_GetNumParam() == 6u)
|
if (Game::Scr_GetNumParam() == 6u)
|
||||||
@ -715,9 +699,6 @@ namespace Components
|
|||||||
Utils::Hook(0x61E92E, Script::VMExecuteInternalStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x61E92E, Script::VMExecuteInternalStub, HOOK_JUMP).install()->quick();
|
||||||
Utils::Hook::Nop(0x61E933, 1);
|
Utils::Hook::Nop(0x61E933, 1);
|
||||||
|
|
||||||
Utils::Hook(0x47548B, Script::ScrShutdownSystemStub, HOOK_CALL).install()->quick(); // G_LoadGame
|
|
||||||
Utils::Hook(0x4D06BA, Script::ScrShutdownSystemStub, HOOK_CALL).install()->quick(); // G_ShutdownGame
|
|
||||||
|
|
||||||
Scheduler::Loop([]()
|
Scheduler::Loop([]()
|
||||||
{
|
{
|
||||||
if (!Game::SV_Loaded())
|
if (!Game::SV_Loaded())
|
||||||
@ -753,14 +734,9 @@ namespace Components
|
|||||||
|
|
||||||
Script::AddFunctions();
|
Script::AddFunctions();
|
||||||
|
|
||||||
Script::OnVMShutdown([]
|
Events::OnVMShutdown([]
|
||||||
{
|
{
|
||||||
Script::ReplacedFunctions.clear();
|
Script::ReplacedFunctions.clear();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Script::~Script()
|
|
||||||
{
|
|
||||||
Script::VMShutdownSignal.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,12 @@ namespace Components
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Script();
|
Script();
|
||||||
~Script();
|
|
||||||
|
|
||||||
typedef void(Callback)();
|
|
||||||
|
|
||||||
static int LoadScriptAndLabel(const std::string& script, const std::string& label);
|
static int LoadScriptAndLabel(const std::string& script, const std::string& label);
|
||||||
|
|
||||||
static void AddFunction(const char* name, Game::BuiltinFunction func, int type = 0);
|
static void AddFunction(const char* name, Game::BuiltinFunction func, int type = 0);
|
||||||
static void AddMethod(const char* name, Game::BuiltinMethod func, int type = 0);
|
static void AddMethod(const char* name, Game::BuiltinMethod func, int type = 0);
|
||||||
|
|
||||||
static void OnVMShutdown(Utils::Slot<Script::Callback> callback);
|
|
||||||
|
|
||||||
static Game::client_t* GetClient(const Game::gentity_t* gentity);
|
static Game::client_t* GetClient(const Game::gentity_t* gentity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -33,8 +28,6 @@ namespace Components
|
|||||||
static const char* ReplacedPos;
|
static const char* ReplacedPos;
|
||||||
static int LastFrameTime;
|
static int LastFrameTime;
|
||||||
|
|
||||||
static Utils::Signal<Script::Callback> VMShutdownSignal;
|
|
||||||
|
|
||||||
static void CompileError(unsigned int offset, const char* message, ...);
|
static void CompileError(unsigned int offset, const char* message, ...);
|
||||||
static void PrintSourcePos(const char* filename, unsigned int offset);
|
static void PrintSourcePos(const char* filename, unsigned int offset);
|
||||||
|
|
||||||
@ -54,7 +47,6 @@ namespace Components
|
|||||||
static Game::BuiltinFunction BuiltIn_GetFunctionStub(const char** pName, int* type);
|
static Game::BuiltinFunction BuiltIn_GetFunctionStub(const char** pName, int* type);
|
||||||
static Game::BuiltinMethod BuiltIn_GetMethod(const char** pName, int* type);
|
static Game::BuiltinMethod BuiltIn_GetMethod(const char** pName, int* type);
|
||||||
|
|
||||||
static void ScrShutdownSystemStub(unsigned char sys);
|
|
||||||
static void StoreScriptBaseProgramNumStub();
|
static void StoreScriptBaseProgramNumStub();
|
||||||
static void StoreScriptBaseProgramNum();
|
static void StoreScriptBaseProgramNum();
|
||||||
static void Scr_PrintPrevCodePosStub();
|
static void Scr_PrintPrevCodePosStub();
|
||||||
|
@ -31,9 +31,9 @@ namespace Components
|
|||||||
strncpy_s(buffer, bufferSize, userInfo.data(), _TRUNCATE);
|
strncpy_s(buffer, bufferSize, userInfo.data(), _TRUNCATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserInfo::ClearClientOverrides(const int client)
|
void UserInfo::ClearClientOverrides(const int clientNum)
|
||||||
{
|
{
|
||||||
UserInfoOverrides[client].clear();
|
UserInfoOverrides[clientNum].clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserInfo::ClearAllOverrides()
|
void UserInfo::ClearAllOverrides()
|
||||||
@ -75,9 +75,15 @@ namespace Components
|
|||||||
|
|
||||||
AddScriptMethods();
|
AddScriptMethods();
|
||||||
|
|
||||||
Script::OnVMShutdown([]
|
Events::OnVMShutdown([]
|
||||||
{
|
{
|
||||||
ClearAllOverrides();
|
ClearAllOverrides();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Events::OnClientDisconnect([](const int clientNum)
|
||||||
|
{
|
||||||
|
// Clear the overrides for UserInfo
|
||||||
|
ClearClientOverrides(clientNum);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ namespace Components
|
|||||||
public:
|
public:
|
||||||
UserInfo();
|
UserInfo();
|
||||||
|
|
||||||
static void ClearClientOverrides(int client);
|
static void ClearClientOverrides(int clientNum);
|
||||||
static void ClearAllOverrides();
|
static void ClearAllOverrides();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -69,12 +69,7 @@ namespace Utils
|
|||||||
class Signal
|
class Signal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Signal()
|
Signal() = default;
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> _(this->mutex);
|
|
||||||
|
|
||||||
this->slots.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
Signal(Signal& obj) : Signal()
|
Signal(Signal& obj) : Signal()
|
||||||
{
|
{
|
||||||
@ -84,13 +79,13 @@ namespace Utils
|
|||||||
Utils::Merge(&this->slots, obj.getSlots());
|
Utils::Merge(&this->slots, obj.getSlots());
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect(Slot<T> slot)
|
void connect(const Slot<T> slot)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> _(this->mutex);
|
std::lock_guard<std::recursive_mutex> _(this->mutex);
|
||||||
|
|
||||||
if (slot)
|
if (slot)
|
||||||
{
|
{
|
||||||
this->slots.push_back(slot);
|
this->slots.emplace_back(slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user