mirror of
https://github.com/roflmuffin/CounterStrikeSharp.git
synced 2025-12-08 00:46:34 -08:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ddf6bcdfa | ||
|
|
98661cd069 | ||
|
|
86a5699b40 | ||
|
|
414710d05c |
@@ -50,8 +50,8 @@
|
||||
"CBaseModelEntity_SetModel": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "\\x48\\x89\\x5C\\x24\\x2A\\x48\\x89\\x7C\\x24\\x2A\\x55\\x48\\x8B\\xEC\\x48\\x83\\xEC\\x50\\x48\\x8B\\xF9",
|
||||
"linux": "\\x55\\x48\\x89\\xF2\\x48\\x89\\xE5\\x41\\x54\\x49\\x89\\xFC\\x48\\x8D\\x7D\\xE0\\x48\\x83\\xEC\\x18\\x48\\x8D\\x05\\xE5\\xD1\\xBF\\x00"
|
||||
"windows": "\\x48\\x89\\x5C\\x24\\x10\\x48\\x89\\x7C\\x24\\x20\\x55\\x48\\x8B\\xEC\\x48\\x83\\xEC\\x50\\x48\\x8B\\xF9\\x4C\\x8B\\xC2\\x48\\x8B\\x0D\\x69\\x07\\xD9\\x00",
|
||||
"linux": "\\x55\\x48\\x89\\xF2\\x48\\x89\\xE5\\x41\\x54\\x49\\x89\\xFC\\x48\\x8D\\x7D\\xE0\\x48\\x83\\xEC\\x18\\x48\\x8D\\x05\\x15\\xD4\\xBF\\x00"
|
||||
}
|
||||
},
|
||||
"CBasePlayerPawn_CommitSuicide": {
|
||||
|
||||
@@ -26,7 +26,7 @@ public partial class CCSPlayerController
|
||||
|
||||
public void PrintToConsole(string message)
|
||||
{
|
||||
NativeAPI.PrintToConsole((int)EntityIndex.Value.Value, message);
|
||||
NativeAPI.PrintToConsole((int)EntityIndex.Value.Value, $"{message}\n\0");
|
||||
}
|
||||
|
||||
public void PrintToChat(string message)
|
||||
|
||||
@@ -31,9 +31,15 @@ public partial class VirtualFunction
|
||||
{
|
||||
if (!_createdFunctions.TryGetValue(signature, out var function))
|
||||
{
|
||||
function = NativeAPI.CreateVirtualFunctionBySignature(IntPtr.Zero, Addresses.ServerPath, signature,
|
||||
argumentTypes.Count(), (int)returnType, arguments);
|
||||
_createdFunctions[signature] = function;
|
||||
try
|
||||
{
|
||||
function = NativeAPI.CreateVirtualFunctionBySignature(IntPtr.Zero, Addresses.ServerPath, signature,
|
||||
argumentTypes.Count(), (int)returnType, arguments);
|
||||
_createdFunctions[signature] = function;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return function;
|
||||
|
||||
@@ -354,7 +354,7 @@ namespace TestPlugin
|
||||
[ConsoleCommand("cssharp_attribute", "This is a custom attribute event")]
|
||||
public void OnCommand(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
Log("cssharp_attribute called!");
|
||||
command.ReplyToCommand("cssharp_attribute called", true);
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_changelevel", "Changes map")]
|
||||
|
||||
@@ -56,9 +56,6 @@ void ChatManager::OnShutdown() {}
|
||||
void DetourHostSay(CBaseEntity* pController, CCommand& args, bool teamonly, int unk1,
|
||||
const char* unk2)
|
||||
{
|
||||
CCommand newArgs;
|
||||
newArgs.Tokenize(args.Arg(1));
|
||||
|
||||
if (pController) {
|
||||
auto pEvent = globals::gameEventManager->CreateEvent("player_chat", true);
|
||||
if (pEvent) {
|
||||
@@ -70,48 +67,52 @@ void DetourHostSay(CBaseEntity* pController, CCommand& args, bool teamonly, int
|
||||
}
|
||||
}
|
||||
|
||||
if (*args[1] == '/' || *args[1] == '!') {
|
||||
globals::chatManager.OnSayCommandPost(pController, newArgs);
|
||||
return;
|
||||
bool bSilent = *args[1] == '/';
|
||||
bool bCommand = *args[1] == '!' || *args[1] == '/';
|
||||
|
||||
if (!bSilent) {
|
||||
m_pHostSay(pController, args, teamonly, unk1, unk2);
|
||||
}
|
||||
|
||||
m_pHostSay(pController, args, teamonly, unk1, unk2);
|
||||
if (bCommand)
|
||||
{
|
||||
char *pszMessage = (char *)(args.ArgS() + 2);
|
||||
|
||||
// Trailing slashes are only removed if Host_Say has been called.
|
||||
if (bSilent)
|
||||
pszMessage[V_strlen(pszMessage) - 1] = 0;
|
||||
|
||||
CCommand args;
|
||||
args.Tokenize(pszMessage);
|
||||
|
||||
auto prefixedPhrase = std::string("css_") + args.Arg(0);
|
||||
auto bValidWithPrefix = globals::conCommandManager.IsValidValveCommand(prefixedPhrase.c_str());
|
||||
|
||||
if (bValidWithPrefix) {
|
||||
// Re-tokenize with a `css_` prefix if we have found that its a valid command.
|
||||
args.Tokenize(("css_" + std::string(pszMessage)).c_str());
|
||||
}
|
||||
|
||||
globals::chatManager.OnSayCommandPost(pController, args);
|
||||
}
|
||||
}
|
||||
|
||||
bool ChatManager::OnSayCommandPre(CBaseEntity* pController, CCommand& command) { return false; }
|
||||
|
||||
void ChatManager::OnSayCommandPost(CBaseEntity* pController, CCommand& command)
|
||||
{
|
||||
const char* args = command.ArgS();
|
||||
auto commandStr = command.Arg(0);
|
||||
|
||||
return InternalDispatch(pController, commandStr + 1, command);
|
||||
return InternalDispatch(pController, commandStr, command);
|
||||
}
|
||||
|
||||
void ChatManager::InternalDispatch(CBaseEntity* pPlayerController, const char* szTriggerPhase,
|
||||
CCommand& fullCommand)
|
||||
{
|
||||
auto ppArgV = new const char*[fullCommand.ArgC()];
|
||||
ppArgV[0] = strdup(szTriggerPhase);
|
||||
for (int i = 1; i < fullCommand.ArgC(); i++) {
|
||||
ppArgV[i] = fullCommand.Arg(i);
|
||||
}
|
||||
|
||||
auto prefixedPhrase = std::string("css_") + szTriggerPhase;
|
||||
|
||||
auto bValidWithPrefix = globals::conCommandManager.IsValidValveCommand(prefixedPhrase.c_str());
|
||||
|
||||
if (bValidWithPrefix) {
|
||||
ppArgV[0] = prefixedPhrase.c_str();
|
||||
}
|
||||
|
||||
CCommand commandCopy(fullCommand.ArgC(), ppArgV);
|
||||
|
||||
if (pPlayerController == nullptr) {
|
||||
globals::conCommandManager.ExecuteCommandCallbacks(
|
||||
commandCopy.Arg(0), CCommandContext(CommandTarget_t::CT_NO_TARGET, CPlayerSlot(-1)),
|
||||
commandCopy, HookMode::Pre);
|
||||
delete[] ppArgV;
|
||||
fullCommand.Arg(0), CCommandContext(CommandTarget_t::CT_NO_TARGET, CPlayerSlot(-1)),
|
||||
fullCommand, HookMode::Pre);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,8 +120,7 @@ void ChatManager::InternalDispatch(CBaseEntity* pPlayerController, const char* s
|
||||
auto slot = CPlayerSlot(index - 1);
|
||||
|
||||
globals::conCommandManager.ExecuteCommandCallbacks(
|
||||
commandCopy.Arg(0), CCommandContext(CommandTarget_t::CT_NO_TARGET, slot), commandCopy,
|
||||
fullCommand.Arg(0), CCommandContext(CommandTarget_t::CT_NO_TARGET, slot), fullCommand,
|
||||
HookMode::Pre);
|
||||
delete[] ppArgV;
|
||||
}
|
||||
} // namespace counterstrikesharp
|
||||
@@ -170,6 +170,9 @@ ConCommandInfo::~ConCommandInfo()
|
||||
globals::callbackManager.ReleaseCallback(callback_pre);
|
||||
globals::callbackManager.ReleaseCallback(callback_post);
|
||||
}
|
||||
ConCommandInfo::ConCommandInfo(bool bNoCallbacks) {
|
||||
|
||||
}
|
||||
|
||||
ConCommandManager::ConCommandManager() {}
|
||||
|
||||
@@ -181,6 +184,10 @@ void ConCommandManager::OnAllInitialized()
|
||||
&ConCommandManager::Hook_DispatchConCommand, false);
|
||||
SH_ADD_HOOK_MEMFUNC(ICvar, DispatchConCommand, globals::cvars, this,
|
||||
&ConCommandManager::Hook_DispatchConCommand_Post, true);
|
||||
|
||||
m_global_cmd.callback_pre = globals::callbackManager.CreateCallback("OnClientCommandGlobalPre");
|
||||
m_global_cmd.callback_post =
|
||||
globals::callbackManager.CreateCallback("OnClientCommandGlobalPost");
|
||||
}
|
||||
|
||||
void ConCommandManager::OnShutdown()
|
||||
@@ -189,6 +196,9 @@ void ConCommandManager::OnShutdown()
|
||||
&ConCommandManager::Hook_DispatchConCommand, false);
|
||||
SH_REMOVE_HOOK_MEMFUNC(ICvar, DispatchConCommand, globals::cvars, this,
|
||||
&ConCommandManager::Hook_DispatchConCommand_Post, true);
|
||||
|
||||
globals::callbackManager.ReleaseCallback(m_global_cmd.callback_pre);
|
||||
globals::callbackManager.ReleaseCallback(m_global_cmd.callback_post);
|
||||
}
|
||||
|
||||
void CommandCallback(const CCommandContext& context, const CCommand& command)
|
||||
@@ -199,6 +209,15 @@ void CommandCallback(const CCommandContext& context, const CCommand& command)
|
||||
|
||||
void ConCommandManager::AddCommandListener(const char* name, CallbackT callback, HookMode mode)
|
||||
{
|
||||
if (name == nullptr) {
|
||||
if (mode == HookMode::Pre) {
|
||||
m_global_cmd.callback_pre->AddListener(callback);
|
||||
} else {
|
||||
m_global_cmd.callback_post->AddListener(callback);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto strName = std::string(name);
|
||||
ConCommandInfo* pInfo = m_cmd_lookup[strName];
|
||||
|
||||
@@ -210,7 +229,6 @@ void ConCommandManager::AddCommandListener(const char* name, CallbackT callback,
|
||||
if (hExistingCommand.IsValid()) {
|
||||
pInfo->command = globals::cvars->GetCommand(hExistingCommand);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (mode == HookMode::Pre) {
|
||||
@@ -218,11 +236,19 @@ void ConCommandManager::AddCommandListener(const char* name, CallbackT callback,
|
||||
} else {
|
||||
pInfo->callback_post->AddListener(callback);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ConCommandManager::RemoveCommandListener(const char* name, CallbackT callback, HookMode mode)
|
||||
{
|
||||
if (name == nullptr) {
|
||||
if (mode == HookMode::Pre) {
|
||||
m_global_cmd.callback_pre->RemoveListener(callback);
|
||||
} else {
|
||||
m_global_cmd.callback_post->RemoveListener(callback);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto strName = std::string(name);
|
||||
ConCommandInfo* pInfo = m_cmd_lookup[strName];
|
||||
|
||||
@@ -285,10 +311,43 @@ bool ConCommandManager::RemoveValveCommand(const char* name)
|
||||
HookResult ConCommandManager::ExecuteCommandCallbacks(const char* name, const CCommandContext& ctx,
|
||||
const CCommand& args, HookMode mode)
|
||||
{
|
||||
CSSHARP_CORE_TRACE("[ConCommandManager::ExecuteCommandCallbacks][{}]: {}", mode == Pre ? "Pre" : "Post", name);
|
||||
CSSHARP_CORE_TRACE("[ConCommandManager::ExecuteCommandCallbacks][{}]: {}",
|
||||
mode == Pre ? "Pre" : "Post", name);
|
||||
ConCommandInfo* pInfo = m_cmd_lookup[std::string(name)];
|
||||
|
||||
HookResult result = HookResult::Continue;
|
||||
|
||||
auto globalCallback = mode == HookMode::Pre ? m_global_cmd.callback_pre : m_global_cmd.callback_post;
|
||||
|
||||
if (globalCallback->GetFunctionCount() > 0) {
|
||||
globalCallback->ScriptContext().Reset();
|
||||
globalCallback->ScriptContext().Push(ctx.GetPlayerSlot().Get());
|
||||
globalCallback->ScriptContext().Push(&args);
|
||||
|
||||
for (auto fnMethodToCall : globalCallback->GetFunctions()) {
|
||||
if (!fnMethodToCall)
|
||||
continue;
|
||||
fnMethodToCall(&globalCallback->ScriptContextStruct());
|
||||
|
||||
auto hookResult = globalCallback->ScriptContext().GetResult<HookResult>();
|
||||
|
||||
if (hookResult >= HookResult::Stop) {
|
||||
if (mode == HookMode::Pre) {
|
||||
return HookResult::Stop;
|
||||
}
|
||||
|
||||
result = hookResult;
|
||||
break;
|
||||
}
|
||||
|
||||
if (hookResult >= HookResult::Handled) {
|
||||
result = hookResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pInfo) {
|
||||
return HookResult::Continue;
|
||||
return result;
|
||||
}
|
||||
|
||||
auto pCallback = mode == HookMode::Pre ? pInfo->callback_pre : pInfo->callback_post;
|
||||
@@ -302,14 +361,16 @@ HookResult ConCommandManager::ExecuteCommandCallbacks(const char* name, const CC
|
||||
continue;
|
||||
fnMethodToCall(&pCallback->ScriptContextStruct());
|
||||
|
||||
auto result = pCallback->ScriptContext().GetResult<HookResult>();
|
||||
auto thisResult = pCallback->ScriptContext().GetResult<HookResult>();
|
||||
|
||||
if (result >= HookResult::Handled) {
|
||||
if (thisResult >= HookResult::Handled) {
|
||||
return result;
|
||||
} else if (thisResult > result) {
|
||||
result = thisResult;
|
||||
}
|
||||
}
|
||||
|
||||
return HookResult::Continue;
|
||||
return result;
|
||||
}
|
||||
|
||||
void ConCommandManager::Hook_DispatchConCommand(ConCommandHandle cmd, const CCommandContext& ctx,
|
||||
|
||||
@@ -58,6 +58,7 @@ class ConCommandInfo {
|
||||
|
||||
public:
|
||||
ConCommandInfo();
|
||||
ConCommandInfo(bool bNoCallbacks);
|
||||
~ConCommandInfo();
|
||||
|
||||
public:
|
||||
@@ -95,6 +96,7 @@ public:
|
||||
private:
|
||||
std::vector<ConCommandInfo*> m_cmd_list;
|
||||
std::map<std::string, ConCommandInfo*, CaseInsensitiveComparator> m_cmd_lookup;
|
||||
ConCommandInfo m_global_cmd = ConCommandInfo(true);
|
||||
};
|
||||
|
||||
} // namespace counterstrikesharp
|
||||
Reference in New Issue
Block a user