diff --git a/primedev/core/convar/concommand.cpp b/primedev/core/convar/concommand.cpp index 41f54c76a..6e09ef918 100644 --- a/primedev/core/convar/concommand.cpp +++ b/primedev/core/convar/concommand.cpp @@ -145,6 +145,7 @@ void RegisterConCommand( ConCommand* newCommand = new ConCommand; ConCommandConstructor(newCommand, name, callback, helpString, flags, nullptr); newCommand->m_pCompletionCallback = completionCallback; + newCommand->m_nCallbackFlags |= 0x3; // seems to be correct?; derived from client.dll + 0x737267 } ON_DLL_LOAD("engine.dll", ConCommand, (CModule module)) diff --git a/primedev/server/auth/bansystem.cpp b/primedev/server/auth/bansystem.cpp index a45cde939..6e4d16447 100644 --- a/primedev/server/auth/bansystem.cpp +++ b/primedev/server/auth/bansystem.cpp @@ -5,8 +5,11 @@ #include "engine/r2engine.h" #include "client/r2client.h" #include "config/profile.h" +#include "shared/maxplayers.h" #include +#include +#include const char* BANLIST_PATH_SUFFIX = "/banlist.txt"; const char BANLIST_COMMENT_CHAR = '#'; @@ -213,12 +216,59 @@ void ConCommand_clearbanlist(const CCommand& args) g_pBanSystem->ClearBanlist(); } +int ConCommand_banCompletion(const char* const partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]) +{ + const char* space = strchr(partial, ' '); + const char* cmdName = partial; + const char* query = partial + (space == nullptr ? 0 : space - partial) + 1; + + const int queryLength = strlen(query); + const int cmdLength = strlen(cmdName) - queryLength; + + int numCompletions = 0; + for (int i = 0; i < GetMaxPlayers() && numCompletions < COMMAND_COMPLETION_MAXITEMS - 2; i++) + { + CBaseClient* client = &g_pClientArray[i]; + if (client->m_Signon < eSignonState::CONNECTED) + continue; + + if (!strncmp(query, client->m_Name, queryLength)) + { + strncpy(commands[numCompletions], cmdName, cmdLength); + strncpy_s( + commands[numCompletions++] + cmdLength, + COMMAND_COMPLETION_ITEM_LENGTH, + client->m_Name, + COMMAND_COMPLETION_ITEM_LENGTH - cmdLength); + } + + if (!strncmp(query, client->m_UID, queryLength)) + { + strncpy(commands[numCompletions], cmdName, cmdLength); + strncpy_s( + commands[numCompletions++] + cmdLength, + COMMAND_COMPLETION_ITEM_LENGTH, + client->m_UID, + COMMAND_COMPLETION_ITEM_LENGTH - cmdLength); + } + } + + return numCompletions; +} + ON_DLL_LOAD_RELIESON("engine.dll", BanSystem, ConCommand, (CModule module)) { g_pBanSystem = new ServerBanSystem; g_pBanSystem->OpenBanlist(); - RegisterConCommand("ban", ConCommand_ban, "bans a given player by uid or name", FCVAR_GAMEDLL); + RegisterConCommand("ban", ConCommand_ban, "bans a given player by uid or name", FCVAR_GAMEDLL, ConCommand_banCompletion); RegisterConCommand("unban", ConCommand_unban, "unbans a given player by uid", FCVAR_GAMEDLL); RegisterConCommand("clearbanlist", ConCommand_clearbanlist, "clears all uids on the banlist", FCVAR_GAMEDLL); } + +ON_DLL_LOAD_RELIESON("server.dll", KickCompletion, ConCommand, (CModule module)) +{ + ConCommand* kick = g_pCVar->FindCommand("kick"); + kick->m_pCompletionCallback = ConCommand_banCompletion; + kick->m_nCallbackFlags |= 0x3; +}