(svn r221) -Feature: console command and variable hooking

-Fix: added another network.c stub
-Consolecommand: "scrollto <tile>" center main view on <tile> [Darkvater]
-Consolecommand: "resettile <tile>" force bulldoze <tile> without any checks (DEBUG only) [Darkvater]
-Fix: resetengines is hooked to be not available in network games
-Codechange: "connect <connectstr>": the connect command now uses a connectionstring like the network-gui
-Fix: Direct Connect editbox can handle up to max ~35 characters [Darkvater]
This commit is contained in:
signde 2004-09-12 20:15:18 +00:00
parent 7cb5b1954d
commit d6cab2e06d
8 changed files with 1296 additions and 1015 deletions

1830
console.c

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
#ifndef CONSOLE_H
#define CONSOLE_H
// ** console ** //
enum {
@ -20,14 +21,26 @@ enum {
ICONSOLE_VAR_STRING,
ICONSOLE_VAR_POINTER,
ICONSOLE_VAR_REFERENCE,
ICONSOLE_VAR_UNKNOWN
ICONSOLE_VAR_UNKNOWN,
} _iconsole_var_types;
enum {
ICONSOLE_HOOK_ACCESS,
ICONSOLE_HOOK_BEFORE_CHANGE,
ICONSOLE_HOOK_BEFORE_EXEC,
ICONSOLE_HOOK_AFTER_CHANGE,
ICONSOLE_HOOK_AFTER_EXEC,
} _iconsole_hook_types;
typedef struct {
// -------------- //
void * addr;
byte * name;
// -------------- //
void * hook_access;
void * hook_before_exec;
void * hook_after_exec;
// -------------- //
void * _next;
} _iconsole_cmd;
@ -37,10 +50,19 @@ typedef struct {
byte * name;
byte type;
// -------------- //
void * hook_access;
void * hook_before_change;
void * hook_after_change;
// -------------- //
void * _next;
bool _malloc;
} _iconsole_var;
// ** console parser ** //
_iconsole_cmd * _iconsole_cmds; // list of registred commands
_iconsole_var * _iconsole_vars; // list of registred vars
// ** console colors ** //
VARDEF byte _iconsole_color_default;
VARDEF byte _iconsole_color_error;
@ -48,6 +70,7 @@ VARDEF byte _iconsole_color_debug;
VARDEF byte _iconsole_color_commands;
// ** ttd.c functions ** //
void SetDebugString(const char *s);
// ** console functions ** //
@ -79,6 +102,7 @@ void* IConsoleCmdGetAddr(byte * name);
// *** Variables *** //
void IConsoleVarRegister(byte * name, void * addr, byte type);
void IConsoleVarMemRegister(byte * name, byte type);
void IConsoleVarInsert(_iconsole_var * var, byte * name);
_iconsole_var * IConsoleVarGet(byte * name);
_iconsole_var * IConsoleVarAlloc(byte type);
@ -91,6 +115,14 @@ void IConsoleVarDump(_iconsole_var * var, byte * dump_desc);
void IConsoleCmdExec(byte * cmdstr);
#include "console_cmds.h"
// ** console std lib ** //
void IConsoleStdLibRegister();
// ** hook code ** //
void IConsoleVarHook(byte * name, byte type, void * proc);
void IConsoleCmdHook(byte * name, byte type, void * proc);
bool IConsoleVarHookHandle(_iconsole_var * hook_var, byte type);
bool IConsoleCmdHookHandle(_iconsole_cmd * hook_cmd, byte type);
#endif /* CONSOLE_H */

387
console_cmds.c Normal file
View File

@ -0,0 +1,387 @@
/* -------------------- dont cross this line --------------------- */
#include "stdafx.h"
#include "ttd.h"
#include "console.h"
#include "engine.h"
#include "functions.h"
#include "variables.h"
#if defined(WIN32)
# define ENABLE_NETWORK
#endif
// ** console command / variable defines ** //
#define DEF_CONSOLE_CMD(yyyy) static _iconsole_var * yyyy(byte argc, byte* argv[], byte argt[])
#define DEF_CONSOLE_CMD_HOOK(yyyy) static bool yyyy(_iconsole_cmd * hookcmd)
#define DEF_CONSOLE_VAR_HOOK(yyyy) static bool yyyy(_iconsole_var * hookvar)
static int32 GetArgumentInteger(byte *arg)
{
int32 result;
sscanf((char *)arg, "%u", &result);
if (result == 0 && arg[0] == '0' && arg[1] == 'x')
sscanf((char *)arg, "%x", &result);
return result;
}
/* **************************** */
/* variable and command hooks */
/* **************************** */
DEF_CONSOLE_CMD_HOOK(ConCmdHookNoNetwork)
{
if (_networking) {
IConsoleError("this command is forbidden in multiplayer");
return false;
}
return true;
}
DEF_CONSOLE_VAR_HOOK(ConVarHookNoNetwork)
{
if (_networking) {
IConsoleError("this variable is forbidden in multiplayer");
return false;
}
return true;
}
DEF_CONSOLE_VAR_HOOK(ConVarHookNoNetClient)
{
if (!_networking_server) {
IConsoleError("this variable only makes sense for a network server");
return false;
}
return true;
}
/* **************************** */
/* reset commands */
/* **************************** */
DEF_CONSOLE_CMD(ConResetEngines)
{
StartupEngines();
return 0;
}
DEF_CONSOLE_CMD(ConResetTile)
{
if (argc == 2) {
TileIndex tile = (TileIndex)GetArgumentInteger(argv[1]);
DoClearSquare(tile);
}
return 0;
}
DEF_CONSOLE_CMD(ConScrollToTile)
{
if (argc == 2) {
TileIndex tile = (TileIndex)GetArgumentInteger(argv[1]);
ScrollMainWindowToTile(tile);
}
return 0;
}
// ********************************* //
// * Network Core Console Commands * //
// ********************************* //
#ifdef ENABLE_NETWORK
DEF_CONSOLE_CMD(ConNetworkConnect)
{
byte * b;
byte * ip = NULL;
byte * port = NULL;
byte * player = NULL;
byte c;
uint16 rport;
if (argc<2) return NULL;
b = argv[1];
rport = _network_server_port;
c = 0;
ip = b;
while (b[c] != 0) {
if (((char)b[c]) == '#') {
player = &b[c+1];
b[c] = 0;
}
if (((char)b[c]) == ':') {
port = &b[c+1];
b[c] = 0;
}
c++;
}
IConsolePrintF(_iconsole_color_default,"Connecting to %s...",ip);
if (player!=NULL) {
_network_playas = atoi(player);
IConsolePrintF(_iconsole_color_default," player-no: %s",player);
}
if (port!=NULL) {
rport = atoi(port);
IConsolePrintF(_iconsole_color_default," port: %s",port);
}
NetworkCoreConnectGame(b, rport);
return NULL;
}
#endif
/* **************************** */
/* default console commands */
/* **************************** */
DEF_CONSOLE_CMD(ConEcho)
{
if (argc<2) return NULL;
IConsolePrint(_iconsole_color_default, argv[1]);
return NULL;
}
DEF_CONSOLE_CMD(ConEchoC)
{
if (argc<3) return NULL;
IConsolePrint(atoi(argv[1]), argv[2]);
return NULL;
}
DEF_CONSOLE_CMD(ConPrintF)
{
if (argc<3) return NULL;
IConsolePrintF(_iconsole_color_default, argv[1] ,argv[2],argv[3],argv[4],argv[5],argv[6],argv[7],argv[8],argv[9],argv[10],argv[11],argv[12],argv[13],argv[14],argv[15],argv[16],argv[17],argv[18],argv[19]);
return NULL;
}
DEF_CONSOLE_CMD(ConPrintFC)
{
if (argc<3) return NULL;
IConsolePrintF(atoi(argv[1]), argv[2] ,argv[3],argv[4],argv[5],argv[6],argv[7],argv[8],argv[9],argv[10],argv[11],argv[12],argv[13],argv[14],argv[15],argv[16],argv[17],argv[18],argv[19]);
return NULL;
}
DEF_CONSOLE_CMD(ConScreenShot)
{
if (argc<2) {
_make_screenshot=1;
} else {
if (strcmp(argv[1],"big")==0) {
_make_screenshot=2;
}
if (strcmp(argv[1],"no_con")==0) {
IConsoleClose();
_make_screenshot=1;
}
}
return NULL;
}
DEF_CONSOLE_CMD(ConVarInfo)
{
if (argc<2) return NULL;
if (argt[1]!=ICONSOLE_VAR_REFERENCE) {
IConsoleError("variable must be an variable reference");
} else {
_iconsole_var * item;
item = (_iconsole_var *) argv[1];
IConsolePrintF(_iconsole_color_default,"variable_name: %s",item->name);
IConsolePrintF(_iconsole_color_default,"variable_type: %i",item->type);
IConsolePrintF(_iconsole_color_default,"variable_addr: %i",item->addr);
if (item->_malloc) IConsolePrintF(_iconsole_color_default,"variable_malloc: internal allocated"); else IConsolePrintF(_iconsole_color_default, "variable_malloc: external allocated");
}
return NULL;
}
DEF_CONSOLE_CMD(ConDebugLevel)
{
if (argc<2) return NULL;
SetDebugString(argv[1]);
return NULL;
}
DEF_CONSOLE_CMD(ConExit)
{
_exit_game = true;
return NULL;
}
DEF_CONSOLE_CMD(ConHelp)
{
IConsolePrint(13 ," -- console help -- ");
IConsolePrint(1 ," variables: [command to list them: list_vars]");
IConsolePrint(1 ," *temp_string = \"my little \"");
IConsolePrint(1 ,"");
IConsolePrint(1 ," commands: [command to list them: list_cmds]");
IConsolePrint(1 ," [command] [\"string argument with spaces\"] [argument 2] ...");
IConsolePrint(1 ," printf \"%s world\" *temp_string");
IConsolePrint(1 ,"");
IConsolePrint(1 ," command/variable returning a value into an variable:");
IConsolePrint(1 ," *temp_uint16 << random");
IConsolePrint(1 ," *temp_uint16 << *temp_uint16_2");
IConsolePrint(1 ,"");
return NULL;
}
DEF_CONSOLE_CMD(ConRandom)
{
_iconsole_var * result;
result = IConsoleVarAlloc(ICONSOLE_VAR_UINT16);
IConsoleVarSetValue(result,rand());
return result;
}
DEF_CONSOLE_CMD(ConListCommands)
{
_iconsole_cmd * item;
int l = 0;
if (argv[1]!=NULL) l = strlen((char *) argv[1]);
item = _iconsole_cmds;
while (item != NULL) {
if (argv[1]!=NULL) {
if (memcmp((void *) item->name, (void *) argv[1],l)==0)
IConsolePrintF(_iconsole_color_default,"%s",item->name);
} else {
IConsolePrintF(_iconsole_color_default,"%s",item->name);
}
item = item->_next;
}
return NULL;
}
DEF_CONSOLE_CMD(ConListVariables)
{
_iconsole_var * item;
int l = 0;
if (argv[1]!=NULL) l = strlen((char *) argv[1]);
item = _iconsole_vars;
while (item != NULL) {
if (argv[1]!=NULL) {
if (memcmp((void *) item->name, (void *) argv[1],l)==0)
IConsolePrintF(_iconsole_color_default,"%s",item->name);
} else {
IConsolePrintF(_iconsole_color_default,"%s",item->name);
}
item = item->_next;
}
return NULL;
}
DEF_CONSOLE_CMD(ConListDumpVariables)
{
_iconsole_var * item;
int l = 0;
if (argv[1]!=NULL) l = strlen((char *) argv[1]);
item = _iconsole_vars;
while (item != NULL) {
if (argv[1]!=NULL) {
if (memcmp((void *) item->name, (void *) argv[1],l)==0)
IConsoleVarDump(item,NULL);
} else {
IConsoleVarDump(item,NULL);
}
item = item->_next;
}
return NULL;
}
#ifdef _DEBUG
/* ****************************************** */
/* debug commands and variables */
/* ****************************************** */
void IConsoleDebugLibRegister()
{
IConsoleVarMemRegister("temp_bool",ICONSOLE_VAR_BOOLEAN);
IConsoleVarMemRegister("temp_int16",ICONSOLE_VAR_INT16);
IConsoleVarMemRegister("temp_int32",ICONSOLE_VAR_INT32);
IConsoleVarMemRegister("temp_pointer",ICONSOLE_VAR_POINTER);
IConsoleVarMemRegister("temp_uint16",ICONSOLE_VAR_UINT16);
IConsoleVarMemRegister("temp_uint16_2",ICONSOLE_VAR_UINT16);
IConsoleVarMemRegister("temp_uint32",ICONSOLE_VAR_UINT32);
IConsoleVarMemRegister("temp_string",ICONSOLE_VAR_STRING);
IConsoleVarMemRegister("temp_string2",ICONSOLE_VAR_STRING);
IConsoleCmdRegister("resettile",ConResetTile);
}
#endif
/* ****************************************** */
/* console command and variable registration */
/* ****************************************** */
void IConsoleStdLibRegister()
{
// stdlib
extern byte _stdlib_developer;
extern bool _stdlib_con_developer;
#ifdef _DEBUG
IConsoleDebugLibRegister();
#endif
// functions [please add them alphabeticaly]
#ifdef ENABLE_NETWORK
IConsoleCmdRegister("connect",ConNetworkConnect);
IConsoleCmdHook("connect",ICONSOLE_HOOK_ACCESS,ConCmdHookNoNetwork);
#endif
IConsoleCmdRegister("debug_level",ConDebugLevel);
IConsoleCmdRegister("dump_vars",ConListDumpVariables);
IConsoleCmdRegister("echo",ConEcho);
IConsoleCmdRegister("echoc",ConEchoC);
IConsoleCmdRegister("exit",ConExit);
IConsoleCmdRegister("help",ConHelp);
IConsoleCmdRegister("printf",ConPrintF);
IConsoleCmdRegister("printfc",ConPrintFC);
IConsoleCmdRegister("quit",ConExit);
IConsoleCmdRegister("random",ConRandom);
IConsoleCmdRegister("list_cmds",ConListCommands);
IConsoleCmdRegister("list_vars",ConListVariables);
IConsoleCmdRegister("resetengines",ConResetEngines);
IConsoleCmdHook("resetengines",ICONSOLE_HOOK_ACCESS,ConCmdHookNoNetwork);
IConsoleCmdRegister("screenshot",ConScreenShot);
IConsoleCmdRegister("scrollto",ConScrollToTile);
IConsoleCmdRegister("varinfo",ConVarInfo);
// variables [please add them alphabeticaly]
IConsoleVarRegister("con_developer",(void *) &_stdlib_con_developer,ICONSOLE_VAR_BOOLEAN);
IConsoleVarRegister("developer",(void *) &_stdlib_developer,ICONSOLE_VAR_BYTE);
#ifdef ENABLE_NETWORK
IConsoleVarRegister("net_client_timeout",&_network_client_timeout,ICONSOLE_VAR_UINT16);
IConsoleVarHook("*net_client_timeout",ICONSOLE_HOOK_ACCESS,ConVarHookNoNetClient);
IConsoleVarRegister("net_ready_ahead",&_network_ready_ahead,ICONSOLE_VAR_UINT16);
IConsoleVarRegister("net_sync_freq",&_network_sync_freq,ICONSOLE_VAR_UINT16);
IConsoleVarHook("*net_sync_freq",ICONSOLE_HOOK_ACCESS,ConVarHookNoNetClient);
#endif
}
/* -------------------- dont cross this line --------------------- */

View File

@ -1,13 +0,0 @@
#ifndef CONSOLE_CMDS_H
#define CONSOLE_CMDS_H
/* Console_CMDS.h is the placeholder of all the console commands
* that will be added to the game. Register the command in
* * console.c IConsoleStdLibRegister;
* then put the command in the appropiate place (eg. where it belongs, stations
* stuff in station_cmd.c, etc.), and add the function decleration here.
*/
_iconsole_var * IConsoleResetEngines(byte argc, byte* argv[], byte argt[]);
#endif /* CONSOLE_CMDS_H */

View File

@ -7,7 +7,6 @@
#include "vehicle.h"
#include "news.h"
#include "saveload.h"
#include "console.h"
#define UPDATE_PLAYER_RAILTYPE(e,p) if ((byte)(e->railtype + 1) > p->max_railtype) p->max_railtype = e->railtype + 1;
@ -165,8 +164,6 @@ void StartupEngines()
AdjustAvailAircraft();
}
_iconsole_var * IConsoleResetEngines(byte argc, byte* argv[], byte argt[]) {StartupEngines(); return 0;}
uint32 _engine_refit_masks[256];

