(svn r2243) -Fix: Rework of console. Use 'help command|variable' to get help about it. You can assign variables with =, ++, --, or just new value. Console parser is now lenient towards typed spaces, and more robust in general (at least readable). Removed the 'set' command, instead implemented all such variables as 'variables'.

- Some variables are really special and cannot be assigned normally, use their callback procedure for assignment/querying. This commit also obsoletes "[1172804] Console set command cleanup"
replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
Darkvater 19 years ago
parent 7a012a3465
commit d102d0c26d

File diff suppressed because it is too large Load Diff

@ -1,108 +1,118 @@
#ifndef CONSOLE_H #ifndef CONSOLE_H
#define CONSOLE_H #define CONSOLE_H
// ** console parser ** // // maximum length of a typed in command
#define ICON_CMDLN_SIZE 255
// maximum length of a totally expanded command
#define ICON_MAX_STREAMSIZE 1024
typedef enum _iconsole_var_types { typedef enum IConsoleVarTypes {
ICONSOLE_VAR_NONE,
ICONSOLE_VAR_BOOLEAN, ICONSOLE_VAR_BOOLEAN,
ICONSOLE_VAR_BYTE, ICONSOLE_VAR_BYTE,
ICONSOLE_VAR_UINT8,
ICONSOLE_VAR_UINT16, ICONSOLE_VAR_UINT16,
ICONSOLE_VAR_UINT32, ICONSOLE_VAR_UINT32,
ICONSOLE_VAR_INT16, ICONSOLE_VAR_INT16,
ICONSOLE_VAR_INT32, ICONSOLE_VAR_INT32,
ICONSOLE_VAR_STRING, ICONSOLE_VAR_STRING
ICONSOLE_VAR_POINTER, } IConsoleVarTypes;
ICONSOLE_VAR_REFERENCE,
ICONSOLE_VAR_UNKNOWN
} _iconsole_var_types;
typedef enum { typedef enum IConsoleModes {
ICONSOLE_FULL, ICONSOLE_FULL,
ICONSOLE_OPENED, ICONSOLE_OPENED,
ICONSOLE_CLOSED ICONSOLE_CLOSED
} _iconsole_modes; } IConsoleModes;
typedef enum _iconsole_hook_types { typedef enum IConsoleHookTypes {
ICONSOLE_HOOK_ACCESS, ICONSOLE_HOOK_ACCESS,
ICONSOLE_HOOK_BEFORE_CHANGE, ICONSOLE_HOOK_PRE_ACTION,
ICONSOLE_HOOK_BEFORE_EXEC, ICONSOLE_HOOK_POST_ACTION
ICONSOLE_HOOK_AFTER_CHANGE, } IConsoleHookTypes;
ICONSOLE_HOOK_AFTER_EXEC
} _iconsole_hook_types; /** --Hooks--
* Hooks are certain triggers get get accessed/executed on either
struct _iconsole_var; * access, before execution/change or after execution/change. This allows
typedef bool (*iconsole_var_hook)(struct _iconsole_var* hook_var); * for general flow of permissions or special action needed in some cases
*/
typedef struct _iconsole_var { typedef bool IConsoleHook(void);
// --------------- // typedef struct IConsoleHooks{
union { IConsoleHook *access; // trigger when accessing the variable/command
void* addr; IConsoleHook *pre; // trigger before the variable/command is changed/executed
bool* bool_; IConsoleHook *post; // trigger after the variable/command is changed/executed
byte* byte_; } IConsoleHooks;
uint16* uint16_;
uint32* uint32_; /** --Commands--
int16* int16_; * Commands are commands, or functions. They get executed once and any
int32* int32_; * effect they produce are carried out. The arguments to the commands
char* string_; * are given to them, each input word seperated by a double-quote (") is an argument
struct _iconsole_var* reference_; * If you want to handle multiple words as one, enclose them in double-quotes
} data; * eg. 'say "hello sexy boy"'
char* name; */
_iconsole_var_types type; typedef bool (IConsoleCmdProc)(byte argc, char *argv[]);
// -------------- //
iconsole_var_hook hook_access; struct IConsoleCmd;
iconsole_var_hook hook_before_change; typedef struct IConsoleCmd {
iconsole_var_hook hook_after_change; char *name; // name of command
// -------------- // struct IConsoleCmd *next; // next command in list
struct _iconsole_var* _next;
bool _malloc; IConsoleCmdProc *proc; // process executed when command is typed
} _iconsole_var; IConsoleHooks hook; // any special trigger action that needs executing
} IConsoleCmd;
struct _iconsole_cmd;
typedef bool (*iconsole_cmd_hook)(struct _iconsole_cmd* hook_cmd); /** --Variables--
* Variables are pointers to real ingame variables which allow for
typedef _iconsole_var* (*_iconsole_cmd_addr)(byte argc, char* argv[], byte argt[]); * changing while ingame. After changing they keep their new value
* and can be used for debugging, gameplay, etc. It accepts:
typedef struct _iconsole_cmd { * - no arguments; just print out current value
// -------------- // * - '= <new value>' to assign a new value to the variable
_iconsole_cmd_addr addr; * - '++' to increase value by one
char* name; * - '--' to decrease value by one
// -------------- // */
iconsole_cmd_hook hook_access; struct IConsoleVar;
iconsole_cmd_hook hook_before_exec; typedef struct IConsoleVar {
iconsole_cmd_hook hook_after_exec; char *name; // name of the variable
// -------------- // struct IConsoleVar *next; // next variable in list
void* _next;
} _iconsole_cmd; void *addr; // the address where the variable is pointing at
uint32 size; // size of the variable, used for strings
void IConsoleAliasRegister(const char* name, const char* cmdline); char *help; // the optional help string shown when requesting information
IConsoleVarTypes type; // type of variable (for correct assignment/output)
typedef struct _iconsole_alias { IConsoleCmdProc *proc; // some variables need really special handling, use a callback function for that
// -------------- // IConsoleHooks hook; // any special trigger action that needs executing
char * cmdline; } IConsoleVar;
char* name;
void* _next; /** --Aliases--
} _iconsole_alias; * Aliases are like shortcuts for complex functions, variable assignments,
* etc. You can use a simple alias to rename a longer command (eg 'lv' for
_iconsole_alias* IConsoleAliasGet(const char* name); * 'list_vars' for example), or concatenate more commands into one
* (eg. 'ng' for 'load %A; unpause; debug_level 5'). Aliases can parse the arguments
* given to them in the command line.
* - "%A - %Z" substitute arguments 1 t/m 26
* - "%+" lists all parameters keeping them seperated
* - "%!" also lists all parameters but presenting them to the aliased command as one argument
* - ";" allows for combining commands (see example 'ng')
*/
struct IConsoleAlias;
typedef struct IConsoleAlias {
char *name; // name of the alias
struct IConsoleAlias *next; // next alias in list
char *cmdline; // command(s) that is/are being aliased
} IConsoleAlias;
// ** console parser ** // // ** console parser ** //
IConsoleCmd *_iconsole_cmds; // list of registred commands
IConsoleVar *_iconsole_vars; // list of registred vars
IConsoleAlias *_iconsole_aliases; // list of registred aliases
_iconsole_cmd* _iconsole_cmds; // list of registred commands // ** console colors/modes ** //
_iconsole_var* _iconsole_vars; // list of registred vars
_iconsole_alias* _iconsole_aliases; // list of registred aliases
// ** console colors ** //
VARDEF byte _iconsole_color_default; VARDEF byte _iconsole_color_default;
VARDEF byte _iconsole_color_error; VARDEF byte _iconsole_color_error;
VARDEF byte _iconsole_color_warning; VARDEF byte _iconsole_color_warning;
VARDEF byte _iconsole_color_debug; VARDEF byte _iconsole_color_debug;
VARDEF byte _iconsole_color_commands; VARDEF byte _iconsole_color_commands;
VARDEF _iconsole_modes _iconsole_mode; VARDEF IConsoleModes _iconsole_mode;
// ** console functions ** // // ** console functions ** //
void IConsoleInit(void); void IConsoleInit(void);
void IConsoleClear(void); void IConsoleClear(void);
void IConsoleFree(void); void IConsoleFree(void);
@ -112,44 +122,42 @@ void IConsoleClose(void);
void IConsoleOpen(void); void IConsoleOpen(void);
// ** console cmd buffer ** // // ** console cmd buffer ** //
void IConsoleCmdBufferAdd(const char* cmd); void IConsoleHistoryAdd(const char *cmd);
void IConsoleCmdBufferNavigate(signed char direction); void IConsoleHistoryNavigate(signed char direction);
// ** console output ** // // ** console output ** //
void IConsolePrint(uint16 color_code, const char* string); void IConsolePrint(uint16 color_code, const char *string);
void CDECL IConsolePrintF(uint16 color_code, const char* s, ...); void CDECL IConsolePrintF(uint16 color_code, const char *s, ...);
void IConsoleDebug(const char* string); void IConsoleDebug(const char *string);
void IConsoleError(const char* string); void IConsoleWarning(const char *string);
void IConsoleWarning(const char* string); void IConsoleError(const char *string);
// *** Commands *** // // *** Commands *** //
void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc);
void IConsoleCmdRegister(const char* name, _iconsole_cmd_addr addr); void IConsoleAliasRegister(const char *name, const char *cmd);
_iconsole_cmd* IConsoleCmdGet(const char* name); IConsoleCmd *IConsoleCmdGet(const char *name);
IConsoleAlias *IConsoleAliasGet(const char *name);
// *** Variables *** // // *** Variables *** //
void IConsoleVarRegister(const char *name, void *addr, IConsoleVarTypes type, const char *help);
void IConsoleVarRegister(const char* name, void* addr, _iconsole_var_types type); void IConsoleVarStringRegister(const char *name, void *addr, uint32 size, const char *help);
void IConsoleVarMemRegister(const char* name, _iconsole_var_types type); IConsoleVar* IConsoleVarGet(const char *name);
void IConsoleVarInsert(_iconsole_var* item_new, const char* name); void IConsoleVarPrintGetValue(const IConsoleVar *var);
_iconsole_var* IConsoleVarGet(const char* name); void IConsoleVarPrintSetValue(const IConsoleVar *var);
_iconsole_var* IConsoleVarAlloc(_iconsole_var_types type);
void IConsoleVarFree(_iconsole_var* var);
void IConsoleVarSetString(_iconsole_var* var, const char* string);
void IConsoleVarSetValue(_iconsole_var* var, int value);
void IConsoleVarDump(const _iconsole_var* var, const char* dump_desc);
// *** Parser *** // // *** Parser *** //
void IConsoleCmdExec(const char *cmdstr);
void IConsoleVarExec(const IConsoleVar *var, byte tokencount, char *token[]);
void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char *tokens[]);
void IConsoleCmdExec(const char* cmdstr); // ** console std lib (register ingame commands/aliases/variables) ** //
// ** console std lib ** //
void IConsoleStdLibRegister(void); void IConsoleStdLibRegister(void);
// ** hook code ** // // ** Hooking code ** //
void IConsoleVarHook(const char* name, _iconsole_hook_types type, iconsole_var_hook proc); void IConsoleCmdHookAdd(const char *name, IConsoleHookTypes type, IConsoleHook *proc);
void IConsoleCmdHook(const char* name, _iconsole_hook_types type, iconsole_cmd_hook proc); void IConsoleVarHookAdd(const char *name, IConsoleHookTypes type, IConsoleHook *proc);
bool IConsoleVarHookHandle(_iconsole_var* hook_var, _iconsole_hook_types type); void IConsoleVarProcAdd(const char *name, IConsoleCmdProc *proc);
bool IConsoleCmdHookHandle(_iconsole_cmd* hook_cmd, _iconsole_hook_types type);
// ** Supporting functions **//
bool GetArgumentInteger(uint32 *value, const char *arg);
#endif /* CONSOLE_H */ #endif /* CONSOLE_H */

