/** * @brief Initializes the global arguments list and dispatches to an underlying * implementation, if provided. Should be called shortly after program * execution begins. */ void Com_Init(int32_t argc, char *argv[]) { quetoo.argc = argc; quetoo.argv = argv; // options that any Com_* implementation can use for (int32_t i = 1; i < Com_Argc(); i++) { // if we specified debug mode, quickly set it to all here // so that early systems prior to init can write stuff out if (!g_strcmp0(Com_Argv(i), "-debug") || !g_strcmp0(Com_Argv(i), "+debug")) { Com_SetDebug("all"); continue; } if (!g_strcmp0(Com_Argv(i), "-log") || !g_strcmp0(Com_Argv(i), "+log")) { Com_InitLog(); continue; } } if (quetoo.Init) { quetoo.Init(); } }
/** * @brief Adds command line parameters as script statements * @note Commands lead with a + and continue until another + or - * @return true if any late commands were added * @sa Cbuf_AddEarlyCommands */ qboolean Cbuf_AddLateCommands (void) { int i, j; int s; char *text, *build, c; int argc; qboolean ret; /* build the combined string to parse from */ s = 0; argc = Com_Argc(); for (i = 1; i < argc; i++) { s += strlen(Com_Argv(i)) + 1; } if (!s) return qfalse; text = (char *)Mem_Alloc(s + 1); text[0] = 0; for (i = 1; i < argc; i++) { Q_strcat(text, Com_Argv(i), s); if (i != argc - 1) Q_strcat(text, " ", s); } /* pull out the commands */ build = (char *)Mem_Alloc(s + 1); build[0] = 0; for (i = 0; i < s - 1; i++) { if (text[i] == '+') { i++; for (j = i; text[j] != '+' && text[j] != '-' && text[j] != 0; j++) {} c = text[j]; text[j] = 0; Q_strcat(build, text + i, s); Q_strcat(build, "\n", s); text[j] = c; i = j - 1; } } ret = (build[0] != 0); if (ret) Cbuf_AddText(build); Mem_Free(text); Mem_Free(build); return ret; }
/** * @brief Adds command line parameters as script statements * Commands lead with a +, and continue until another + * Set commands are added early, so they are guaranteed to be set before * the client and server initialize for the first time. * Other commands are added late, after all initialization is complete. * @sa Cbuf_AddLateCommands */ void Cbuf_AddEarlyCommands (qboolean clear) { int i; for (i = 1; i < Com_Argc(); i++) { const char *s = Com_Argv(i); if (!Q_streq(s, "+set")) continue; Cbuf_AddText(va("set %s %s\n", Com_Argv(i + 1), Com_Argv(i + 2))); if (clear) { Com_ClearArgv(i); Com_ClearArgv(i + 1); Com_ClearArgv(i + 2); } i += 2; } }
/** * @brief Add a single alien of a given type. */ static void AC_AddOne_f (void) { const char *alienName; teamDef_t *alienType; aliensCont_t *containment; qboolean updateAlive = qtrue; int j; base_t *base = B_GetCurrentSelectedBase(); /* Can be called from everywhere. */ if (!base) return; /* arg parsing */ if (Cmd_Argc() < 2) { Com_Printf("Usage: %s <alientype> [dead:true|false]\n", Cmd_Argv(0)); return; } alienName = Cmd_Argv(1); alienType = Com_GetTeamDefinitionByID(alienName); if (!alienType) { Com_Printf("AC_AddOne_f: Team definition '%s' does not exist.\n", alienName); return; } /* Check that alientType exists */ containment = base->alienscont; for (j = 0; j < ccs.numAliensTD; j++) { aliensCont_t *ac = &containment[j]; assert(ac->teamDef); if (ac->teamDef == alienType) break; } if (j == ccs.numAliensTD) { Com_Printf("AC_AddOne_f: Alien Type '%s' does not exist. Available choices are:\n", alienName); for (j = 0; j < ccs.numAliensTD; j++) Com_Printf("\t* %s\n", containment[j].teamDef->name); return; } if (Cmd_Argc() == 3) updateAlive = Com_ParseBoolean(Com_Argv(2)); /* update alien counter*/ if (B_GetBuildingStatus(base, B_ALIEN_CONTAINMENT)) { containment = base->alienscont; } else { return; } /* call the function that actually changes the persistent datastructure */ AL_AddAliens2(base, alienType, !updateAlive); }
/** * @brief */ int32_t main(int32_t argc, char **argv) { printf("Quetoo Master Server %s %s %s\n", VERSION, __DATE__, BUILD_HOST); memset(&quetoo, 0, sizeof(quetoo)); quetoo.Debug = Debug; quetoo.Verbose = Verbose; quetoo.Init = Init; quetoo.Shutdown = Shutdown; signal(SIGINT, Sys_Signal); signal(SIGQUIT, Sys_Signal); signal(SIGSEGV, Sys_Signal); signal(SIGTERM, Sys_Signal); Com_Init(argc, argv); int32_t i; for (i = 0; i < Com_Argc(); i++) { if (!g_strcmp0(Com_Argv(i), "-v") || !g_strcmp0(Com_Argv(i), "-verbose")) { verbose = true; continue; } if (!g_strcmp0(Com_Argv(i), "-d") || !g_strcmp0(Com_Argv(i), "-debug")) { debug = true; continue; } } ms_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); struct sockaddr_in address; memset(&address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_port = htons(PORT_MASTER); address.sin_addr.s_addr = INADDR_ANY; if ((bind(ms_sock, (struct sockaddr *) &address, sizeof(address))) == -1) { Com_Error(ERROR_FATAL, "Failed to bind port %i\n", PORT_MASTER); } Com_Print("Listening on %s\n", atos(&address)); while (true) { fd_set set; FD_ZERO(&set); FD_SET(ms_sock, &set); struct timeval delay; delay.tv_sec = 1; delay.tv_usec = 0; if (select(ms_sock + 1, &set, NULL, NULL, &delay) > 0) { if (FD_ISSET(ms_sock, &set)) { char buffer[0xffff]; memset(buffer, 0, sizeof(buffer)); struct sockaddr_in from; memset(&from, 0, sizeof(from)); socklen_t from_len = sizeof(from); const ssize_t len = recvfrom(ms_sock, buffer, sizeof(buffer), 0, (struct sockaddr *) &from, &from_len); if (len > 0) { if (len > 4) { Ms_ParseMessage(&from, buffer); } else { Com_Warn("Invalid packet from %s\n", atos(&from)); } } else { Com_Warn("Socket error: %s\n", strerror(errno)); } } } Ms_Frame(); } }