mirror of
https://github.com/rehlds/rehlds.git
synced 2025-01-04 02:55:50 +03:00
Add tab completion support in launcher. (#393)
Add tab completion support in launcher.
This commit is contained in:
parent
fb0c81aec9
commit
08825fdf0d
@ -130,13 +130,22 @@ void CTextConsole::ReceiveBackspace()
|
|||||||
|
|
||||||
void CTextConsole::ReceiveTab()
|
void CTextConsole::ReceiveTab()
|
||||||
{
|
{
|
||||||
|
#ifndef LAUNCHER_FIXES
|
||||||
if (!m_System)
|
if (!m_System)
|
||||||
return;
|
return;
|
||||||
|
#else
|
||||||
|
if (!rehldsFuncs || !m_nConsoleTextLen)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
ObjectList matches;
|
ObjectList matches;
|
||||||
m_szConsoleText[ m_nConsoleTextLen ] = '\0';
|
m_szConsoleText[ m_nConsoleTextLen ] = '\0';
|
||||||
|
#ifndef LAUNCHER_FIXES
|
||||||
m_System->GetCommandMatches(m_szConsoleText, &matches);
|
m_System->GetCommandMatches(m_szConsoleText, &matches);
|
||||||
|
#else
|
||||||
|
rehldsFuncs->GetCommandMatches(m_szConsoleText, &matches);
|
||||||
|
#endif
|
||||||
if (matches.IsEmpty())
|
if (matches.IsEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -159,15 +168,26 @@ void CTextConsole::ReceiveTab()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
int nLongestCmd = 0;
|
int nLongestCmd = 0;
|
||||||
|
int nSmallestCmd = 0;
|
||||||
int nCurrentColumn;
|
int nCurrentColumn;
|
||||||
int nTotalColumns;
|
int nTotalColumns;
|
||||||
|
char szCommonCmd[256];//Should be enough.
|
||||||
|
char szFormatCmd[256];
|
||||||
|
char *pszSmallestCmd;
|
||||||
char *pszCurrentCmd = (char *)matches.GetFirst();
|
char *pszCurrentCmd = (char *)matches.GetFirst();
|
||||||
|
nSmallestCmd = strlen(pszCurrentCmd);
|
||||||
|
pszSmallestCmd = pszCurrentCmd;
|
||||||
while (pszCurrentCmd)
|
while (pszCurrentCmd)
|
||||||
{
|
{
|
||||||
if ((int)strlen(pszCurrentCmd) > nLongestCmd)
|
if ((int)strlen(pszCurrentCmd) > nLongestCmd)
|
||||||
|
{
|
||||||
nLongestCmd = strlen(pszCurrentCmd);
|
nLongestCmd = strlen(pszCurrentCmd);
|
||||||
|
}
|
||||||
|
if ((int)strlen(pszCurrentCmd) < nSmallestCmd)
|
||||||
|
{
|
||||||
|
nSmallestCmd = strlen(pszCurrentCmd);
|
||||||
|
pszSmallestCmd = pszCurrentCmd;
|
||||||
|
}
|
||||||
pszCurrentCmd = (char *)matches.GetNext();
|
pszCurrentCmd = (char *)matches.GetNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,13 +195,11 @@ void CTextConsole::ReceiveTab()
|
|||||||
nCurrentColumn = 0;
|
nCurrentColumn = 0;
|
||||||
|
|
||||||
Echo("\n");
|
Echo("\n");
|
||||||
|
Q_strcpy(szCommonCmd, pszSmallestCmd);
|
||||||
// Would be nice if these were sorted, but not that big a deal
|
// Would be nice if these were sorted, but not that big a deal
|
||||||
pszCurrentCmd = (char *)matches.GetFirst();
|
pszCurrentCmd = (char *)matches.GetFirst();
|
||||||
|
|
||||||
while (pszCurrentCmd)
|
while (pszCurrentCmd)
|
||||||
{
|
{
|
||||||
char szFormatCmd[256];
|
|
||||||
if (++nCurrentColumn > nTotalColumns)
|
if (++nCurrentColumn > nTotalColumns)
|
||||||
{
|
{
|
||||||
Echo("\n");
|
Echo("\n");
|
||||||
@ -190,17 +208,25 @@ void CTextConsole::ReceiveTab()
|
|||||||
|
|
||||||
_snprintf(szFormatCmd, sizeof(szFormatCmd), "%-*s ", nLongestCmd, pszCurrentCmd);
|
_snprintf(szFormatCmd, sizeof(szFormatCmd), "%-*s ", nLongestCmd, pszCurrentCmd);
|
||||||
Echo(szFormatCmd);
|
Echo(szFormatCmd);
|
||||||
|
for (char *pCur = pszCurrentCmd, *pCommon = szCommonCmd; (*pCur&&*pCommon); pCur++, pCommon++)
|
||||||
|
{
|
||||||
|
if (*pCur != *pCommon)
|
||||||
|
{
|
||||||
|
*pCommon = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
pszCurrentCmd = (char *)matches.GetNext();
|
pszCurrentCmd = (char *)matches.GetNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
Echo("\n");
|
Echo("\n");
|
||||||
Echo(m_szConsoleText);
|
if (Q_strcmp(szCommonCmd, m_szConsoleText))
|
||||||
|
{
|
||||||
|
Q_strcpy(m_szConsoleText, szCommonCmd);
|
||||||
|
m_nConsoleTextLen = Q_strlen(szCommonCmd);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO:
|
Echo(m_szConsoleText);
|
||||||
// Tack on 'common' chars in all the matches, i.e. if I typed 'con' and all the
|
|
||||||
// matches begin with 'connect_' then print the matches but also complete the
|
|
||||||
// command up to that point at least.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_nCursorPosition = m_nConsoleTextLen;
|
m_nCursorPosition = m_nConsoleTextLen;
|
||||||
|
@ -9,5 +9,8 @@ typedef void (*SleepType)(int msec);
|
|||||||
|
|
||||||
extern bool g_bVGui;
|
extern bool g_bVGui;
|
||||||
extern IDedicatedServerAPI *engineAPI;
|
extern IDedicatedServerAPI *engineAPI;
|
||||||
|
#ifdef LAUNCHER_FIXES
|
||||||
|
extern IRehldsApi *rehldsApi;
|
||||||
|
extern const RehldsFuncs_t* rehldsFuncs;
|
||||||
|
#endif
|
||||||
#endif // DEDICATED_H
|
#endif // DEDICATED_H
|
||||||
|
@ -12,6 +12,12 @@
|
|||||||
#include "idedicatedexports.h"
|
#include "idedicatedexports.h"
|
||||||
#include "icommandline.h"
|
#include "icommandline.h"
|
||||||
|
|
||||||
|
#ifdef LAUNCHER_FIXES
|
||||||
|
struct DLL_FUNCTIONS;
|
||||||
|
#include "cvardef.h"
|
||||||
|
#include "rehlds_api.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "sys_ded.h"
|
#include "sys_ded.h"
|
||||||
#include "icommandline.h"
|
#include "icommandline.h"
|
||||||
#include "textconsole.h"
|
#include "textconsole.h"
|
||||||
|
@ -8,6 +8,10 @@ bool gbAppHasBeenTerminated = false;
|
|||||||
|
|
||||||
CSysModule *g_pEngineModule = nullptr;
|
CSysModule *g_pEngineModule = nullptr;
|
||||||
IDedicatedServerAPI *engineAPI = nullptr;
|
IDedicatedServerAPI *engineAPI = nullptr;
|
||||||
|
#ifdef LAUNCHER_FIXES
|
||||||
|
IRehldsApi *rehldsApi = nullptr;
|
||||||
|
const RehldsFuncs_t* rehldsFuncs = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
IFileSystem *g_pFileSystemInterface = nullptr;
|
IFileSystem *g_pFileSystemInterface = nullptr;
|
||||||
CSysModule *g_pFileSystemModule = nullptr;
|
CSysModule *g_pFileSystemModule = nullptr;
|
||||||
@ -92,8 +96,23 @@ int RunServer()
|
|||||||
RunVGUIFrame();
|
RunVGUIFrame();
|
||||||
|
|
||||||
if (engineFactory)
|
if (engineFactory)
|
||||||
|
{
|
||||||
engineAPI = (IDedicatedServerAPI *)engineFactory(VENGINE_HLDS_API_VERSION, NULL);
|
engineAPI = (IDedicatedServerAPI *)engineFactory(VENGINE_HLDS_API_VERSION, NULL);
|
||||||
|
#ifdef LAUNCHER_FIXES
|
||||||
|
rehldsApi = (IRehldsApi *)engineFactory(VREHLDS_HLDS_API_VERSION, NULL);
|
||||||
|
if (rehldsApi)
|
||||||
|
{
|
||||||
|
if (rehldsApi->GetMajorVersion() != REHLDS_API_VERSION_MAJOR || rehldsApi->GetMinorVersion() < REHLDS_API_VERSION_MINOR)
|
||||||
|
{
|
||||||
|
rehldsApi = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rehldsFuncs = rehldsApi->GetFuncs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
RunVGUIFrame();
|
RunVGUIFrame();
|
||||||
if (!engineAPI)
|
if (!engineAPI)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -33,9 +33,10 @@
|
|||||||
#include "FlightRecorder.h"
|
#include "FlightRecorder.h"
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
#include "ObjectList.h"
|
||||||
|
|
||||||
#define REHLDS_API_VERSION_MAJOR 3
|
#define REHLDS_API_VERSION_MAJOR 3
|
||||||
#define REHLDS_API_VERSION_MINOR 1
|
#define REHLDS_API_VERSION_MINOR 2
|
||||||
|
|
||||||
//Steam_NotifyClientConnect hook
|
//Steam_NotifyClientConnect hook
|
||||||
typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect;
|
typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect;
|
||||||
@ -283,6 +284,7 @@ struct RehldsFuncs_t {
|
|||||||
void(*SV_UpdateUserInfo)(IGameClient *pGameClient);
|
void(*SV_UpdateUserInfo)(IGameClient *pGameClient);
|
||||||
bool(*StripUnprintableAndSpace)(char *pch);
|
bool(*StripUnprintableAndSpace)(char *pch);
|
||||||
void(*Cmd_RemoveCmd)(const char *cmd_name);
|
void(*Cmd_RemoveCmd)(const char *cmd_name);
|
||||||
|
void(*GetCommandMatches)(const char *string, ObjectList *pMatchList);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IRehldsApi {
|
class IRehldsApi {
|
||||||
|
@ -158,6 +158,29 @@ void EXT_FUNC Rehlds_RegisterPluginApi(const char *name, void *impl) {
|
|||||||
api->impl = impl;
|
api->impl = impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EXT_FUNC GetCommandMatches_api(const char *string, ObjectList *pMatchList)
|
||||||
|
{
|
||||||
|
if (!string || !string[0])
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto TextLen = Q_strlen(string);
|
||||||
|
for (auto EngCmd = Cmd_GetFirstCmd(); EngCmd; EngCmd = EngCmd->next)
|
||||||
|
{
|
||||||
|
if (!Q_strnicmp(EngCmd->name, string, TextLen))
|
||||||
|
{
|
||||||
|
pMatchList->Add((void*)(EngCmd->name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto EngCvar = GetCvarVars_api(); EngCvar; EngCvar = EngCvar->next)
|
||||||
|
{
|
||||||
|
if (!Q_strnicmp(EngCvar->name, string, TextLen))
|
||||||
|
{
|
||||||
|
pMatchList->Add((void*)(EngCvar->name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CRehldsServerStatic g_RehldsServerStatic;
|
CRehldsServerStatic g_RehldsServerStatic;
|
||||||
CRehldsServerData g_RehldsServerData;
|
CRehldsServerData g_RehldsServerData;
|
||||||
CRehldsHookchains g_RehldsHookchains;
|
CRehldsHookchains g_RehldsHookchains;
|
||||||
@ -211,7 +234,8 @@ RehldsFuncs_t g_RehldsApiFuncs =
|
|||||||
&SV_EmitSound2_api,
|
&SV_EmitSound2_api,
|
||||||
&SV_UpdateUserInfo_api,
|
&SV_UpdateUserInfo_api,
|
||||||
&StripUnprintableAndSpace_api,
|
&StripUnprintableAndSpace_api,
|
||||||
&Cmd_RemoveCmd
|
&Cmd_RemoveCmd,
|
||||||
|
&GetCommandMatches_api
|
||||||
};
|
};
|
||||||
|
|
||||||
bool EXT_FUNC SV_EmitSound2_internal(edict_t *entity, IGameClient *pReceiver, int channel, const char *sample, float volume, float attenuation, int flags, int pitch, int emitFlags, const float *pOrigin)
|
bool EXT_FUNC SV_EmitSound2_internal(edict_t *entity, IGameClient *pReceiver, int channel, const char *sample, float volume, float attenuation, int flags, int pitch, int emitFlags, const float *pOrigin)
|
||||||
|
Loading…
Reference in New Issue
Block a user