src/main.cpp

00001 #ifdef WIN32
00002 #include <afxres.h>
00003 #endif
00004 
00005 #include <SDL.h>
00006 #include <SDL_thread.h>
00007 #include <SDL_net.h>
00008 #include <stdio.h>
00009  #include <stdlib.h>
00010  #include <signal.h>
00011  #include <string.h>     /* for memset() (on some compilers) */
00012  #include <osdefs.h>     /* for _MAX_PATH */
00013  #include <amx.h>
00014 
00015  #include <time.h>
00016  #if !defined CLOCKS_PER_SEC     /* some (older) compilers do not have it */
00017  #define CLOCKS_PER_SEC CLK_TCK
00018  #endif
00019 
00020  #if !defined AMX_NODYNALOAD && (defined LINUX || defined __FreeBSD__ || defined __OpenBSD__)
00021  #include <binreloc.h> /* from BinReloc, see www.autopackage.org */
00022  #endif
00023 
00024  #if defined AMXDBG
00025  #include <amxdbg.h>
00026  static char g_filename[_MAX_PATH];/* for loading the debug information */
00027  #endif
00028 
00029 #include <iostream>
00030 #include <vector>
00031 
00032 
00033 #include "Connection.h"
00034 #include "Server.h"
00035 #include "Logger.h"
00036 #include "Console.h"
00037 
00038 #ifdef TESTPHASE
00039 #include "Account.h"
00040 #endif
00041 
00042 
00043 int main(int argc, char **argv){
00044 
00045         // A logger, used to log server messages.
00046         Logger* logger = Logger::getInstance();
00047 
00048         #ifdef TESTPHASE
00049         logger->setDebugMode(false);
00050         #endif
00051 
00052 //      #ifdef TESTPHASE
00053 //      Account* acc = new Account();
00054 //      acc->save("test", "password");
00055 //      delete acc;
00056 //      #endif
00057 
00058         logger->log("Initializing SDL subsystems...", LOGMODE_NORMAL);
00059 
00060         /*
00061          * Initializes SDL, this maybe should be moved to another class...
00062          */
00063         if(SDL_Init(0)==-1)
00064         {
00065                 cerr << "SDL_Init: "<< SDL_GetError() << endl;
00066                 exit(1);
00067         }
00068 
00069         /*
00070          * Initializes SDL_net, this maybe should be moved to another class...
00071          */
00072         if(SDLNet_Init()==-1)
00073         {
00074                 cerr << "SDLNet_Init: " << SDLNet_GetError() << endl;
00075                 SDL_Quit();
00076                 exit(2);
00077         }
00078 
00079         // What to do before exiting.
00080         atexit(SDL_Quit);
00081 
00082         cout << "OK" << endl << endl;
00083 
00084         cout << "Creating a new server instance...";
00085         Server* server = new Server(9999);
00086         cout << "OK" << endl << endl;
00087 
00088         Console * console = new Console(server);        // Creates and initializes the console.
00089         console->setServer(server);
00090 
00091         SDL_WaitThread(server->getThread(), NULL);
00092 
00093         return 0;
00094 }
00095 
00096 
00098 //* (libraries with native functions) that this run-time uses. More
00099 //* extension modules may be dynamically linked (depending on whether
00100 //* support for dynamic linking is enabled).
00101 //*/
00102 // extern "C" int AMXEXPORT amx_ConsoleInit(AMX *amx);
00103 // extern "C" int AMXEXPORT amx_CoreInit(AMX *amx);
00104 // extern int AMXEXPORT amx_ServerLanguageInit(AMX *amx);
00105 // extern int AMXEXPORT amx_ServerLanguageCleanup(AMX *amx);
00106 //
00107 // AMX *global_amx;
00108 // int AMXAPI srun_Monitor(AMX *amx);
00109 //
00110 // static int abortflagged = 0;
00111 // void sigabort(int sig)
00112 // {
00113 //      /* install the debug hook procedure if this was not done already */
00114 //      amx_SetDebugHook(global_amx, srun_Monitor);
00115 //      abortflagged=1;
00116 //      signal(sig,sigabort); /* re-install the signal handler */
00117 // }
00118 //
00119 // typedef struct tagSTACKINFO {
00120 //      long maxstack, maxheap;
00121 // } STACKINFO;
00122 //
00123 //
00125 //* A simple debug hook, that allows the user to break out of a program
00126 //* and that monitors stack usage. Note that the stack usage can only be
00127 //* properly monitored when the debug hook is installed from the start
00128 //* of the script to the end.
00129 //*/
00130 // int AMXAPI srun_Monitor(AMX *amx)
00131 // {
00132 //      int err;
00133 //      STACKINFO *stackinfo;
00134 //
00135 //      /* record the heap and stack usage */
00136 //      err = amx_GetUserData(amx, AMX_USERTAG('S','t','c','k'), (void**)&stackinfo);
00137 //      if (err == AMX_ERR_NONE) {
00138 //              if (amx->stp - amx->stk > stackinfo->maxstack)
00139 //                      stackinfo->maxstack = amx->stp - amx->stk;
00140 //              if (amx->hea - amx->hlw > stackinfo->maxheap)
00141 //                      stackinfo->maxstack = amx->stp - amx->stk;
00142 //      } /* if */
00143 //
00144 //      /* check whether an "abort" was requested */
00145 //      return abortflagged ? AMX_ERR_EXIT : AMX_ERR_NONE;
00146 // }
00147 //
00149 //* Load a compiled Pawn script into memory and initialize the abstract machine.
00150 //* This function is extracted out of AMXAUX.C.
00151 //*/
00152 // int AMXAPI aux_LoadProgram(AMX *amx, char *filename, void *memblock)
00153 // {
00154 //      FILE *fp;
00155 //      AMX_HEADER hdr;
00156 //      int result, didalloc;
00157 //
00158 //      /* open the file, read and check the header */
00159 //      if ((fp = fopen(filename, "rb")) == NULL)
00160 //              return AMX_ERR_NOTFOUND;
00161 //      fread(&hdr, sizeof hdr, 1, fp);
00162 //      amx_Align16(&hdr.magic);
00163 //      amx_Align32((uint32_t *)&hdr.size);
00164 //      amx_Align32((uint32_t *)&hdr.stp);
00165 //      if (hdr.magic != AMX_MAGIC) {
00166 //              fclose(fp);
00167 //              return AMX_ERR_FORMAT;
00168 //      } /* if */
00169 //
00170 //      /* allocate the memblock if it is NULL */
00171 //      didalloc = 0;
00172 //      if (memblock == NULL) {
00173 //              if ((memblock = malloc(hdr.stp)) == NULL) {
00174 //                      fclose(fp);
00175 //                      return AMX_ERR_MEMORY;
00176 //              } /* if */
00177 //              didalloc = 1;
00178 //              /* after amx_Init(), amx->base points to the memory block */
00179 //      } /* if */
00180 //
00181 //      /* read in the file */
00182 //      rewind(fp);
00183 //      fread(memblock, 1, (size_t)hdr.size, fp);
00184 //      fclose(fp);
00185 //
00186 //      /* initialize the abstract machine */
00187 //      memset(amx, 0, sizeof *amx);
00188 //      result = amx_Init(amx, memblock);
00189 //
00190 //      /* free the memory block on error, if it was allocated here */
00191 //      if (result != AMX_ERR_NONE && didalloc) {
00192 //              free(memblock);
00193 //              amx->base = NULL;                   /* avoid a double free */
00194 //      } /* if */
00195 //
00196 //      /* save the filename, for optionally reading the debug information (we could
00197 //      * also have read it here immediately
00198 //      */
00199 // #if defined AMXDBG
00200 //      strcpy(g_filename, filename);
00201 // #endif
00202 //
00203 //      return result;
00204 // }
00205 //
00207 //* Clean up a program and free memory.
00208 //* This function is extracted out of AMXAUX.C.
00209 //*/
00210 // int AMXAPI aux_FreeProgram(AMX *amx)
00211 // {
00212 //      if (amx->base!=NULL) {
00213 //              amx_Cleanup(amx);
00214 //              free(amx->base);
00215 //              memset(amx,0,sizeof(AMX));
00216 //      } /* if */
00217 //      return AMX_ERR_NONE;
00218 // }
00219 //
00221 //* Convert an error code to a "readable" string.
00222 //* This function is extracted out of AMXAUX.C.
00223 //*/
00224 //char * AMXAPI aux_StrError(int errnum)
00225 //{
00226 //      static char *messages[] = {
00227 //              /* AMX_ERR_NONE      */ "(none)",
00228 //              /* AMX_ERR_EXIT      */ "Forced exit",
00229 //              /* AMX_ERR_ASSERT    */ "Assertion failed",
00230 //              /* AMX_ERR_STACKERR  */ "Stack/heap collision (insufficient stack size)",
00231 //              /* AMX_ERR_BOUNDS    */ "Array index out of bounds",
00232 //              /* AMX_ERR_MEMACCESS */ "Invalid memory access",
00233 //              /* AMX_ERR_INVINSTR  */ "Invalid instruction",
00234 //              /* AMX_ERR_STACKLOW  */ "Stack underflow",
00235 //              /* AMX_ERR_HEAPLOW   */ "Heap underflow",
00236 //              /* AMX_ERR_CALLBACK  */ "No (valid) native function callback",
00237 //              /* AMX_ERR_NATIVE    */ "Native function failed",
00238 //              /* AMX_ERR_DIVIDE    */ "Divide by zero",
00239 //              /* AMX_ERR_SLEEP     */ "(sleep mode)",
00240 //              /* 13 */                "(reserved)",
00241 //              /* 14 */                "(reserved)",
00242 //              /* 15 */                "(reserved)",
00243 //              /* AMX_ERR_MEMORY    */ "Out of memory",
00244 //              /* AMX_ERR_FORMAT    */ "Invalid/unsupported P-code file format",
00245 //              /* AMX_ERR_VERSION   */ "File is for a newer version of the AMX",
00246 //              /* AMX_ERR_NOTFOUND  */ "File or function is not found",
00247 //              /* AMX_ERR_INDEX     */ "Invalid index parameter (bad entry point)",
00248 //              /* AMX_ERR_DEBUG     */ "Debugger cannot run",
00249 //              /* AMX_ERR_INIT      */ "AMX not initialized (or doubly initialized)",
00250 //              /* AMX_ERR_USERDATA  */ "Unable to set user data field (table full)",
00251 //              /* AMX_ERR_INIT_JIT  */ "Cannot initialize the JIT",
00252 //              /* AMX_ERR_PARAMS    */ "Parameter error",
00253 //      };
00254 //      if (errnum < 0 || errnum >= sizeof messages / sizeof messages[0])
00255 //              return "(unknown)";
00256 //      return messages[errnum];
00257 //}
00258 //
00259 // void ExitOnError(AMX *amx, int error)
00260 // {
00261 //      if (error != AMX_ERR_NONE) {
00262 // #if defined AMXDBG
00263 //              FILE *fp;
00264 //              AMX_DBG amxdbg;
00265 //              long line;
00266 //              const char *filename;
00267 // #endif
00268 //
00269 //              printf("Run time error %d: \"%s\" on address %ld\n",
00270 //                      error, aux_StrError(error), (long)amx->cip);
00271 //
00272 //              /* optionally use the debug library to find the line number (if debug info.
00273 //              * is available)
00274 //              */
00275 // #if defined AMXDBG
00276 //              /* load the debug info. */
00277 //              if ((fp=fopen(g_filename,"r")) != NULL && dbg_LoadInfo(&amxdbg,fp) == AMX_ERR_NONE) {
00278 //                      dbg_LookupFile(&amxdbg, amx->cip, &filename);
00279 //                      dbg_LookupLine(&amxdbg, amx->cip, &line);
00280 //                      printf("File: %s, line: %ld\n", filename, line);
00281 //                      dbg_FreeInfo(&amxdbg);
00282 //                      fclose(fp);
00283 //              } /* if */
00284 // #endif
00285 //              exit(1);
00286 //      } /* if */
00287 // }
00288 //
00289 // void PrintUsage(char *program)
00290 // {
00291 //      printf("Usage: %s <filename> [options]\n\n"
00292 //              "Options:\n"
00293 //              "\t-stack\tto monitor stack usage\n"
00294 //              "\t...\tother options are passed to the script\n"
00295 //              , program);
00296 //      exit(1);
00297 // }
00298 //
00299 //
00300 // int main(int argc,char *argv[])
00301 // {
00302 //      AMX amx;
00303 //      cell ret = 0;
00304 //      int err, i;
00305 //      clock_t start,end;
00306 //      STACKINFO stackinfo = { 0 };
00307 //      AMX_IDLE idlefunc;
00308 //
00309 //
00310 // //   if (argc < 2)
00311 // //           PrintUsage(argv[0]);        /* function "usage" aborts the program */
00312 //
00313 //
00314 // #if !defined AMX_NODYNALOAD && (defined LINUX || defined __FreeBSD__ || defined __OpenBSD__)
00315 //      /* see www.autopackage.org for the BinReloc module */
00316 //      if (br_init(NULL)) {
00317 //              char *libroot=br_find_exe_dir("");
00318 //              setenv("AMXLIB",libroot,0);
00319 //              free(libroot);
00320 //      } /* if */
00321 // #endif
00322 //
00323 //      /* Load the program and initialize the abstract machine. */
00324 //      //err = aux_LoadProgram(&amx, argv[1], NULL);
00325 //      err = aux_LoadProgram(&amx, "../src/pawn/serverStartup.amx", NULL);
00326 //      if (err != AMX_ERR_NONE) {
00327 //              /* try adding an extension */
00328 //              char filename[_MAX_PATH];
00329 //              strcpy(filename, argv[1]);
00330 //              strcat(filename, ".amx");
00331 //              err = aux_LoadProgram(&amx, filename, NULL);
00332 //              if (err != AMX_ERR_NONE)
00333 //                      PrintUsage(argv[0]);
00334 //      } /* if */
00335 //
00336 //      /* To install the debug hook "just-in-time", the signal function needs
00337 //      * a pointer to the abstract machine(s) to abort. There are various ways
00338 //      * to implement this; here I have done so with a simple global variable.
00339 //      */
00340 //      global_amx = &amx;
00341 //      signal(SIGINT, sigabort);
00342 //
00343 //      /* Initialize two core extension modules (more extension modules may be
00344 //      * loaded & initialized automatically as DLLs or shared libraries.
00345 //      */
00346 //      amx_ConsoleInit(&amx);
00347 //      // Init server language extensions
00348 //      amx_ServerLanguageInit(&amx);
00349 //
00350 //      // Init AMX core and also perform native functions checks.
00351 //      err = amx_CoreInit(&amx);
00352 //      ExitOnError(&amx, err);
00353 //
00354 //
00355 //      /* save the idle function, if set by any of the extension modules */
00356 //      if (amx_GetUserData(&amx, AMX_USERTAG('I','d','l','e'), (void**)&idlefunc) != AMX_ERR_NONE)
00357 //              idlefunc = NULL;
00358 //
00359 //      for (i = 2; i < argc; i++) {
00360 //              if (strcmp(argv[i],"-stack") == 0) {
00361 //                      uint16_t flags;
00362 //                      amx_Flags(&amx, &flags);
00363 //                      if ((flags & AMX_FLAG_NOCHECKS) != 0)
00364 //                              printf("This script was compiled with debug information removed.\n"
00365 //                              "Stack monitoring is disfunctional\n\n");
00366 //                      /* Set "user data" with which the debug monitor can monitor stack usage
00367 //                      * per abstract machine (in this example, though, there is only one abstract
00368 //                      * machine, so a global variable would have sufficed).
00369 //                      */
00370 //                      memset(&stackinfo, 0, sizeof stackinfo);
00371 //                      err = amx_SetUserData(&amx, AMX_USERTAG('S','t','c','k'), &stackinfo);
00372 //                      ExitOnError(&amx, err);
00373 //                      /* Install the debug hook, so that we can start monitoring the stack/heap
00374 //                      * usage right from the beginning of the script.
00375 //                      */
00376 //                      amx_SetDebugHook(&amx, srun_Monitor);
00377 //              } /* if */
00378 //      } /* for */
00379 //
00380 //      start=clock();
00381 //
00382 //      /* Run the compiled script and time it. The "sleep" instruction causes the
00383 //      * abstract machine to return in a "restartable" state (it restarts from
00384 //      * the point that it stopped. This allows for a kind of light-weight
00385 //      * cooperative multi-tasking. As native functions (or the debug hook) can
00386 //      * also force an abstract machine to "sleep", you can also use it to create
00387 //      * "latent functions": functions that allow the host application to continue
00388 //      * processing, and/or other abstract machines to run, while they wait for
00389 //      * some resource.
00390 //      */
00391 //      err = amx_Exec(&amx, &ret, AMX_EXEC_MAIN);
00392 //      while (err == AMX_ERR_SLEEP) {
00393 //              if (idlefunc != NULL) {
00394 //                      /* If the abstract machine was put to sleep, we can handle events during
00395 //                      * that time. To save the "restart point", we must make a copy of the AMX
00396 //                      * (keeping the stack, frame, instruction pointer and other vital
00397 //                      * registers), but without cloning the entire abstract machine.
00398 //                      * There should be some criterion on when the abstract machine must be
00399 //                      * "woken up". In this example run-time, the parameter of the sleep
00400 //                      * instruction is taken to be a delay in milliseconds. In your own host
00401 //                      * application, you can choose to wait on a resource/semaphore or other.
00402 //                      */
00403 //                      AMX nested_amx = amx;
00404 //                      clock_t stamp = clock();
00405 //                      while (((clock() - stamp)*1000)/CLOCKS_PER_SEC < amx.pri
00406 //                              && (err = idlefunc(&nested_amx,amx_Exec)) == AMX_ERR_NONE)
00407 //                              /* nothing */;
00408 //                      ExitOnError(&nested_amx, err);
00409 //              } /* if */
00410 //              err = amx_Exec(&amx, &ret, AMX_EXEC_CONT);
00411 //      } /* while */
00412 //      ExitOnError(&amx, err);
00413 //
00414 //      /* For event-driven programs, we also need to loop over the idle/monitor
00415 //      * function that some extension module installed (this could be the console
00416 //      * module, for example). We did this if the main program was put to "sleep",
00417 //      * but we do that here too.
00418 //      */
00419 //      if (idlefunc != NULL) {
00420 //              while ((err = idlefunc(&amx,amx_Exec)) == AMX_ERR_NONE)
00421 //                      /* nothing */;
00422 //              ExitOnError(&amx, err);
00423 //      } /* if */
00424 //
00425 //      end=clock();
00426 //
00427 //      /* Free the compiled script and resources. This also unloads and DLLs or
00428 //      * shared libraries that were registered automatically by amx_Init().
00429 //      */
00430 //      aux_FreeProgram(&amx);
00431 //
00432 //      /* Print the return code of the compiled script (often not very useful),
00433 //      * its run time, and its stack usage.
00434 //      */
00435 //      if (ret!=0)
00436 //              printf("\nReturn value: %ld\n", (long)ret);
00437 //
00438 //      printf("\nRun time:     %.2f seconds\n",(double)(end-start)/CLOCKS_PER_SEC);
00439 //      if (stackinfo.maxstack != 0 || stackinfo.maxheap != 0) {
00440 //              printf("Stack usage:  %ld cells (%ld bytes)\n",
00441 //                      stackinfo.maxstack / sizeof(cell), stackinfo.maxstack);
00442 //              printf("Heap usage:   %ld cells (%ld bytes)\n",
00443 //                      stackinfo.maxheap / sizeof(cell), stackinfo.maxheap);
00444 //      } /* if */
00445 //
00446 // #if defined AMX_TERMINAL
00447 //      /* This is likely a graphical terminal, which should not be closed
00448 //      * automatically
00449 //      */
00450 //      {
00451 //              extern int amx_termctl(int,int);
00452 //              while (amx_termctl(4,0))
00453 //                      /* nothing */;
00454 //      }
00455 // #endif
00456 //
00457 //      return 0;
00458 // }

Generated on Mon Dec 3 04:30:13 2007 for lo-testserver by  doxygen 1.3.9.1