File diff suppressed because it is too large Load Diff

@ -1370,21 +1370,6 @@ void NetworkShutDown(void)
} }
#endif #endif
} }
void NetworkChangeCompanyPassword(const char *str)
{
if (strncmp(str, "*", sizeof(_network_player_info[_local_player].password)) == 0) {
_network_player_info[_local_player].password[0] = '\0';
IConsolePrint(_iconsole_color_warning, "Company password protection removed.");
} else {
ttd_strlcpy(_network_player_info[_local_player].password, str, sizeof(_network_player_info[_local_player].password));
IConsolePrintF(_iconsole_color_warning, "Company protected with password '%s'.", _network_player_info[_local_player].password);
}
if (!_network_server)
SEND_COMMAND(PACKET_CLIENT_SET_PASSWORD)(_network_player_info[_local_player].password);
}
#else #else
void ParseConnectionString(const char **player, const char **port, char *connection_string) {} void ParseConnectionString(const char **player, const char **port, char *connection_string) {}

@ -217,6 +217,6 @@ void ParseConnectionString(const char **player, const char **port, char *connect
void NetworkUpdateClientInfo(uint16 client_index); void NetworkUpdateClientInfo(uint16 client_index);
void NetworkAddServer(const char *b); void NetworkAddServer(const char *b);
void NetworkRebuildHostList(void); void NetworkRebuildHostList(void);
void NetworkChangeCompanyPassword(const char *str); bool NetworkChangeCompanyPassword(byte argc, char *argv[]);
#endif /* NETWORK_H */ #endif /* NETWORK_H */

@ -656,7 +656,7 @@ static void PlayerCompanyWndProc(Window *w, WindowEvent *e)
#ifdef ENABLE_NETWORK #ifdef ENABLE_NETWORK
case 2: /* Change company password */ case 2: /* Change company password */
if (*b == 0) *b = '*'; // empty password is a '*' because of console argument if (*b == 0) *b = '*'; // empty password is a '*' because of console argument
NetworkChangeCompanyPassword(b); NetworkChangeCompanyPassword(1, &b);
#endif #endif
} }
} break; } break;

