diff options
Diffstat (limited to 'src/engine/server.cpp')
| -rw-r--r-- | src/engine/server.cpp | 357 |
1 files changed, 30 insertions, 327 deletions
diff --git a/src/engine/server.cpp b/src/engine/server.cpp index e76c67d..9348b67 100644 --- a/src/engine/server.cpp +++ b/src/engine/server.cpp @@ -18,11 +18,7 @@ void closelogfile() FILE *getlogfile() { -#ifdef WIN32 - return logfile; -#else return logfile ? logfile : stdout; -#endif } void setlogfile(const char *fname) @@ -64,21 +60,17 @@ static void writelogv(FILE *file, const char *fmt, va_list args) vformatstring(buf, fmt, args, sizeof(buf)); writelog(file, buf); } - + #ifdef STANDALONE -void fatal(const char *fmt, ...) -{ +void fatal(const char *fmt, ...) +{ void cleanupserver(); - cleanupserver(); + cleanupserver(); defvformatstring(msg,fmt,fmt); if(logfile) logoutf("%s", msg); -#ifdef WIN32 - MessageBox(NULL, msg, "Cube 2: Sauerbraten fatal error", MB_OK|MB_SYSTEMMODAL); -#else fprintf(stderr, "server error: %s\n", msg); -#endif closelogfile(); - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } void conoutfv(int type, const char *fmt, va_list args) @@ -103,7 +95,7 @@ struct client // server side version of "dynent" type vector<client *> clients; ENetHost *serverhost = NULL; -int laststatus = 0; +int laststatus = 0; ENetSocket pongsock = ENET_SOCKET_NULL, lansock = ENET_SOCKET_NULL; int localclients = 0, nonlocalclients = 0; @@ -221,7 +213,7 @@ ENetPacket *sendf(int cn, int chan, const char *format, ...) break; } - case 'i': + case 'i': { int n = isdigit(*format) ? *format++-'0' : 1; loopi(n) putint(p, va_arg(args, int)); @@ -359,7 +351,7 @@ VARN(updatemaster, allowupdatemaster, 0, 1, 1); void disconnectmaster() { - if(mastersock != ENET_SOCKET_NULL) + if(mastersock != ENET_SOCKET_NULL) { server::masterdisconnected(); enet_socket_destroy(mastersock); @@ -453,7 +445,7 @@ void processmasterinput() masterinpos = end - masterin.getbuf(); input = end; end = (char *)memchr(input, '\n', masterin.length() - masterinpos); - } + } if(masterinpos >= masterin.length()) { @@ -556,8 +548,8 @@ void checkserversockets() // reply all server info requests { if(!masterconnected) { - if(ENET_SOCKETSET_CHECK(readset, mastersock) || ENET_SOCKETSET_CHECK(writeset, mastersock)) - { + if(ENET_SOCKETSET_CHECK(readset, mastersock) || ENET_SOCKETSET_CHECK(writeset, mastersock)) + { int error = 0; if(enet_socket_get_option(mastersock, ENET_SOCKOPT_ERROR, &error) < 0 || error) { @@ -566,9 +558,9 @@ void checkserversockets() // reply all server info requests } else { - masterconnecting = 0; - masterconnected = totalmillis ? totalmillis : 1; - server::masterconnected(); + masterconnecting = 0; + masterconnected = totalmillis ? totalmillis : 1; + server::masterconnected(); } } } @@ -596,7 +588,7 @@ uint totalsecs = 0; void updatetime() { static int lastsec = 0; - if(totalmillis - lastsec >= 1000) + if(totalmillis - lastsec >= 1000) { int cursecs = (totalmillis - lastsec) / 1000; totalsecs += cursecs; @@ -606,16 +598,16 @@ void updatetime() void serverslice(bool dedicated, uint timeout) // main server update, called from main loop in sp, or from below in dedicated server { - if(!serverhost) + if(!serverhost) { server::serverupdate(); server::sendpackets(); return; } - + // below is network only - if(dedicated) + if(dedicated) { int millis = (int)enet_time_get(); elapsedtime = millis - totalmillis; @@ -635,10 +627,10 @@ void serverslice(bool dedicated, uint timeout) // main server update, called f if(!lastupdatemaster || totalmillis-lastupdatemaster>60*60*1000) // send alive signal to masterserver every hour of uptime updatemasterserver(); - + if(totalmillis-laststatus>60*1000) // display bandwidth stats, useful for server ops { - laststatus = totalmillis; + laststatus = totalmillis; if(nonlocalclients || serverhost->totalSentData || serverhost->totalReceivedData) logoutf("status: %d remote clients, %.1f send, %.1f rec (K/sec)", nonlocalclients, serverhost->totalSentData/60.0f/1024, serverhost->totalReceivedData/60.0f/1024); serverhost->totalSentData = serverhost->totalReceivedData = 0; } @@ -662,7 +654,7 @@ void serverslice(bool dedicated, uint timeout) // main server update, called f string hn; copystring(c.hostname, (enet_address_get_host_ip(&c.peer->address, hn, sizeof(hn))==0) ? hn : "unknown"); logoutf("client connected (%s)", c.hostname); - int reason = server::clientconnect(c.num, c.peer->address.host); + int reason = server::clientconnect(c.num); if(reason) disconnect_client(c.num, reason); break; } @@ -673,7 +665,7 @@ void serverslice(bool dedicated, uint timeout) // main server update, called f if(event.packet->referenceCount==0) enet_packet_destroy(event.packet); break; } - case ENET_EVENT_TYPE_DISCONNECT: + case ENET_EVENT_TYPE_DISCONNECT: { client *c = (client *)event.peer->data; if(!c) break; @@ -698,7 +690,7 @@ void flushserver(bool force) void localdisconnect(bool cleanup) { bool disconnected = false; - loopv(clients) if(clients[i]->type==ST_LOCAL) + loopv(clients) if(clients[i]->type==ST_LOCAL) { server::localdisconnect(i); delclient(clients[i]); @@ -719,279 +711,12 @@ void localconnect() } #endif -#ifdef WIN32 -#include "shellapi.h" - -#define IDI_ICON1 1 - -static string apptip = ""; -static HINSTANCE appinstance = NULL; -static ATOM wndclass = 0; -static HWND appwindow = NULL, conwindow = NULL; -static HICON appicon = NULL; -static HMENU appmenu = NULL; -static HANDLE outhandle = NULL; -static const int MAXLOGLINES = 200; -struct logline { int len; char buf[LOGSTRLEN]; }; -static queue<logline, MAXLOGLINES> loglines; - -static void cleanupsystemtray() -{ - NOTIFYICONDATA nid; - memset(&nid, 0, sizeof(nid)); - nid.cbSize = sizeof(nid); - nid.hWnd = appwindow; - nid.uID = IDI_ICON1; - Shell_NotifyIcon(NIM_DELETE, &nid); -} - -static bool setupsystemtray(UINT uCallbackMessage) -{ - NOTIFYICONDATA nid; - memset(&nid, 0, sizeof(nid)); - nid.cbSize = sizeof(nid); - nid.hWnd = appwindow; - nid.uID = IDI_ICON1; - nid.uCallbackMessage = uCallbackMessage; - nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; - nid.hIcon = appicon; - strcpy(nid.szTip, apptip); - if(Shell_NotifyIcon(NIM_ADD, &nid) != TRUE) - return false; - atexit(cleanupsystemtray); - return true; -} - -#if 0 -static bool modifysystemtray() -{ - NOTIFYICONDATA nid; - memset(&nid, 0, sizeof(nid)); - nid.cbSize = sizeof(nid); - nid.hWnd = appwindow; - nid.uID = IDI_ICON1; - nid.uFlags = NIF_TIP; - strcpy(nid.szTip, apptip); - return Shell_NotifyIcon(NIM_MODIFY, &nid) == TRUE; -} -#endif - -static void cleanupwindow() -{ - if(!appinstance) return; - if(appmenu) - { - DestroyMenu(appmenu); - appmenu = NULL; - } - if(wndclass) - { - UnregisterClass(MAKEINTATOM(wndclass), appinstance); - wndclass = 0; - } -} - -static BOOL WINAPI consolehandler(DWORD dwCtrlType) -{ - switch(dwCtrlType) - { - case CTRL_C_EVENT: - case CTRL_BREAK_EVENT: - case CTRL_CLOSE_EVENT: - exit(EXIT_SUCCESS); - return TRUE; - } - return FALSE; -} - -static void writeline(logline &line) -{ - static uchar ubuf[512]; - size_t len = strlen(line.buf), carry = 0; - while(carry < len) - { - size_t numu = encodeutf8(ubuf, sizeof(ubuf), &((uchar *)line.buf)[carry], len - carry, &carry); - DWORD written = 0; - WriteConsole(outhandle, ubuf, numu, &written, NULL); - } -} - -static void setupconsole() -{ - if(conwindow) return; - if(!AllocConsole()) return; - SetConsoleCtrlHandler(consolehandler, TRUE); - conwindow = GetConsoleWindow(); - SetConsoleTitle(apptip); - //SendMessage(conwindow, WM_SETICON, ICON_SMALL, (LPARAM)appicon); - SendMessage(conwindow, WM_SETICON, ICON_BIG, (LPARAM)appicon); - outhandle = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO coninfo; - GetConsoleScreenBufferInfo(outhandle, &coninfo); - coninfo.dwSize.Y = MAXLOGLINES; - SetConsoleScreenBufferSize(outhandle, coninfo.dwSize); - SetConsoleCP(CP_UTF8); - SetConsoleOutputCP(CP_UTF8); - loopv(loglines) writeline(loglines[i]); -} - -enum -{ - MENU_OPENCONSOLE = 0, - MENU_SHOWCONSOLE, - MENU_HIDECONSOLE, - MENU_EXIT -}; - -static LRESULT CALLBACK handlemessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch(uMsg) - { - case WM_APP: - SetForegroundWindow(hWnd); - switch(lParam) - { - //case WM_MOUSEMOVE: - // break; - case WM_LBUTTONUP: - case WM_RBUTTONUP: - { - POINT pos; - GetCursorPos(&pos); - TrackPopupMenu(appmenu, TPM_CENTERALIGN|TPM_BOTTOMALIGN|TPM_RIGHTBUTTON, pos.x, pos.y, 0, hWnd, NULL); - PostMessage(hWnd, WM_NULL, 0, 0); - break; - } - } - return 0; - case WM_COMMAND: - switch(LOWORD(wParam)) - { - case MENU_OPENCONSOLE: - setupconsole(); - if(conwindow) ModifyMenu(appmenu, 0, MF_BYPOSITION|MF_STRING, MENU_HIDECONSOLE, "Hide Console"); - break; - case MENU_SHOWCONSOLE: - ShowWindow(conwindow, SW_SHOWNORMAL); - ModifyMenu(appmenu, 0, MF_BYPOSITION|MF_STRING, MENU_HIDECONSOLE, "Hide Console"); - break; - case MENU_HIDECONSOLE: - ShowWindow(conwindow, SW_HIDE); - ModifyMenu(appmenu, 0, MF_BYPOSITION|MF_STRING, MENU_SHOWCONSOLE, "Show Console"); - break; - case MENU_EXIT: - PostMessage(hWnd, WM_CLOSE, 0, 0); - break; - } - return 0; - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - return DefWindowProc(hWnd, uMsg, wParam, lParam); -} - -static void setupwindow(const char *title) -{ - copystring(apptip, title); - //appinstance = GetModuleHandle(NULL); - if(!appinstance) fatal("failed getting application instance"); - appicon = LoadIcon(appinstance, MAKEINTRESOURCE(IDI_ICON1));//(HICON)LoadImage(appinstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); - if(!appicon) fatal("failed loading icon"); - - appmenu = CreatePopupMenu(); - if(!appmenu) fatal("failed creating popup menu"); - AppendMenu(appmenu, MF_STRING, MENU_OPENCONSOLE, "Open Console"); - AppendMenu(appmenu, MF_SEPARATOR, 0, NULL); - AppendMenu(appmenu, MF_STRING, MENU_EXIT, "Exit"); - //SetMenuDefaultItem(appmenu, 0, FALSE); - - WNDCLASS wc; - memset(&wc, 0, sizeof(wc)); - wc.hCursor = NULL; //LoadCursor(NULL, IDC_ARROW); - wc.hIcon = appicon; - wc.lpszMenuName = NULL; - wc.lpszClassName = title; - wc.style = 0; - wc.hInstance = appinstance; - wc.lpfnWndProc = handlemessages; - wc.cbWndExtra = 0; - wc.cbClsExtra = 0; - wndclass = RegisterClass(&wc); - if(!wndclass) fatal("failed registering window class"); - - appwindow = CreateWindow(MAKEINTATOM(wndclass), title, 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, HWND_MESSAGE, NULL, appinstance, NULL); - if(!appwindow) fatal("failed creating window"); - - atexit(cleanupwindow); - - if(!setupsystemtray(WM_APP)) fatal("failed adding to system tray"); -} - -static char *parsecommandline(const char *src, vector<char *> &args) -{ - char *buf = new char[strlen(src) + 1], *dst = buf; - for(;;) - { - while(isspace(*src)) src++; - if(!*src) break; - args.add(dst); - for(bool quoted = false; *src && (quoted || !isspace(*src)); src++) - { - if(*src != '"') *dst++ = *src; - else if(dst > buf && src[-1] == '\\') dst[-1] = '"'; - else quoted = !quoted; - } - *dst++ = '\0'; - } - args.add(NULL); - return buf; -} - - -int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) -{ - vector<char *> args; - char *buf = parsecommandline(GetCommandLine(), args); - appinstance = hInst; -#ifdef STANDALONE - int standalonemain(int argc, char **argv); - int status = standalonemain(args.length()-1, args.getbuf()); - #define main standalonemain -#else - SDL_SetMainReady(); - int status = SDL_main(args.length()-1, args.getbuf()); -#endif - delete[] buf; - exit(status); - return 0; -} - -void logoutfv(const char *fmt, va_list args) -{ - if(appwindow) - { - logline &line = loglines.add(); - vformatstring(line.buf, fmt, args, sizeof(line.buf)); - if(logfile) writelog(logfile, line.buf); - line.len = min(strlen(line.buf), sizeof(line.buf)-2); - line.buf[line.len++] = '\n'; - line.buf[line.len] = '\0'; - if(outhandle) writeline(line); - } - else if(logfile) writelogv(logfile, fmt, args); -} - -#else - void logoutfv(const char *fmt, va_list args) { FILE *f = getlogfile(); if(f) writelogv(f, fmt, args); } -#endif - static bool dedicatedserver = false; bool isdedicatedserver() { return dedicatedserver; } @@ -1000,22 +725,7 @@ void rundedicatedserver() { dedicatedserver = true; logoutf("dedicated server started, waiting for clients..."); -#ifdef WIN32 - SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); - for(;;) - { - MSG msg; - while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - if(msg.message == WM_QUIT) exit(EXIT_SUCCESS); - TranslateMessage(&msg); - DispatchMessage(&msg); - } - serverslice(true, 5); - } -#else for(;;) serverslice(true, 5); -#endif dedicatedserver = false; } @@ -1032,7 +742,7 @@ bool servererror(bool dedicated, const char *desc) fatal("%s", desc); return false; } - + bool setuplistenserver(bool dedicated) { ENetAddress address = { ENET_HOST_ANY, enet_uint16(serverport <= 0 ? server::serverport() : serverport) }; @@ -1067,13 +777,6 @@ bool setuplistenserver(bool dedicated) void initserver(bool listen, bool dedicated) { - if(dedicated) - { -#ifdef WIN32 - setupwindow("Cube 2: Sauerbraten server"); -#endif - } - execfile("server-init.cfg", false); if(listen) setuplistenserver(dedicated); @@ -1097,12 +800,12 @@ void startlistenserver(int *usemaster) if(serverhost) { conoutf(CON_ERROR, "listen server is already running"); return; } allowupdatemaster = *usemaster>0 ? 1 : 0; - + if(!setuplistenserver(false)) return; - + updatemasterserver(); - - conoutf("listen server started for %d clients%s", maxclients, allowupdatemaster ? " and listed with master server" : ""); + + conoutf("listen server started for %d clients%s", maxclients, allowupdatemaster ? " and listed with master server" : ""); } COMMAND(startlistenserver, "i"); @@ -1126,7 +829,7 @@ bool serveroption(char *opt) case 'u': setvar("serveruprate", atoi(opt+2)); return true; case 'c': setvar("maxclients", atoi(opt+2)); return true; case 'i': setsvar("serverip", opt+2); return true; - case 'j': setvar("serverport", atoi(opt+2)); return true; + case 'j': setvar("serverport", atoi(opt+2)); return true; case 'm': setsvar("mastername", opt+2); setvar("updatemaster", mastername[0] ? 1 : 0); return true; #ifdef STANDALONE case 'q': logoutf("Using home directory: %s", opt); sethomedir(opt+2); return true; @@ -1141,7 +844,7 @@ vector<const char *> gameargs; #ifdef STANDALONE int main(int argc, char **argv) -{ +{ setlogfile(NULL); if(enet_initialize()<0) fatal("Unable to initialise network module"); atexit(enet_deinitialize); |
