mirror of
https://github.com/roflmuffin/CounterStrikeSharp.git
synced 2025-12-08 08:56:34 -08:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98661cd069 | ||
|
|
86a5699b40 | ||
|
|
414710d05c | ||
|
|
b09c2b62c8 |
@@ -75,8 +75,6 @@ SET(SOURCE_FILES
|
||||
src/core/managers/entity_manager.h
|
||||
src/core/managers/chat_manager.cpp
|
||||
src/core/managers/chat_manager.h
|
||||
src/core/managers/client_command_manager.cpp
|
||||
src/core/managers/client_command_manager.h
|
||||
src/core/managers/server_manager.cpp
|
||||
src/core/managers/server_manager.h
|
||||
src/scripting/natives/natives_server.cpp
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace CounterStrikeSharp.API.Core
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr AddCommand(string name, string description, bool serveronly, int flags, InputArgument callback){
|
||||
public static void AddCommand(string name, string description, bool serveronly, int flags, InputArgument callback){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
@@ -41,7 +41,6 @@ namespace CounterStrikeSharp.API.Core
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x807C6B9C);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -209,14 +209,10 @@ namespace CounterStrikeSharp.API.Core
|
||||
{
|
||||
var wrappedHandler = new Func<int, IntPtr, HookResult>((i, ptr) =>
|
||||
{
|
||||
if (i == -1)
|
||||
{
|
||||
return HookResult.Continue;
|
||||
}
|
||||
var caller = (i != -1) ? new CCSPlayerController(NativeAPI.GetEntityFromIndex(i + 1)) : null;
|
||||
|
||||
var entity = new CCSPlayerController(NativeAPI.GetEntityFromIndex(i + 1));
|
||||
var command = new CommandInfo(ptr, entity);
|
||||
return handler.Invoke(entity.IsValid ? entity : null, command);
|
||||
var command = new CommandInfo(ptr, caller);
|
||||
return handler.Invoke(caller, command);
|
||||
});
|
||||
|
||||
var subscriber = new CallbackSubscriber(handler, wrappedHandler, () => { RemoveCommandListener(name, handler, mode); });
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "memory_module.h"
|
||||
#include "interfaces/cs2_interfaces.h"
|
||||
#include "core/managers/entity_manager.h"
|
||||
#include "core/managers/client_command_manager.h"
|
||||
#include "core/managers/server_manager.h"
|
||||
#include <public/game/server/iplayerinfo.h>
|
||||
#include <public/entity2/entitysystem.h>
|
||||
@@ -76,7 +75,6 @@ TimerSystem timerSystem;
|
||||
ConCommandManager conCommandManager;
|
||||
EntityManager entityManager;
|
||||
ChatManager chatManager;
|
||||
ClientCommandManager clientCommandManager;
|
||||
ServerManager serverManager;
|
||||
|
||||
void Initialize() {
|
||||
|
||||
@@ -48,7 +48,6 @@ class ChatCommands;
|
||||
class HookManager;
|
||||
class EntityManager;
|
||||
class ChatManager;
|
||||
class ClientCommandManager;
|
||||
class ServerManager;
|
||||
class CGameConfig;
|
||||
|
||||
@@ -92,7 +91,6 @@ extern EntityManager entityManager;
|
||||
extern TimerSystem timerSystem;
|
||||
extern ChatCommands chatCommands;
|
||||
extern ChatManager chatManager;
|
||||
extern ClientCommandManager clientCommandManager;
|
||||
extern ServerManager serverManager;
|
||||
|
||||
extern HookManager hookManager;
|
||||
|
||||
@@ -39,8 +39,7 @@ ChatManager::~ChatManager() {}
|
||||
void ChatManager::OnAllInitialized()
|
||||
{
|
||||
m_pHostSay = reinterpret_cast<HostSay>(
|
||||
modules::server->FindSignature(globals::gameConfig->GetSignature("Host_Say"))
|
||||
);
|
||||
modules::server->FindSignature(globals::gameConfig->GetSignature("Host_Say")));
|
||||
|
||||
if (m_pHostSay == nullptr) {
|
||||
CSSHARP_CORE_ERROR("Failed to find signature for \'Host_Say\'");
|
||||
@@ -57,71 +56,71 @@ void ChatManager::OnShutdown() {}
|
||||
void DetourHostSay(CBaseEntity* pController, CCommand& args, bool teamonly, int unk1,
|
||||
const char* unk2)
|
||||
{
|
||||
CCommand newArgs;
|
||||
newArgs.Tokenize(args.Arg(1));
|
||||
|
||||
if (*args[1] == '/' || *args[1] == '!') {
|
||||
globals::chatManager.OnSayCommandPost(pController, newArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
m_pHostSay(pController, args, teamonly, unk1, unk2);
|
||||
|
||||
if (pController) {
|
||||
auto pEvent = globals::gameEventManager->CreateEvent("player_chat", true);
|
||||
if (pEvent) {
|
||||
pEvent->SetBool("teamonly", teamonly);
|
||||
pEvent->SetInt("userid", pController->GetEntityIndex().Get());
|
||||
pEvent->SetInt("userid", pController->GetEntityIndex().Get() - 1);
|
||||
pEvent->SetString("text", args[1]);
|
||||
|
||||
globals::gameEventManager->FireEvent(pEvent, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool bSilent = *args[1] == '/';
|
||||
bool bCommand = *args[1] == '!' || *args[1] == '/';
|
||||
|
||||
if (!bSilent) {
|
||||
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;
|
||||
}
|
||||
bool ChatManager::OnSayCommandPre(CBaseEntity* pController, CCommand& command) { return false; }
|
||||
|
||||
bool ChatManager::OnSayCommandPost(CBaseEntity* pController, CCommand& command)
|
||||
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);
|
||||
}
|
||||
|
||||
bool ChatManager::InternalDispatch(CBaseEntity* pPlayerController, const char* szTriggerPhase,
|
||||
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 command = globals::conCommandManager.FindCommand(prefixedPhrase.c_str());
|
||||
|
||||
if (command) {
|
||||
ppArgV[0] = prefixedPhrase.c_str();
|
||||
}
|
||||
|
||||
CCommand commandCopy(fullCommand.ArgC(), ppArgV);
|
||||
|
||||
if (pPlayerController == nullptr) {
|
||||
auto result = globals::conCommandManager.InternalDispatch(CPlayerSlot(-1), &commandCopy);
|
||||
delete[] ppArgV;
|
||||
return result;
|
||||
globals::conCommandManager.ExecuteCommandCallbacks(
|
||||
fullCommand.Arg(0), CCommandContext(CommandTarget_t::CT_NO_TARGET, CPlayerSlot(-1)),
|
||||
fullCommand, HookMode::Pre);
|
||||
return;
|
||||
}
|
||||
|
||||
auto index = pPlayerController->GetEntityIndex().Get();
|
||||
|
||||
auto slot = CPlayerSlot(index - 1);
|
||||
|
||||
auto result = globals::conCommandManager.InternalDispatch(slot, &commandCopy);
|
||||
delete[] ppArgV;
|
||||
return result;
|
||||
globals::conCommandManager.ExecuteCommandCallbacks(
|
||||
fullCommand.Arg(0), CCommandContext(CommandTarget_t::CT_NO_TARGET, slot), fullCommand,
|
||||
HookMode::Pre);
|
||||
}
|
||||
} // namespace counterstrikesharp
|
||||
@@ -53,10 +53,10 @@ class ChatManager : public GlobalClass
|
||||
void OnShutdown() override;
|
||||
|
||||
bool OnSayCommandPre(CBaseEntity* pController, CCommand& args);
|
||||
bool OnSayCommandPost(CBaseEntity* pController, CCommand& args);
|
||||
void OnSayCommandPost(CBaseEntity* pController, CCommand& args);
|
||||
|
||||
private:
|
||||
bool InternalDispatch(CBaseEntity* pPlayerController, const char* szTriggerPhrase,
|
||||
void InternalDispatch(CBaseEntity* pPlayerController, const char* szTriggerPhrase,
|
||||
CCommand& pFullCommand);
|
||||
|
||||
std::vector<ChatCommandInfo*> m_cmd_list;
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
#include "core/managers/client_command_manager.h"
|
||||
|
||||
#include <public/eiface.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "scripting/callback_manager.h"
|
||||
#include "core/log.h"
|
||||
|
||||
namespace counterstrikesharp {
|
||||
|
||||
ClientCommandManager::ClientCommandManager() {}
|
||||
|
||||
ClientCommandManager::~ClientCommandManager() {}
|
||||
|
||||
void ClientCommandManager::OnAllInitialized()
|
||||
{
|
||||
m_global_cmd.callback_pre = globals::callbackManager.CreateCallback("OnClientCommandGlobalPre");
|
||||
m_global_cmd.callback_post =
|
||||
globals::callbackManager.CreateCallback("OnClientCommandGlobalPost");
|
||||
}
|
||||
|
||||
void ClientCommandManager::OnShutdown() {}
|
||||
|
||||
bool ClientCommandManager::DispatchClientCommand(CPlayerSlot slot, const char* cmd,
|
||||
const CCommand* args)
|
||||
{
|
||||
CSSHARP_CORE_TRACE("Dispatch client command {}", cmd);
|
||||
auto* p_info = m_cmd_lookup[cmd];
|
||||
|
||||
bool result = false;
|
||||
|
||||
if (m_global_cmd.callback_pre->GetFunctionCount() > 0) {
|
||||
m_global_cmd.callback_pre->ScriptContext().Reset();
|
||||
m_global_cmd.callback_pre->ScriptContext().Push(slot.Get());
|
||||
m_global_cmd.callback_pre->ScriptContext().Push(args);
|
||||
|
||||
for (auto fnMethodToCall : m_global_cmd.callback_pre->GetFunctions()) {
|
||||
if (!fnMethodToCall)
|
||||
continue;
|
||||
fnMethodToCall(&m_global_cmd.callback_pre->ScriptContextStruct());
|
||||
|
||||
auto hookResult = m_global_cmd.callback_pre->ScriptContext().GetResult<HookResult>();
|
||||
CSSHARP_CORE_TRACE("Received hook result from command callback {}:{}", cmd, hookResult);
|
||||
|
||||
if (hookResult >= HookResult::Stop) {
|
||||
return true;
|
||||
} else if (hookResult >= HookResult::Handled) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_info && p_info->callback_pre) {
|
||||
p_info->callback_pre->ScriptContext().Reset();
|
||||
p_info->callback_pre->ScriptContext().Push(slot.Get());
|
||||
p_info->callback_pre->ScriptContext().Push(args);
|
||||
|
||||
for (auto fnMethodToCall : p_info->callback_pre->GetFunctions()) {
|
||||
if (!fnMethodToCall)
|
||||
continue;
|
||||
fnMethodToCall(&p_info->callback_pre->ScriptContextStruct());
|
||||
|
||||
auto hookResult = p_info->callback_pre->ScriptContext().GetResult<HookResult>();
|
||||
CSSHARP_CORE_TRACE("Received hook result from command callback {}:{}", cmd, hookResult);
|
||||
|
||||
if (hookResult >= HookResult::Stop) {
|
||||
return true;
|
||||
} else if (hookResult >= HookResult::Handled) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_global_cmd.callback_post->GetFunctionCount() > 0) {
|
||||
m_global_cmd.callback_post->ScriptContext().Reset();
|
||||
m_global_cmd.callback_post->ScriptContext().Push(slot.Get());
|
||||
m_global_cmd.callback_post->ScriptContext().Push(args);
|
||||
m_global_cmd.callback_post->Execute();
|
||||
}
|
||||
|
||||
if (result && p_info && p_info->callback_post) {
|
||||
p_info->callback_post->ScriptContext().Reset();
|
||||
p_info->callback_post->ScriptContext().Push(slot.Get());
|
||||
p_info->callback_post->ScriptContext().Push(args);
|
||||
p_info->callback_post->Execute();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
void ClientCommandManager::AddCommandListener(const char* cmd, CallbackT callback, bool bPost)
|
||||
{
|
||||
// Handle global command listeners that listen for every ClientCommand.
|
||||
if (cmd == nullptr) {
|
||||
if (bPost) {
|
||||
m_global_cmd.callback_post->AddListener(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
m_global_cmd.callback_pre->AddListener(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* p_info = m_cmd_lookup[std::string(cmd)];
|
||||
|
||||
if (!p_info) {
|
||||
p_info = new ClientCommandInfo();
|
||||
p_info->command = cmd;
|
||||
|
||||
p_info->callback_pre = globals::callbackManager.CreateCallback(cmd);
|
||||
p_info->callback_post = globals::callbackManager.CreateCallback(cmd);
|
||||
|
||||
m_cmd_list.push_back(p_info);
|
||||
m_cmd_lookup[cmd] = p_info;
|
||||
}
|
||||
|
||||
if (bPost) {
|
||||
p_info->callback_post->AddListener(callback);
|
||||
} else {
|
||||
p_info->callback_pre->AddListener(callback);
|
||||
}
|
||||
}
|
||||
void ClientCommandManager::RemoveCommandListener(const char* cmd, CallbackT callback, bool bPost)
|
||||
{
|
||||
if (cmd == nullptr) {
|
||||
if (bPost) {
|
||||
m_global_cmd.callback_post->RemoveListener(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
m_global_cmd.callback_pre->RemoveListener(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* p_info = m_cmd_lookup[std::string(cmd)];
|
||||
|
||||
if (!p_info) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bPost) {
|
||||
p_info->callback_post->RemoveListener(callback);
|
||||
} else {
|
||||
p_info->callback_pre->RemoveListener(callback);
|
||||
}
|
||||
}
|
||||
} // namespace counterstrikesharp
|
||||
@@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "core/globals.h"
|
||||
#include "core/global_listener.h"
|
||||
#include "scripting/script_engine.h"
|
||||
#include <string>
|
||||
#include "playerslot.h"
|
||||
|
||||
namespace counterstrikesharp {
|
||||
class ScriptCallback;
|
||||
|
||||
class ClientCommandInfo {
|
||||
friend class ClientCommandManager;
|
||||
|
||||
public:
|
||||
ClientCommandInfo() {}
|
||||
|
||||
private:
|
||||
std::string command;
|
||||
ScriptCallback* callback_pre;
|
||||
ScriptCallback* callback_post;
|
||||
};
|
||||
|
||||
class ClientCommandManager : public GlobalClass {
|
||||
|
||||
|
||||
public:
|
||||
ClientCommandManager();
|
||||
~ClientCommandManager();
|
||||
void OnAllInitialized() override;
|
||||
void OnShutdown() override;
|
||||
bool DispatchClientCommand(CPlayerSlot slot, const char* cmd, const CCommand* args);
|
||||
void AddCommandListener(const char* cmd, CallbackT callback, bool bPost);
|
||||
void RemoveCommandListener(const char* cmd, CallbackT callback, bool bPost);
|
||||
|
||||
private:
|
||||
std::vector<ClientCommandInfo*> m_cmd_list;
|
||||
std::map<std::string, ClientCommandInfo*> m_cmd_lookup;
|
||||
ClientCommandInfo m_global_cmd;
|
||||
};
|
||||
|
||||
} // namespace counterstrikesharp
|
||||
@@ -157,307 +157,248 @@ CON_COMMAND(dump_schema, "dump schema symbols")
|
||||
output << std::setw(2) << j << std::endl;
|
||||
}
|
||||
|
||||
SH_DECL_HOOK2_void(ConCommandHandle, Dispatch, SH_NOATTRIB, false, const CCommandContext&,
|
||||
const CCommand&);
|
||||
SH_DECL_HOOK3_void(ICvar, DispatchConCommand, SH_NOATTRIB, 0, ConCommandHandle,
|
||||
const CCommandContext&, const CCommand&);
|
||||
|
||||
void ConCommandInfo::HookChange(CallbackT cb, bool post)
|
||||
ConCommandInfo::ConCommandInfo()
|
||||
{
|
||||
if (post) {
|
||||
this->callback_post->AddListener(cb);
|
||||
} else {
|
||||
this->callback_pre->AddListener(cb);
|
||||
}
|
||||
callback_pre = globals::callbackManager.CreateCallback("");
|
||||
callback_post = globals::callbackManager.CreateCallback("");
|
||||
}
|
||||
ConCommandInfo::~ConCommandInfo()
|
||||
{
|
||||
globals::callbackManager.ReleaseCallback(callback_pre);
|
||||
globals::callbackManager.ReleaseCallback(callback_post);
|
||||
}
|
||||
ConCommandInfo::ConCommandInfo(bool bNoCallbacks) {
|
||||
|
||||
}
|
||||
|
||||
void ConCommandInfo::UnhookChange(CallbackT cb, bool post)
|
||||
{
|
||||
if (post) {
|
||||
if (this->callback_post && this->callback_post->GetFunctionCount()) {
|
||||
callback_post->RemoveListener(cb);
|
||||
}
|
||||
} else {
|
||||
if (this->callback_pre && this->callback_pre->GetFunctionCount()) {
|
||||
callback_pre->RemoveListener(cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConCommandManager::ConCommandManager() : last_command_client(-1) {}
|
||||
ConCommandManager::ConCommandManager() {}
|
||||
|
||||
ConCommandManager::~ConCommandManager() {}
|
||||
|
||||
void ConCommandManager::OnAllInitialized() {}
|
||||
void ConCommandManager::OnAllInitialized()
|
||||
{
|
||||
SH_ADD_HOOK_MEMFUNC(ICvar, DispatchConCommand, globals::cvars, this,
|
||||
&ConCommandManager::Hook_DispatchConCommand, false);
|
||||
SH_ADD_HOOK_MEMFUNC(ICvar, DispatchConCommand, globals::cvars, this,
|
||||
&ConCommandManager::Hook_DispatchConCommand_Post, true);
|
||||
|
||||
void ConCommandManager::OnShutdown() {}
|
||||
m_global_cmd.callback_pre = globals::callbackManager.CreateCallback("OnClientCommandGlobalPre");
|
||||
m_global_cmd.callback_post =
|
||||
globals::callbackManager.CreateCallback("OnClientCommandGlobalPost");
|
||||
}
|
||||
|
||||
void ConCommandManager::OnShutdown()
|
||||
{
|
||||
SH_REMOVE_HOOK_MEMFUNC(ICvar, DispatchConCommand, globals::cvars, this,
|
||||
&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)
|
||||
{
|
||||
bool rval = globals::conCommandManager.InternalDispatch(context.GetPlayerSlot(), &command);
|
||||
|
||||
if (rval) {
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
// This is handled by the global hook
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
void CommandCallback_Post(const CCommandContext& context, const CCommand& command)
|
||||
void ConCommandManager::AddCommandListener(const char* name, CallbackT callback, HookMode mode)
|
||||
{
|
||||
bool rval = globals::conCommandManager.InternalDispatch_Post(context.GetPlayerSlot(), &command);
|
||||
|
||||
if (rval) {
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
}
|
||||
|
||||
ConCommandInfo* ConCommandManager::AddOrFindCommand(const char* name, const char* description,
|
||||
bool server_only, int flags)
|
||||
{
|
||||
ConCommandInfo* p_info = m_cmd_lookup[std::string(name)];
|
||||
|
||||
if (!p_info) {
|
||||
CSSHARP_CORE_TRACE("[ConCommandManager] Could not find command in existing lookup {}",
|
||||
name);
|
||||
// auto found = std::find_if(m_cmd_list.begin(), m_cmd_list.end(),
|
||||
// [&](ConCommandInfo* info) {
|
||||
// return V_strcasecmp(info->command->GetName(), name) == 0;
|
||||
// });
|
||||
// if (found != m_cmd_list.end()) {
|
||||
// return *found;
|
||||
// }
|
||||
p_info = new ConCommandInfo();
|
||||
ConCommandHandle existingCommand = globals::cvars->FindCommand(name);
|
||||
ConCommandRefAbstract pointerConCommand;
|
||||
p_info->p_cmd = pointerConCommand;
|
||||
|
||||
if (!existingCommand.IsValid()) {
|
||||
if (!description) {
|
||||
description = "";
|
||||
}
|
||||
|
||||
CSSHARP_CORE_TRACE("[ConCommandManager] Creating new command {}", name);
|
||||
|
||||
char* new_name = strdup(name);
|
||||
char* new_desc = strdup(description);
|
||||
|
||||
CSSHARP_CORE_TRACE("[ConCommandManager] Creating new command {}, {}, {}, {}, {}",
|
||||
(void*)&pointerConCommand, new_name, (void*)CommandCallback,
|
||||
new_desc, flags);
|
||||
|
||||
auto conCommand =
|
||||
new ConCommand(&pointerConCommand, new_name, CommandCallback, new_desc, flags);
|
||||
|
||||
CSSHARP_CORE_TRACE("[ConCommandManager] Creating callbacks for command {}", name);
|
||||
|
||||
p_info->command = conCommand;
|
||||
p_info->callback_pre = globals::callbackManager.CreateCallback(name);
|
||||
p_info->callback_post = globals::callbackManager.CreateCallback(name);
|
||||
p_info->server_only = server_only;
|
||||
|
||||
CSSHARP_CORE_TRACE(
|
||||
"[ConCommandManager] Adding hooks for command callback for command {}", name);
|
||||
|
||||
SH_ADD_HOOK(ConCommandHandle, Dispatch, &pointerConCommand.handle,
|
||||
SH_STATIC(CommandCallback), false);
|
||||
SH_ADD_HOOK(ConCommandHandle, Dispatch, &pointerConCommand.handle,
|
||||
SH_STATIC(CommandCallback_Post), true);
|
||||
|
||||
CSSHARP_CORE_TRACE("[ConCommandManager] Adding command to internal lookup {}", name);
|
||||
|
||||
m_cmd_list.push_back(p_info);
|
||||
m_cmd_lookup[name] = p_info;
|
||||
if (name == nullptr) {
|
||||
if (mode == HookMode::Pre) {
|
||||
m_global_cmd.callback_pre->AddListener(callback);
|
||||
} else {
|
||||
p_info->callback_pre = globals::callbackManager.CreateCallback(name);
|
||||
p_info->callback_post = globals::callbackManager.CreateCallback(name);
|
||||
p_info->server_only = server_only;
|
||||
m_global_cmd.callback_post->AddListener(callback);
|
||||
}
|
||||
|
||||
return p_info;
|
||||
return;
|
||||
}
|
||||
|
||||
return p_info;
|
||||
}
|
||||
auto strName = std::string(name);
|
||||
ConCommandInfo* pInfo = m_cmd_lookup[strName];
|
||||
|
||||
ConCommandInfo* ConCommandManager::AddCommand(const char* name, const char* description,
|
||||
bool server_only, int flags, CallbackT callback)
|
||||
{
|
||||
ConCommandInfo* p_info = AddOrFindCommand(name, description, server_only, flags);
|
||||
if (!p_info || !p_info->callback_pre) {
|
||||
return nullptr;
|
||||
if (!pInfo) {
|
||||
pInfo = new ConCommandInfo();
|
||||
m_cmd_lookup[strName] = pInfo;
|
||||
|
||||
ConCommandHandle hExistingCommand = globals::cvars->FindCommand(name);
|
||||
if (hExistingCommand.IsValid()) {
|
||||
pInfo->command = globals::cvars->GetCommand(hExistingCommand);
|
||||
}
|
||||
}
|
||||
|
||||
p_info->callback_pre->AddListener(callback);
|
||||
|
||||
return p_info;
|
||||
if (mode == HookMode::Pre) {
|
||||
pInfo->callback_pre->AddListener(callback);
|
||||
} else {
|
||||
pInfo->callback_post->AddListener(callback);
|
||||
}
|
||||
}
|
||||
|
||||
bool ConCommandManager::RemoveCommand(const char* name, CallbackT callback)
|
||||
void ConCommandManager::RemoveCommandListener(const char* name, CallbackT callback, HookMode mode)
|
||||
{
|
||||
auto strName = std::string(strdup(name));
|
||||
ConCommandInfo* p_info = m_cmd_lookup[strName];
|
||||
if (!p_info)
|
||||
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];
|
||||
|
||||
if (!pInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == HookMode::Pre) {
|
||||
pInfo->callback_pre->RemoveListener(callback);
|
||||
} else {
|
||||
pInfo->callback_post->RemoveListener(callback);
|
||||
}
|
||||
}
|
||||
|
||||
bool ConCommandManager::AddValveCommand(const char* name, const char* description, bool server_only,
|
||||
int flags)
|
||||
{
|
||||
ConCommandHandle hExistingCommand = globals::cvars->FindCommand(name);
|
||||
if (hExistingCommand.IsValid())
|
||||
return false;
|
||||
|
||||
if (p_info->callback_pre && p_info->callback_pre->GetFunctionCount()) {
|
||||
p_info->callback_pre->RemoveListener(callback);
|
||||
ConCommandRefAbstract conCommandRefAbstract;
|
||||
auto conCommand =
|
||||
new ConCommand(&conCommandRefAbstract, strdup(name), CommandCallback, strdup(description), flags);
|
||||
|
||||
ConCommandInfo* pInfo = m_cmd_lookup[std::string(name)];
|
||||
|
||||
if (!pInfo) {
|
||||
pInfo = new ConCommandInfo();
|
||||
m_cmd_lookup[std::string(name)] = pInfo;
|
||||
}
|
||||
|
||||
if (p_info->callback_post && p_info->callback_post->GetFunctionCount()) {
|
||||
p_info->callback_post->RemoveListener(callback);
|
||||
}
|
||||
|
||||
if (!p_info->callback_pre || p_info->callback_pre->GetFunctionCount() == 0) {
|
||||
// It does not look like this actually removes the con command.
|
||||
// You can still find with `find` command.
|
||||
globals::cvars->UnregisterConCommand(p_info->p_cmd.handle);
|
||||
}
|
||||
pInfo->p_cmd = conCommandRefAbstract;
|
||||
pInfo->command = conCommand;
|
||||
pInfo->server_only = server_only;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ConCommandInfo* ConCommandManager::FindCommand(const char* name)
|
||||
bool ConCommandManager::RemoveValveCommand(const char* name)
|
||||
{
|
||||
ConCommandInfo* p_info = m_cmd_lookup[std::string(name)];
|
||||
auto hFoundCommand = globals::cvars->FindCommand(name);
|
||||
|
||||
if (p_info == nullptr) {
|
||||
auto found = std::find_if(m_cmd_list.begin(), m_cmd_list.end(), [&](ConCommandInfo* info) {
|
||||
return V_strcasecmp(info->command->GetName(), name) == 0;
|
||||
});
|
||||
if (found != m_cmd_list.end()) {
|
||||
return *found;
|
||||
}
|
||||
|
||||
ConCommandHandle p_cmd = globals::cvars->FindCommand(name);
|
||||
if (!p_cmd.IsValid())
|
||||
return nullptr;
|
||||
|
||||
p_info = new ConCommandInfo();
|
||||
p_info->command = globals::cvars->GetCommand(p_cmd);
|
||||
|
||||
p_info->p_cmd = *p_info->command->GetRef();
|
||||
p_info->callback_pre = globals::callbackManager.CreateCallback(name);
|
||||
p_info->callback_post = globals::callbackManager.CreateCallback(name);
|
||||
p_info->server_only = false;
|
||||
|
||||
m_cmd_list.push_back(p_info);
|
||||
m_cmd_lookup[name] = p_info;
|
||||
|
||||
return p_info;
|
||||
if (!hFoundCommand.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return p_info;
|
||||
globals::cvars->UnregisterConCommand(hFoundCommand);
|
||||
|
||||
auto pInfo = m_cmd_lookup[std::string(name)];
|
||||
if (!pInfo) {
|
||||
return true;
|
||||
}
|
||||
|
||||
pInfo->command = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int ConCommandManager::GetCommandClient() { return last_command_client; }
|
||||
|
||||
void ConCommandManager::SetCommandClient(int client) { last_command_client = client + 1; }
|
||||
|
||||
bool ConCommandManager::InternalDispatch(CPlayerSlot slot, const CCommand* args)
|
||||
HookResult ConCommandManager::ExecuteCommandCallbacks(const char* name, const CCommandContext& ctx,
|
||||
const CCommand& args, HookMode mode)
|
||||
{
|
||||
const char* cmd = args->Arg(0);
|
||||
CSSHARP_CORE_TRACE("[ConCommandManager::ExecuteCommandCallbacks][{}]: {}",
|
||||
mode == Pre ? "Pre" : "Post", name);
|
||||
ConCommandInfo* pInfo = m_cmd_lookup[std::string(name)];
|
||||
|
||||
ConCommandInfo* p_info = m_cmd_lookup[cmd];
|
||||
if (p_info == nullptr) {
|
||||
if (slot.Get() == 0 && !globals::engine->IsDedicatedServer())
|
||||
return false;
|
||||
HookResult result = HookResult::Continue;
|
||||
|
||||
for (ConCommandInfo* cmdInfo : m_cmd_list) {
|
||||
if ((cmdInfo != nullptr) && strcasecmp(cmdInfo->command->GetName(), cmd) == 0) {
|
||||
p_info = cmdInfo;
|
||||
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 (!p_info) {
|
||||
return false;
|
||||
if (!pInfo) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int realClient = slot.Get();
|
||||
auto pCallback = mode == HookMode::Pre ? pInfo->callback_pre : pInfo->callback_post;
|
||||
|
||||
bool result = false;
|
||||
if (p_info->callback_pre) {
|
||||
p_info->callback_pre->ScriptContext().Reset();
|
||||
p_info->callback_pre->ScriptContext().SetArgument(0, realClient);
|
||||
p_info->callback_pre->ScriptContext().SetArgument(1, args);
|
||||
p_info->callback_pre->Execute(false);
|
||||
pCallback->Reset();
|
||||
pCallback->ScriptContext().Push(ctx.GetPlayerSlot().Get());
|
||||
pCallback->ScriptContext().Push(&args);
|
||||
|
||||
result = p_info->callback_pre->ScriptContext().GetResult<bool>();
|
||||
for (auto fnMethodToCall : pCallback->GetFunctions()) {
|
||||
if (!fnMethodToCall)
|
||||
continue;
|
||||
fnMethodToCall(&pCallback->ScriptContextStruct());
|
||||
|
||||
auto thisResult = pCallback->ScriptContext().GetResult<HookResult>();
|
||||
|
||||
if (thisResult >= HookResult::Handled) {
|
||||
return result;
|
||||
} else if (thisResult > result) {
|
||||
result = thisResult;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ConCommandManager::InternalDispatch_Post(CPlayerSlot slot, const CCommand* args)
|
||||
void ConCommandManager::Hook_DispatchConCommand(ConCommandHandle cmd, const CCommandContext& ctx,
|
||||
const CCommand& args)
|
||||
{
|
||||
const char* cmd = args->Arg(0);
|
||||
const char* name = args.Arg(0);
|
||||
|
||||
ConCommandInfo* p_info = m_cmd_lookup[cmd];
|
||||
if (p_info == nullptr) {
|
||||
if (slot.Get() == 0 && !globals::engine->IsDedicatedServer())
|
||||
return false;
|
||||
CSSHARP_CORE_TRACE("[ConCommandManager::Hook_DispatchConCommand]: {}", name);
|
||||
|
||||
for (ConCommandInfo* cmdInfo : m_cmd_list) {
|
||||
if ((cmdInfo != nullptr) && strcasecmp(cmdInfo->command->GetName(), cmd) == 0) {
|
||||
p_info = cmdInfo;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
auto result = ExecuteCommandCallbacks(name, ctx, args, HookMode::Pre);
|
||||
if (result >= HookResult::Handled) {
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
int realClient = slot.Get();
|
||||
|
||||
bool result = false;
|
||||
if (p_info->callback_post) {
|
||||
p_info->callback_post->ScriptContext().Reset();
|
||||
p_info->callback_post->ScriptContext().SetArgument(0, realClient);
|
||||
p_info->callback_post->ScriptContext().SetArgument(1, args);
|
||||
p_info->callback_post->Execute(false);
|
||||
|
||||
result = p_info->callback_post->ScriptContext().GetResult<bool>();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ConCommandManager::DispatchClientCommand(CPlayerSlot slot, const char* cmd,
|
||||
const CCommand* args)
|
||||
void ConCommandManager::Hook_DispatchConCommand_Post(ConCommandHandle cmd,
|
||||
const CCommandContext& ctx,
|
||||
const CCommand& args)
|
||||
{
|
||||
ConCommandInfo* p_info = m_cmd_lookup[cmd];
|
||||
if (p_info == nullptr) {
|
||||
auto found =
|
||||
std::find_if(m_cmd_list.begin(), m_cmd_list.end(), [&](const ConCommandInfo* info) {
|
||||
return V_strcasecmp(info->command->GetName(), cmd) == 0;
|
||||
});
|
||||
if (found == m_cmd_list.end()) {
|
||||
return false;
|
||||
}
|
||||
const char* name = args.Arg(0);
|
||||
|
||||
p_info = *found;
|
||||
auto result = ExecuteCommandCallbacks(name, ctx, args, HookMode::Post);
|
||||
if (result >= HookResult::Handled) {
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
if (p_info->server_only)
|
||||
return false;
|
||||
|
||||
bool result = false;
|
||||
if (p_info->callback_pre) {
|
||||
p_info->callback_pre->ScriptContext().Reset();
|
||||
p_info->callback_pre->ScriptContext().Push(slot.Get());
|
||||
p_info->callback_pre->ScriptContext().Push(args);
|
||||
p_info->callback_pre->Execute();
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
if (p_info->callback_post) {
|
||||
p_info->callback_post->ScriptContext().Reset();
|
||||
p_info->callback_post->ScriptContext().Push(slot.Get());
|
||||
p_info->callback_post->ScriptContext().Push(args);
|
||||
p_info->callback_post->Execute();
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
bool ConCommandManager::IsValidValveCommand(const char* name) {
|
||||
ConCommandHandle pCmd = globals::cvars->FindCommand(name);
|
||||
return pCmd.IsValid();
|
||||
}
|
||||
|
||||
} // namespace counterstrikesharp
|
||||
@@ -40,6 +40,16 @@
|
||||
#include <string>
|
||||
#include "playerslot.h"
|
||||
|
||||
struct CaseInsensitiveComparator {
|
||||
bool operator()(const std::string& lhs, const std::string& rhs) const {
|
||||
return std::lexicographical_compare(
|
||||
lhs.begin(), lhs.end(),
|
||||
rhs.begin(), rhs.end(),
|
||||
[](char a, char b) { return std::tolower(a) < std::tolower(b); }
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
namespace counterstrikesharp {
|
||||
class ScriptCallback;
|
||||
|
||||
@@ -47,7 +57,9 @@ class ConCommandInfo {
|
||||
friend class ConCommandManager;
|
||||
|
||||
public:
|
||||
ConCommandInfo() {}
|
||||
ConCommandInfo();
|
||||
ConCommandInfo(bool bNoCallbacks);
|
||||
~ConCommandInfo();
|
||||
|
||||
public:
|
||||
void HookChange(CallbackT callback, bool post);
|
||||
@@ -64,39 +76,27 @@ private:
|
||||
|
||||
class ConCommandManager : public GlobalClass {
|
||||
friend class ConCommandInfo;
|
||||
friend void CommandCallback(const CCommand& command);
|
||||
friend void CommandCallback_Post(const CCommand& command);
|
||||
|
||||
public:
|
||||
ConCommandManager();
|
||||
~ConCommandManager();
|
||||
void OnAllInitialized() override;
|
||||
void OnShutdown() override;
|
||||
ConCommandInfo* AddOrFindCommand(const char* name,
|
||||
const char* description,
|
||||
bool server_only,
|
||||
int flags);
|
||||
bool DispatchClientCommand(CPlayerSlot slot, const char* cmd, const CCommand* args);
|
||||
|
||||
bool InternalDispatch(CPlayerSlot slot, const CCommand* args);
|
||||
|
||||
int GetCommandClient();
|
||||
|
||||
bool InternalDispatch_Post(CPlayerSlot slot, const CCommand* args);
|
||||
|
||||
public:
|
||||
ConCommandInfo* AddCommand(
|
||||
const char* name, const char* description, bool server_only, int flags, CallbackT callback);
|
||||
bool RemoveCommand(const char* name, CallbackT callback);
|
||||
ConCommandInfo* FindCommand(const char* name);
|
||||
void AddCommandListener(const char* name, CallbackT callback, HookMode mode);
|
||||
void RemoveCommandListener(const char* name, CallbackT callback, HookMode mode);
|
||||
bool IsValidValveCommand(const char* name);
|
||||
bool AddValveCommand(const char* name, const char* description, bool server_only, int flags);
|
||||
bool RemoveValveCommand(const char* name);
|
||||
void Hook_DispatchConCommand(ConCommandHandle cmd, const CCommandContext& ctx, const CCommand& args);
|
||||
void Hook_DispatchConCommand_Post(ConCommandHandle cmd, const CCommandContext& ctx, const CCommand& args);
|
||||
HookResult ExecuteCommandCallbacks(const char* name, const CCommandContext& ctx,
|
||||
const CCommand& args, HookMode mode);
|
||||
|
||||
private:
|
||||
void SetCommandClient(int client);
|
||||
|
||||
private:
|
||||
int last_command_client;
|
||||
std::vector<ConCommandInfo*> m_cmd_list;
|
||||
std::map<std::string, ConCommandInfo*> m_cmd_lookup;
|
||||
std::map<std::string, ConCommandInfo*, CaseInsensitiveComparator> m_cmd_lookup;
|
||||
ConCommandInfo m_global_cmd = ConCommandInfo(true);
|
||||
};
|
||||
|
||||
} // namespace counterstrikesharp
|
||||
@@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include "core/managers/player_manager.h"
|
||||
#include "core/managers/client_command_manager.h"
|
||||
#include "core/managers/con_command_manager.h"
|
||||
|
||||
#include <public/eiface.h>
|
||||
#include <public/inetchannelinfo.h>
|
||||
@@ -287,8 +287,10 @@ void PlayerManager::OnClientCommand(CPlayerSlot slot, const CCommand& args) cons
|
||||
|
||||
const char* cmd = args.Arg(0);
|
||||
|
||||
bool response = globals::clientCommandManager.DispatchClientCommand(slot, cmd, &args);
|
||||
if (response) {
|
||||
auto result = globals::conCommandManager.ExecuteCommandCallbacks(
|
||||
cmd, CCommandContext(CommandTarget_t::CT_NO_TARGET, slot), args, HookMode::Pre);
|
||||
|
||||
if (result >= HookResult::Handled) {
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include <eiface.h>
|
||||
|
||||
#include "core/managers/client_command_manager.h"
|
||||
#include "scripting/autonative.h"
|
||||
#include "scripting/callback_manager.h"
|
||||
#include "core/managers/con_command_manager.h"
|
||||
@@ -26,7 +25,7 @@
|
||||
|
||||
namespace counterstrikesharp {
|
||||
|
||||
static ConCommandInfo* AddCommand(ScriptContext& script_context)
|
||||
static void AddCommand(ScriptContext& script_context)
|
||||
{
|
||||
auto name = script_context.GetArgument<const char*>(0);
|
||||
auto description = script_context.GetArgument<const char*>(1);
|
||||
@@ -37,7 +36,8 @@ static ConCommandInfo* AddCommand(ScriptContext& script_context)
|
||||
CSSHARP_CORE_TRACE("Adding command {}, {}, {}, {}, {}", name, description, server_only, flags,
|
||||
(void*)callback);
|
||||
|
||||
return globals::conCommandManager.AddCommand(name, description, server_only, flags, callback);
|
||||
globals::conCommandManager.AddValveCommand(name, description, server_only, flags);
|
||||
globals::conCommandManager.AddCommandListener(name, callback, HookMode::Pre);
|
||||
}
|
||||
|
||||
static void RemoveCommand(ScriptContext& script_context)
|
||||
@@ -45,7 +45,8 @@ static void RemoveCommand(ScriptContext& script_context)
|
||||
auto name = script_context.GetArgument<const char*>(0);
|
||||
auto callback = script_context.GetArgument<CallbackT>(1);
|
||||
|
||||
globals::conCommandManager.RemoveCommand(name, callback);
|
||||
globals::conCommandManager.RemoveCommandListener(name, callback, HookMode::Pre);
|
||||
globals::conCommandManager.RemoveValveCommand(name);
|
||||
}
|
||||
|
||||
static void AddCommandListener(ScriptContext& script_context)
|
||||
@@ -54,7 +55,7 @@ static void AddCommandListener(ScriptContext& script_context)
|
||||
auto callback = script_context.GetArgument<CallbackT>(1);
|
||||
auto post = script_context.GetArgument<bool>(2);
|
||||
|
||||
globals::clientCommandManager.AddCommandListener(name, callback, post);
|
||||
globals::conCommandManager.AddCommandListener(name, callback, post ? HookMode::Post : HookMode::Pre);
|
||||
}
|
||||
|
||||
static void RemoveCommandListener(ScriptContext& script_context)
|
||||
@@ -63,7 +64,7 @@ static void RemoveCommandListener(ScriptContext& script_context)
|
||||
auto callback = script_context.GetArgument<CallbackT>(1);
|
||||
auto post = script_context.GetArgument<bool>(2);
|
||||
|
||||
globals::clientCommandManager.RemoveCommandListener(name, callback, post);
|
||||
globals::conCommandManager.RemoveCommandListener(name, callback, post ? HookMode::Post : HookMode::Pre);
|
||||
}
|
||||
|
||||
static int CommandGetArgCount(ScriptContext& script_context)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ADD_COMMAND: name:string,description:string,serverOnly:bool,flags:int,callback:callback -> pointer
|
||||
ADD_COMMAND: name:string,description:string,serverOnly:bool,flags:int,callback:callback -> void
|
||||
REMOVE_COMMAND: name:string,callback:callback -> void
|
||||
ADD_COMMAND_LISTENER: cmd:string, callback:callback, post:bool -> void
|
||||
REMOVE_COMMAND_LISTENER: cmd:string, callback:callback, post:bool -> void
|
||||
|
||||
@@ -40,6 +40,11 @@ enum HookResult {
|
||||
Stop = 4,
|
||||
};
|
||||
|
||||
enum HookMode {
|
||||
Pre = 0,
|
||||
Post = 1,
|
||||
};
|
||||
|
||||
inline uint32_t hash_string(const char *string) {
|
||||
unsigned long result = 5381;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user