/** * @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 Returns the command line argument at the specified index. */ char *Com_Argv(int32_t arg) { if (arg < 0 || arg >= Com_Argc()) return ""; return quake2world.argv[arg]; }
/** * @brief Returns the command line argument at the specified index. */ char *Com_Argv(int32_t arg) { if (arg < 0 || arg >= Com_Argc()) { return ""; } return quetoo.argv[arg]; }
/** * @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(); } }