View File

@ -202,8 +202,6 @@ static int _num_clients;
// keep a history of the 16 most recent seeds to be able to capture out of sync errors.
static uint32 _my_seed_list[16][2];
static bool _network_ready_sent;
static uint16 _network_ready_ahead = 1;
static uint16 _network_client_timeout;
static uint32 _frame_fsync_last;
typedef struct FutureSeeds {
@ -1348,28 +1346,6 @@ void NetworkStartSync(bool fcreset)
memset(_my_seed_list, 0, sizeof(_my_seed_list));
}
// ********************************* //
// * Network Core Console Commands * //
// ********************************* //
static _iconsole_var * NetworkConsoleCmdConnect(byte argc, byte* argv[], byte argt[])
{
if (argc<2) return NULL;
if (argc == 2) {
IConsolePrintF(_iconsole_color_default, "connecting to %s",argv[1]);
NetworkCoreConnectGame(argv[1],_network_server_port);
} else if (argc == 3) {
IConsolePrintF(_iconsole_color_default, "connecting to %s on port %s",argv[1],argv[2]);
NetworkCoreConnectGame(argv[1],atoi(argv[2]));
} else if (argc == 4) {
IConsolePrintF(_iconsole_color_default, "connecting to %s on port %s as player %s",argv[1],argv[2],argv[3]);
_network_playas = atoi(argv[3]);
NetworkCoreConnectGame(argv[1],atoi(argv[2]));
}
return NULL;
}
// ************************** //
// * UDP Network Extensions * //
// ************************** //
@ -1587,8 +1563,9 @@ void NetworkIPListInit()
void NetworkCoreInit()
{
DEBUG(net, 3) ("[NET][Core] init()");
_network_available=true;
_network_client_timeout=300;
_network_available = true;
_network_client_timeout = 300;
_network_ready_ahead = 1;
// [win32] winsock startup
@ -1644,10 +1621,6 @@ void NetworkCoreInit()
DEBUG(net, 3) ("[NET][Core] OK: multiplayer available");
// initiate network ip list
NetworkIPListInit();
IConsoleCmdRegister("connect",NetworkConsoleCmdConnect);
IConsoleVarRegister("net_client_timeout",&_network_client_timeout,ICONSOLE_VAR_UINT16);
IConsoleVarRegister("net_ready_ahead",&_network_ready_ahead,ICONSOLE_VAR_UINT16);
IConsoleVarRegister("net_sync_freq",&_network_sync_freq,ICONSOLE_VAR_UINT16);
} else
DEBUG(net, 3) ("[NET][Core] FAILED: multiplayer not available");
}
@ -1938,6 +1911,7 @@ void NetworkGameListFromLAN() {};
void NetworkGameListFromInternet() {};
void NetworkGameFillDefaults() {};
NetworkGameList * NetworkGameListItem(uint16 index) {return NULL;};
bool NetworkCoreConnectGameStruct(NetworkGameList * item) {return false;};
void NetworkGameChangeDate(uint16 newdate) {};
#endif

View File

@ -295,6 +295,9 @@
<File
RelativePath=".\console.c">
</File>
<File
RelativePath=".\console_cmds.c">
</File>
<File
RelativePath="economy.c">
<FileConfiguration
@ -1104,9 +1107,6 @@
<File
RelativePath="console.h">
</File>
<File
RelativePath=".\console_cmds.h">
</File>
<File
RelativePath="economy.h">
</File>

View File

@ -231,6 +231,8 @@ VARDEF uint _network_server_port;
VARDEF uint16 _network_sync_freq;
VARDEF uint16 _network_ahead_frames;
VARDEF uint16 _network_ready_ahead;
VARDEF uint16 _network_client_timeout;
VARDEF uint32 _sync_seed_1, _sync_seed_2;