SA-MP/server/console.cpp
2023-12-01 20:43:33 +08:00

401 lines
8.9 KiB
C++

#include "main.h"
extern bool bQuitApp;
void con_exit()
{
bQuitApp = true;
}
void con_echo()
{
char* arg = strtok(NULL, "");
if (arg)
{
logprintf("%s", arg);
} else {
logprintf("");
}
}
void con_exec()
{
char* arg = strtok(NULL, " ");
if (arg)
{
char tmp[1025];
char tmpvarname[1025];
sprintf(tmp, "%s.cfg", arg);
FILE* f = fopen(tmp, "r");
if (!f)
{
logprintf("Unable to exec file '%s'.", tmp);
} else {
memset(tmp, 0, sizeof(tmp));
while (fgets(tmp, 1024, f))
{
int len = strlen(tmp);
if (len > 1024) continue;
if (len > 0 && tmp[len-1] == '\n')
tmp[strlen(tmp)-1] = 0;
len = strlen(tmp);
if (len > 0 && tmp[len-1] == '\r')
tmp[strlen(tmp)-1] = 0;
if (tmp[0] == 0)
continue;
// If the line has a comment, finish it there.
for (size_t i=0; i<strlen(tmp)-1; i++)
{
if (((tmp[i] == '/') && (tmp[i+1] == '/')) || tmp[i] == '#')
{
tmp[i] = 0;
break;
}
}
if (strlen(tmp) > 2)
{
if ((tmp[0] != '/') && (tmp[1] != '/')) {
memset(tmpvarname, 0, sizeof(tmpvarname));
for(int i = 0; tmp[i] != '\0'; i++)
{
if (tmp[i] == ' ')
{
tmpvarname[i] = '\0';
break;
}
tmpvarname[i] = tmp[i];
}
if (pConsole->FindVariable(tmpvarname))
{
pConsole->Execute(tmp);
}
}
}
memset(tmp, 0, sizeof(tmp));
}
fclose(f);
}
} else {
logprintf("Usage:");
logprintf(" exec <filename>");
}
}
void con_kick() {} // TODO: con_kick W: 0048A530 L: 0809ECB0
void con_ban() {} // TODO: con_ban W: 0048A5D0 L: 0809ED80
void con_banip() {} // TODO: con_banip W: 0048A740 L: 0809EF40
void con_unbanip() {} // TODO: con_unbanip W: 0048A790 L: 0809EFB0
void con_gmx() {} // TODO: con_gmx W: 0048A7D0 L: 0809F000
void con_changemode() {} // TODO: con_changemode W: 0048A800 L: 0809F050
void con_cmdlist();
void con_varlist()
{
pConsole->PrintVariableList();
}
void con_say() {} // TODO: con_say W: 0048A830 L: 0809F0A0
void con_reloadbans() {} // TODO: con_reloadbans W: 0048A880 L: 0809F110
void con_reloadlog() {
LoadLogFile();
}
void con_players() {} // TODO: con_players W: 0048A8A0 L: 0809F140
void con_gravity() {} // TODO: con_gravity W: 0048A950 L: 0809F220
void con_weather() {} // TODO: con_weather W: 0048A980 L: 0809F260
void con_loadfs() {} // TODO: con_loadfs W: 0048A9B0 L: 0809F2A0
void con_reloadfs() {} // TODO: con_reloadfs W: 0048AA20 L: 0809F330
void con_unloadfs() {} // TODO: con_unloadfs W: 0048AAC0 L: 0809F410
#define CON_CMDFLAG_DEBUG 1
struct ConsoleCommand_s
{
char CmdName[255];
DWORD CmdFlags;
void (*CmdFunc)();
} ConsoleCommands[] = {
{"echo", 0, con_echo},
{"exec", 0, con_exec},
{"cmdlist", 0, con_cmdlist},
{"varlist", 0, con_varlist},
{"exit", 0, con_exit},
{"kick", 0, con_kick},
{"ban", 0, con_ban},
{"gmx", 0, con_gmx},
{"changemode", 0, con_changemode},
{"say", 0, con_say},
{"reloadbans", 0, con_reloadbans},
{"reloadlog", 0, con_reloadlog},
{"players", 0, con_players},
{"banip", 0, con_banip},
{"unbanip", 0, con_unbanip},
{"gravity", 0, con_gravity},
{"weather", 0, con_weather},
{"loadfs", 0, con_loadfs},
{"unloadfs", 0, con_unloadfs},
{"reloadfs", 0, con_reloadfs},
};
void con_cmdlist()
{
logprintf("Console Commands:");
for (int i=0; i<ARRAY_SIZE(ConsoleCommands); i++)
{
logprintf(" %s%s", ConsoleCommands[i].CmdName, (ConsoleCommands[i].CmdFlags & CON_CMDFLAG_DEBUG)?" (DEBUG)":"");
}
logprintf("");
}
CConsole::CConsole()
{
}
CConsole::~CConsole()
{
ConsoleVariables.clear();
}
ConsoleVariable_s* CConsole::FindVariable(char* pVarName)
{
char VarName[256];
strncpy(VarName, pVarName, 255);
strlwr(VarName);
StringConvarMap::iterator itor;
itor = ConsoleVariables.find(VarName);
if (itor != ConsoleVariables.end())
{
return itor->second;
}
return NULL;
}
void CConsole::PrintVariableList()
{
char val[1034]; // Max str size of 1024 + the (string) tag.
logprintf("Console Variables:");
StringConvarMap::iterator itor;
for (itor = ConsoleVariables.begin(); itor != ConsoleVariables.end(); itor++)
{
val[0] = 0;
switch (itor->second->VarType)
{
case CON_VARTYPE_FLOAT:
sprintf(val, "%f (float)", *(float*)itor->second->VarPtr);
break;
case CON_VARTYPE_INT:
sprintf(val, "%d (int)", *(int*)itor->second->VarPtr);
break;
case CON_VARTYPE_BOOL:
sprintf(val, "%d (bool)", *(bool*)itor->second->VarPtr);
break;
case CON_VARTYPE_STRING:
sprintf(val, "\"%s\" (string)", (char*)itor->second->VarPtr);
break;
}
const char* VarName = itor->first.c_str();
logprintf(" %s\t%s= %s%s%s%s", VarName, (strlen(VarName)<6)?"\t":"", val,
(itor->second->VarFlags & CON_VARFLAG_READONLY)?" (read-only)":"",
(itor->second->VarFlags & CON_VARFLAG_DEBUG)?" (debug)":"",
(itor->second->VarFlags & CON_VARFLAG_RULE)?" (rule)":"");
}
logprintf("");
}
void CConsole::AddVariable(char* pVarName, CON_VARTYPE VarType, DWORD VarFlags, void* VarPtr,
VARCHANGEFUNC VarChangeFunc)
{
char VarName[256];
strncpy(VarName, pVarName, 255);
strlwr(VarName);
if (FindVariable(VarName) != NULL)
{
logprintf("Unable to add console variable '%s'. Already exists.", VarName);
return;
}
ConsoleVariable_s* ConVar = new ConsoleVariable_s;
ConVar->VarType = VarType;
ConVar->VarFlags = VarFlags;
ConVar->VarPtr = VarPtr;
ConVar->VarChangeFunc = VarChangeFunc;
if (VarChangeFunc)
VarChangeFunc();
ConsoleVariables.insert(StringConvarMap::value_type(VarName, ConVar));
}
char* CConsole::AddStringVariable(char* pVarName, DWORD VarFlags, char* pInitStr,
VARCHANGEFUNC VarChangeFunc)
{
char* str;
if (!pInitStr)
{
// Empty string
str = (char*)malloc(1);
str[0] = 0;
} else {
str = (char*)malloc(strlen(pInitStr)+1);
strcpy(str,pInitStr);
}
AddVariable(pVarName, CON_VARTYPE_STRING, VarFlags, (void*)str, VarChangeFunc);
return str;
}
void CConsole::RemoveVariable(char* pVarName)
{
ConsoleVariable_s* ConVar = FindVariable(pVarName);
if (ConVar != NULL)
{
if (ConVar->VarType == CON_VARTYPE_STRING)
{
if (ConVar->VarPtr != NULL)
free(ConVar->VarPtr);
}
char VarName[255];
strncpy(VarName, pVarName, 255);
strlwr(VarName);
delete ConVar;
ConsoleVariables.erase(VarName);
}
}
void CConsole::ModifyVariableFlags(char* pVarName, DWORD VarFlags)
{
ConsoleVariable_s* ConVar = FindVariable(pVarName);
if (ConVar != NULL)
{
ConVar->VarFlags = VarFlags;
}
}
char* CConsole::GetStringVariable(char* pVarName)
{
ConsoleVariable_s* ConVar = FindVariable(pVarName);
if (ConVar != NULL)
{
if (ConVar->VarType == CON_VARTYPE_STRING)
return (char*)ConVar->VarPtr;
}
return NULL;
}
void CConsole::SetStringVariable(char* pVarName, char* pString)
{
ConsoleVariable_s* ConVar = FindVariable(pVarName);
if (ConVar != NULL)
{
if (ConVar->VarType == CON_VARTYPE_STRING)
{
if (ConVar->VarPtr != NULL)
free(ConVar->VarPtr);
char* str = (char*)malloc(strlen(pString)+1);
strcpy(str, pString);
ConVar->VarPtr = str;
}
}
}
float CConsole::GetFloatVariable(char* pVarName)
{
ConsoleVariable_s* ConVar = FindVariable(pVarName);
if (ConVar != NULL)
{
if (ConVar->VarType == CON_VARTYPE_FLOAT)
return *(float*)ConVar->VarPtr;
}
return 0.0f;
}
void CConsole::SetFloatVariable(char* pVarName, float fFloat)
{
ConsoleVariable_s* ConVar = FindVariable(pVarName);
if (ConVar != NULL)
{
if (ConVar->VarType == CON_VARTYPE_FLOAT)
*(float*)ConVar->VarPtr = fFloat;
}
}
int CConsole::GetIntVariable(char* pVarName)
{
ConsoleVariable_s* ConVar = FindVariable(pVarName);
if (ConVar != NULL)
{
if (ConVar->VarType == CON_VARTYPE_INT)
return *(int*)ConVar->VarPtr;
}
return 0;
}
void CConsole::SetIntVariable(char* pVarName, int iInt)
{
ConsoleVariable_s* ConVar = FindVariable(pVarName);
if (ConVar != NULL)
{
if (ConVar->VarType == CON_VARTYPE_INT)
*(int*)ConVar->VarPtr = iInt;
}
}
bool CConsole::GetBoolVariable(char* pVarName)
{
ConsoleVariable_s* ConVar = FindVariable(pVarName);
if (ConVar != NULL)
{
if (ConVar->VarType == CON_VARTYPE_BOOL)
return *(bool*)ConVar->VarPtr;
}
return false;
}
void CConsole::SetBoolVariable(char* pVarName, bool bBool)
{
ConsoleVariable_s* ConVar = FindVariable(pVarName);
if (ConVar != NULL)
{
if (ConVar->VarType == CON_VARTYPE_BOOL)
*(bool*)ConVar->VarPtr = bBool;
}
}
void CConsole::Execute(char* pExecLine)
{
// TODO: CConsole::Execute W: 0048B610 L: 0809FBD0
if (!pExecLine) return;
// Ya can't strtok on a read-only string!
char cpy[256];
memset(cpy,0,sizeof(cpy));
strncpy(cpy, pExecLine, 255);
char* tmp = strtok(cpy, " ");
if(!tmp) return;
char* cmd = strlwr(tmp);
for (int i=0; i<ARRAY_SIZE(ConsoleCommands); i++)
{
if (stricmp(cmd, ConsoleCommands[i].CmdName) == 0)
{
if (ConsoleCommands[i].CmdFlags & 1)
{
#ifndef _DEBUG
logprintf("Unable to execute command '%s'. Debug mode required.", ConsoleCommands[i].CmdName);
return;
#endif
}
ConsoleCommands[i].CmdFunc();
return;
}
}
}