[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 Ceg());
|
||||
Loader::Register(new UserInfo());
|
||||
Loader::Register(new Events());
|
||||
|
||||
Loader::Pregame = false;
|
||||
}
|
||||
|
@ -143,3 +143,4 @@ namespace Components
|
||||
#include "Modules/MapRotation.hpp"
|
||||
#include "Modules/Ceg.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()
|
||||
{
|
||||
AssertOffset(Game::client_s, bIsTestClient, 0x41AF0);
|
||||
@ -340,7 +325,10 @@ namespace Components
|
||||
Utils::Hook(0x441B80, Bots::G_SelectWeaponIndex_Hk, HOOK_JUMP).install()->quick();
|
||||
|
||||
// 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
|
||||
for (auto i = 0u; i < std::extent_v<decltype(g_botai)>; i++)
|
||||
@ -393,9 +381,9 @@ namespace Components
|
||||
Bots::AddMethods();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
@ -22,7 +22,5 @@ namespace Components
|
||||
|
||||
static void G_SelectWeaponIndex(int clientNum, int iWeaponIndex);
|
||||
static void G_SelectWeaponIndex_Hk();
|
||||
|
||||
static void ClientDisconnect_Hk(int clientNum);
|
||||
};
|
||||
}
|
||||
|
@ -961,7 +961,7 @@ namespace Components
|
||||
|
||||
}, Scheduler::Pipeline::MAIN);
|
||||
|
||||
Script::OnVMShutdown([]()
|
||||
Events::OnVMShutdown([]()
|
||||
{
|
||||
Download::ScriptDownloads.clear();
|
||||
});
|
||||
|
@ -377,6 +377,9 @@ namespace Components
|
||||
|
||||
// If the game closed abruptly, the dvars would not have been restored
|
||||
Scheduler::Once(Dvar::ResetDvarsValue, Scheduler::Pipeline::MAIN);
|
||||
|
||||
// Reset archive dvars when client leaves a server
|
||||
Events::OnSteamDisconnect(Dvar::ResetDvarsValue);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
__declspec(naked) void Friends::DisconnectStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
pushad
|
||||
|
||||
call Friends::ClearServer
|
||||
call Dvar::ResetDvarsValue
|
||||
|
||||
popad
|
||||
|
||||
push 467CC0h
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
void Friends::AddFriend(SteamID user)
|
||||
{
|
||||
if (Steam::Proxy::ClientFriends && Steam::Proxy::SteamFriends)
|
||||
@ -622,7 +606,8 @@ namespace Components
|
||||
});
|
||||
|
||||
// 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();
|
||||
|
||||
// Show blue icons on the minimap
|
||||
|
@ -77,7 +77,6 @@ namespace Components
|
||||
static std::recursive_mutex Mutex;
|
||||
static std::vector<Friend> FriendsList;
|
||||
|
||||
static void DisconnectStub();
|
||||
static void ClearServer();
|
||||
static void SetServer();
|
||||
|
||||
|
@ -14,8 +14,6 @@ namespace Components
|
||||
const char* Script::ReplacedPos = nullptr;
|
||||
int Script::LastFrameTime = -1;
|
||||
|
||||
Utils::Signal<Script::Callback> Script::VMShutdownSignal;
|
||||
|
||||
void Script::FunctionError()
|
||||
{
|
||||
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()
|
||||
{
|
||||
if (Game::Scr_GetNumParam() == 6u)
|
||||
@ -715,9 +699,6 @@ namespace Components
|
||||
Utils::Hook(0x61E92E, Script::VMExecuteInternalStub, HOOK_JUMP).install()->quick();
|
||||
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([]()
|
||||
{
|
||||
if (!Game::SV_Loaded())
|
||||
@ -753,14 +734,9 @@ namespace Components
|
||||
|
||||
Script::AddFunctions();
|
||||
|
||||
Script::OnVMShutdown([]
|
||||
Events::OnVMShutdown([]
|
||||
{
|
||||
Script::ReplacedFunctions.clear();
|
||||
});
|
||||
}
|
||||
|
||||
Script::~Script()
|
||||
{
|
||||
Script::VMShutdownSignal.clear();
|
||||
}
|
||||
}
|
||||
|
@ -7,17 +7,12 @@ namespace Components
|
||||
{
|
||||
public:
|
||||
Script();
|
||||
~Script();
|
||||
|
||||
typedef void(Callback)();
|
||||
|
||||
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 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);
|
||||
|
||||
private:
|
||||
@ -33,8 +28,6 @@ namespace Components
|
||||
static const char* ReplacedPos;
|
||||
static int LastFrameTime;
|
||||
|
||||
static Utils::Signal<Script::Callback> VMShutdownSignal;
|
||||
|
||||
static void CompileError(unsigned int offset, const char* message, ...);
|
||||
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::BuiltinMethod BuiltIn_GetMethod(const char** pName, int* type);
|
||||
|
||||
static void ScrShutdownSystemStub(unsigned char sys);
|
||||
static void StoreScriptBaseProgramNumStub();
|
||||
static void StoreScriptBaseProgramNum();
|
||||
static void Scr_PrintPrevCodePosStub();
|
||||
|
@ -31,9 +31,9 @@ namespace Components
|
||||
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()
|
||||
@ -75,9 +75,15 @@ namespace Components
|
||||
|
||||
AddScriptMethods();
|
||||
|
||||
Script::OnVMShutdown([]
|
||||
Events::OnVMShutdown([]
|
||||
{
|
||||
ClearAllOverrides();
|
||||
});
|
||||
|
||||
Events::OnClientDisconnect([](const int clientNum)
|
||||
{
|
||||
// Clear the overrides for UserInfo
|
||||
ClearClientOverrides(clientNum);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ namespace Components
|
||||
public:
|
||||
UserInfo();
|
||||
|
||||
static void ClearClientOverrides(int client);
|
||||
static void ClearClientOverrides(int clientNum);
|
||||
static void ClearAllOverrides();
|
||||
|
||||
private:
|
||||
|
@ -69,12 +69,7 @@ namespace Utils
|
||||
class Signal
|
||||
{
|
||||
public:
|
||||
Signal()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(this->mutex);
|
||||
|
||||
this->slots.clear();
|
||||
}
|
||||
Signal() = default;
|
||||
|
||||
Signal(Signal& obj) : Signal()
|
||||
{
|
||||
@ -84,13 +79,13 @@ namespace Utils
|
||||
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);
|
||||
|
||||
if (slot)
|
||||
{
|
||||
this->slots.push_back(slot);
|
||||
this->slots.emplace_back(slot);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user