Compare commits

...

4 Commits
v1.0.49 ... v53

Author SHA1 Message Date
Nexd
0ddf6bcdfa fix: new signature for CBaseModelEntity_SetModel (#84) 2023-11-15 15:18:03 +10:00
Roflmuffin
98661cd069 fix: public and silent triggers (finally) 2023-11-14 22:29:59 +10:00
Roflmuffin
86a5699b40 feat: re-add global command listener 2023-11-14 21:15:06 +10:00
Roflmuffin
414710d05c hotfix: wrap vfunc creation in try catch to prevent all vfuncs from erroring 2023-11-13 21:40:33 +10:00
7 changed files with 113 additions and 44 deletions

View File

@@ -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": {

View File

@@ -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)

View File

@@ -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;

View File

@@ -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")]

View File

@@ -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

View File

@@ -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,

View File

@@ -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