@ -42,4 +42,7 @@ typedef struct SettingDesc {
const void *b; const void *b;
} SettingDesc; } SettingDesc;
void IConsoleSetPatchSetting(const char *name, const char *value);
void IConsoleGetPatchSetting(const char *name);
#endif /* SETTINGS_H */ #endif /* SETTINGS_H */

@ -1033,17 +1033,22 @@ static void PatchesSelectionWndProc(Window *w, WindowEvent *e)
} }
} }
/**
* Network-safe changing of patch-settings.
* @param p1 bytes 0 - 7: the patches type (page) that is being changed (construction, network, ai)
* @param p1 bytes 8 - ..: the actual patch (entry) being set inside the category
* @param p2 the new value for the patch
*/
int32 CmdChangePatchSetting(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdChangePatchSetting(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
const PatchPage *page; byte pcat = p1 & 0xFF;
const PatchEntry *pe; byte pel = (p1 >> 8) & 0xFF;
if (flags & DC_EXEC) { if (pcat >= lengthof(_patches_page)) return 0;
page = &_patches_page[(byte)p1]; if (pel >= _patches_page[pcat].num) return 0;
if (page == NULL) return 0;
pe = &page->entries[(byte)(p1 >> 8)];
if (pe == NULL) return 0;
if (flags & DC_EXEC) {
const PatchEntry *pe = &_patches_page[pcat].entries[pel];
WritePE(pe, (int32)p2); WritePE(pe, (int32)p2);
InvalidateWindow(WC_GAME_OPTIONS, 0); InvalidateWindow(WC_GAME_OPTIONS, 0);
@ -1052,116 +1057,79 @@ int32 CmdChangePatchSetting(int x, int y, uint32 flags, uint32 p1, uint32 p2)
return 0; return 0;
} }
static const PatchEntry *IConsoleGetPatch(const char *name, uint *page, uint *entry)
{
const PatchPage *pp;
const PatchEntry *pe;
for (*page = 0; *page < lengthof(_patches_page); (*page)++) {
pp = &_patches_page[*page];
for (*entry = 0; *entry < pp->num; (*entry)++) {
pe = &pp->entries[*entry];
if (strncmp(pe->console_name, name, sizeof(pe->console_name)) == 0)
return pe;
}
}
return NULL;
}
/* Those 2 functions need to be here, else we have to make some stuff non-static /* Those 2 functions need to be here, else we have to make some stuff non-static
and besides, it is also better to keep stuff like this at the same place */ and besides, it is also better to keep stuff like this at the same place */
void ConsoleSetPatchSetting(char *name, char *value) void IConsoleSetPatchSetting(char *name, const char *value)
{ {
const PatchPage *page; const PatchEntry *pe;
const PatchEntry *pe = NULL; uint page, entry;
bool found = false;
uint i;
unsigned int j;
int val; int val;
/* Search for the name in the patch-settings */ pe = IConsoleGetPatch(name, &page, &entry);
for (i = 0; i < lengthof(_patches_page); i++) {
page = &_patches_page[i];
for (j = 0; j < page->num; j++) {
pe = &page->entries[j];
if (strncmp(pe->console_name, name, sizeof(pe->console_name)) == 0) {
/* We found the name */
found = true;
break;
}
}
if (found)
break;
}
/* We did not found the patch setting */ if (pe == NULL) {
if (!found || pe == NULL) { IConsolePrintF(_iconsole_color_warning, "'%s' is an unknown patch setting.", name);
IConsolePrintF(_iconsole_color_warning, "'%s' is an unkown patch setting", name);
return; return;
} }
val = atoi(value); sscanf(value, "%d", &val);
if (pe->type == PE_CURRENCY) { if (pe->type == PE_CURRENCY) // currency can be different on each client
val /= GetCurrentCurrencyRate(); val /= GetCurrentCurrencyRate();
}
// If an item is playerbased, we do not send it over the network (if any) // If an item is playerbased, we do not send it over the network (if any)
if (pe->flags & PF_PLAYERBASED) { if (pe->flags & PF_PLAYERBASED) {
WritePE(pe, val); WritePE(pe, val);
} else { } else // Else we do
// Else we do DoCommandP(0, page + (entry << 8), val, NULL, CMD_CHANGE_PATCH_SETTING);
DoCommandP(0, i + (j << 8), val, NULL, CMD_CHANGE_PATCH_SETTING);
} {
char tval[20];
const char *tval2 = value;
if (pe->type == PE_BOOL) {
snprintf(tval, sizeof(tval), (val == 1) ? "on" : "off");
tval2 = tval;
}
switch(pe->type) { IConsolePrintF(_iconsole_color_warning, "'%s' changed to: %s", name, tval2);
case PE_BOOL:
if (val == 1)
snprintf(value, sizeof(value), "enabled");
else
snprintf(value, sizeof(value), "disabled");
break;
default:
break;
} }
IConsolePrintF(_iconsole_color_warning, "'%s' changed in:", name);
IConsolePrintF(_iconsole_color_warning, " '%s'", value);
} }
void ConsoleGetPatchSetting(char *name) void IConsoleGetPatchSetting(const char *name)
{ {
const PatchPage *page; char value[20];
const PatchEntry *pe = NULL; uint page, entry;
char value[50]; const PatchEntry *pe = IConsoleGetPatch(name, &page, &entry);
bool found = false;
uint i;
unsigned int j;
/* Search for the name in the patch-settings */
for (i = 0; i < lengthof(_patches_page); i++) {
page = &_patches_page[i];
for (j = 0; j < page->num; j++) {
pe = &page->entries[j];
if (strncmp(pe->console_name, name, sizeof(pe->console_name)) == 0) {
/* We found the name */
found = true;
break;
}
}
if (found)
break;
}
/* We did not found the patch setting */ /* We did not find the patch setting */
if (!found || pe == NULL) { if (pe == NULL) {
IConsolePrintF(_iconsole_color_warning, "'%s' is an unkown patch setting", name); IConsolePrintF(_iconsole_color_warning, "'%s' is an unknown patch setting.", name);
return; return;
} }
/* 'pe' is now the correct patch setting */ if (pe->type == PE_BOOL) {
switch(pe->type) { snprintf(value, sizeof(value), (ReadPE(pe) == 1) ? "on" : "off");
case PE_BOOL: } else
if (ReadPE(pe) == 1) snprintf(value, sizeof(value), "%d", ReadPE(pe));
snprintf(value, sizeof(value), "enabled");
else
snprintf(value, sizeof(value), "disabled");
break;
case PE_UINT8:
case PE_INT16:
case PE_UINT16:
case PE_INT32:
case PE_CURRENCY:
snprintf(value, sizeof(value), "%d", ReadPE(pe));
break;
}
IConsolePrintF(_iconsole_color_warning, "Current value for '%s' is:", name); IConsolePrintF(_iconsole_color_warning, "Current value for '%s' is: '%s'", name, value);
IConsolePrintF(_iconsole_color_warning, " '%s'", value);
} }
static const Widget _patches_selection_widgets[] = { static const Widget _patches_selection_widgets[] = {

Loading…
Cancel
Save