diff options
Diffstat (limited to 'src/plugins/console.c')
-rw-r--r-- | src/plugins/console.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/src/plugins/console.c b/src/plugins/console.c new file mode 100644 index 000000000..41ef434e9 --- /dev/null +++ b/src/plugins/console.c @@ -0,0 +1,226 @@ +// Copyright (c) Athena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#include "../common/plugin.h" + +#ifdef WIN32 + #define WIN32_LEAN_AND_MEAN + #include <windows.h> +#else + #include <sys/types.h> + #include <unistd.h> + #include <poll.h> + #include <string.h> +#endif +#include <stdio.h> // stdin, fgets + +#ifdef WIN32 + +#define THREAD_FUNC_START(name) DWORD WINAPI thread_ ## name(LPVOID lpParameter) { (void)lpParameter; { +#define THREAD_FUNC_END(name) } ExitThread(0); return 0; } +#define THREAD_EXECUTE(name,errvar) \ + do{ \ + int _fail_ = (CreateThread(NULL,0,thread_ ## name,NULL,0,NULL) == NULL); \ + if( errvar ) \ + *errvar = _fail_; \ + }while(0) +#define sleep Sleep + +#define pipe_create(p) ( CreatePipe(&p[PIPE_READ], &p[PIPE_WRITE], NULL, 1) != 0 ) +#define pipe_read(p,data,len) do{ DWORD _b_; ReadFile(p[PIPE_READ], data, len, &_b_, NULL); }while(0) +#define pipe_write(p,data,len) do{ DWORD _b_; WriteFile(p[PIPE_WRITE], data, len, &_b_, NULL); }while(0) +#define pipe_close(p,side) CloseHandle(p[side]) +typedef HANDLE PIPE[2]; + +#else + +#define THREAD_FUNC_START(name) void thread_ ## name(void) { +#define THREAD_FUNC_END(name) _exit(0); } +#define THREAD_EXECUTE(name,errvar) \ + do{ \ + int pid = fork(); \ + if( pid == 0 ){ \ + thread_ ## name(); \ + } \ + if( errvar ) \ + *errvar = (pid == -1); \ + }while(0) + +#define pipe_create(p) pipe(p) +#define pipe_read(p,data,len) read(p[PIPE_READ], data, len) +#define pipe_write(p,data,len) write(p[PIPE_WRITE], data, len) +#define pipe_close(p,side) close(p[side]) +typedef int PIPE[2]; + +#endif + +#define PIPE_READ 0 +#define PIPE_WRITE 1 +#define INPUT_BUFSIZE 4096 + +////// Plugin information //////// +// +PLUGIN_INFO = { + "Console", // Name + PLUGIN_ALL, // Target servers + "0.1", // Version + "1.03", // Minimum plugin engine version to run + "Console parser" // Short description +}; + +////// Plugin event list ////////// +// Format: <plugin function>,<event name> +// All registered functions to a event gets executed +// (In descending order) when its called. +// Multiple functions can be called by multiple events too, +// So it's up to your creativity ^^ +// +PLUGIN_EVENTS_TABLE = { + { "console_init", EVENT_PLUGIN_INIT }, + { "console_final", EVENT_PLUGIN_FINAL }, + { "console_start", EVENT_ATHENA_INIT }, + { "console_stop", EVENT_ATHENA_FINAL }, + { NULL, NULL } +}; + +///// Variables ///// + +typedef int TimerFunc(int tid, unsigned int tick, int id, int data); +int (*add_timer_func_list)(TimerFunc func, char* name); +int (*add_timer_interval)(unsigned int tick, TimerFunc* func, int id, int data, int interval); +int (*delete_timer)(int tid, TimerFunc* func); +unsigned int (*gettick)(void); +int (*parse_console)(char* buf); + +int tid; +PIPE data; +PIPE next; + +//////// Plugin functions ////////// + +static int pipe_hasdata(PIPE p) +{ +#ifdef WIN32 + return ( WaitForSingleObject(p[PIPE_READ],0) == WAIT_OBJECT_0 ); +#else + struct pollfd fds; + fds.fd = p[PIPE_READ]; + fds.events = POLLRDNORM; + return ( poll(&fds,1,0) > 0 ); +#endif +} + +int console_parsebuf(int tid, unsigned int tick, int id, int data_) +{ + //printf("console_parsebuf\n"); + //delete_timer(tid, console_parsebuf); + if( pipe_hasdata(data) ){ + char buf[INPUT_BUFSIZE]; + size_t len; + //printf("console_parsebuf pipe_hasdata\n"); + // receive string + pipe_read(data, &len, sizeof(size_t)); + pipe_read(data, &buf, len); + buf[len] = '\0'; + //printf("console_parsebuf buf='%s'\n", buf); + // parse it + parse_console(buf); + //printf("console_parsebuf writing next\n"); + // send next state + buf[0] = 'R'; + pipe_write(next, &buf, 1); + //printf("console_parsebuf done with next\n"); + } + return 0; +} + +THREAD_FUNC_START(readinput) + char buf[INPUT_BUFSIZE]; + char state = 'R'; + size_t len; + + //printf("thread_readinput START\n"); + pipe_close(data, PIPE_READ); + pipe_close(next, PIPE_WRITE); + buf[sizeof(buf)-1] = '\0'; + for( ; state != 'X'; ) + { + //printf("thread_readinput getting data\n"); + buf[0] = '\0'; + fgets(buf, sizeof(buf)-1, stdin); + len = strlen(buf); + //printf("thread_readinput buf='%s'\n", buf); + // send string + pipe_write(data, &len, sizeof(size_t)); + pipe_write(data, buf, len); + // receive next state + pipe_read(next, &state, sizeof(char)); + } + pipe_close(data, PIPE_WRITE); + pipe_close(next, PIPE_READ); + //printf("thread_readinput STOP (%d)\n", state); +THREAD_FUNC_END(readinput) + +void console_start(void) +{ + int error = 0; + //printf("console_start\n"); + if( pipe_create(data) ){ + //printf("console_start data pipe failed\n"); + return; + } + if( pipe_create(next) ){ + //printf("console_start next pipe failed\n"); + pipe_close(data, PIPE_READ); + pipe_close(data, PIPE_WRITE); + return; + } + THREAD_EXECUTE(readinput, &error); + if( error ){ + //printf("console_start thread start error\n"); + pipe_close(data, PIPE_READ); + pipe_close(next, PIPE_WRITE); + } else { + //printf("console_start thread started\n"); + //parse_console("help"); + add_timer_func_list(console_parsebuf,"console_parsebuf"); + tid = add_timer_interval(gettick(),console_parsebuf,0,0,1); // run once every cycle + } + pipe_close(data, PIPE_WRITE); + pipe_close(next, PIPE_READ); +} + +void console_stop(void) +{ + char c = 'X'; + //printf("console_stop\n"); + if( tid != -1 ){ + delete_timer(tid, console_parsebuf); + pipe_write(next, &c, sizeof(char)); + } + return; +} + +void console_init(void) +{ + //printf("console_init\n"); + // import symbols + IMPORT_SYMBOL(add_timer_interval, SYMBOL_ADD_TIMER_INTERVAL); + IMPORT_SYMBOL(add_timer_func_list, SYMBOL_ADD_TIMER_FUNC_LIST); + IMPORT_SYMBOL(delete_timer, SYMBOL_DELETE_TIMER); + IMPORT_SYMBOL(gettick, SYMBOL_GETTICK); + IMPORT_SYMBOL(parse_console, SYMBOL_PARSE_CONSOLE); + //printf("%d -> add_timer_func_list=0x%x\n", SYMBOL_ADD_TIMER_FUNC_LIST, (int)add_timer_func_list); + //printf("%d -> add_timer_interval=0x%x\n", SYMBOL_ADD_TIMER_INTERVAL, (int)add_timer_interval); + //printf("%d -> delete_timer=0x%x\n", SYMBOL_DELETE_TIMER, (int)delete_timer); + //printf("%d -> gettick=0x%x\n", SYMBOL_GETTICK, (int)gettick); + //printf("%d -> parse_console=0x%x\n", SYMBOL_PARSE_CONSOLE, (int)parse_console); + + return; +} + +void console_final(void) +{ + //printf("console_final\n"); + return; +} |