const char *GetMODVersion(void) { static msg_t msg; // we must be connected to the master server before writing to it if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0)) { CONS_Printf("cannot connect to the master server\n"); M_StartMessage("There was a problem connecting to\nthe Master Server", NULL, MM_NOTHING); return NULL; } msg.type = GET_VERSION_MSG; msg.length = sizeof MODVERSION; msg.room = MODID; // Might as well use it for something. sprintf(msg.buffer,"%d",MODVERSION); if (MS_Write(&msg) < 0) return NULL; MS_Read(&msg); CloseConnection(); if(strcmp(msg.buffer,"NULL") != 0) { return msg.buffer; } else return NULL; }
/** Gets a list of game servers from the master server. */ static INT32 GetServersList(void) { msg_t msg; INT32 count = 0; msg.type = GET_SERVER_MSG; msg.length = 0; msg.room = 0; if (MS_Write(&msg) < 0) return MS_WRITE_ERROR; while (MS_Read(&msg) >= 0) { if (!msg.length) { if (!count) CONS_Printf("No servers currently running.\n"); return MS_NO_ERROR; } count++; CONS_Printf("%s",msg.buffer); } return MS_READ_ERROR; }
static INT32 RemoveFromMasterSever(void) { msg_t msg; msg_server_t *info = (msg_server_t *)msg.buffer; strcpy(info->header.buffer, ""); strcpy(info->ip, ""); strcpy(info->port, int2str(current_port)); strcpy(info->name, registered_server.name); sprintf(info->version, "%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION); msg.type = REMOVE_SERVER_MSG; msg.length = (UINT32)sizeof (msg_server_t); msg.room = 0; if (MS_Write(&msg) < 0) return MS_WRITE_ERROR; return MS_NO_ERROR; }
const msg_server_t *GetShortServersList(INT32 room) { static msg_server_t server_list[NUM_LIST_SERVER+1]; // +1 for easy test msg_t msg; INT32 i; // updated now oldroomnum = room; // we must be connected to the master server before writing to it if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0)) { CONS_Printf("cannot connect to the master server\n"); M_StartMessage("There was a problem connecting to\nthe Master Server", NULL, MM_NOTHING); return NULL; } msg.type = GET_SHORT_SERVER_MSG; msg.length = 0; msg.room = room; if (MS_Write(&msg) < 0) return NULL; for (i = 0; i < NUM_LIST_SERVER && MS_Read(&msg) >= 0; i++) { if (!msg.length) { server_list[i].header.buffer[0] = 0; CloseConnection(); return server_list; } M_Memcpy(&server_list[i], msg.buffer, sizeof (msg_server_t)); server_list[i].header.buffer[0] = 1; } CloseConnection(); if (i == NUM_LIST_SERVER) { server_list[i].header.buffer[0] = 0; return server_list; } else return NULL; }
/** Gets a list of game servers from the master server. */ static inline int GetServersList(SOCKET socket) { msg_t msg; int count = 0; msg.type = GET_SERVER_MSG; msg.length = 0; if (MS_Write(&msg, socket) < 0) return MS_WRITE_ERROR; while (MS_Read(&msg, socket) >= 0) { if (!msg.length) { // if (!count) // printf("No server currently running.\n"); return MS_NO_ERROR; } count++; printf(msg.buffer); } return MS_READ_ERROR; }
/** Get the MOTD from the master server. */ static inline INT32 GetMSMOTD(void) { msg_t msg; INT32 count = 0; msg.type = GET_MOTD_MSG; msg.length = 0; if (MS_Write(&msg) < 0) return MS_WRITE_ERROR; while (MS_Read(&msg) >= 0) { if (!msg.length) { if (!count) CONS_Printf("%s", M_GetText("No servers currently running.\n")); return MS_NO_ERROR; } count++; CONS_Printf("%s",msg.buffer); } return MS_READ_ERROR; }
/* * assemble a file and load into memory */ Assembly* parse_file(FILE* file) { Assembly* assembly; /* assembly structure */ int labelid; /* new label id */ Segment* current_segment; /* holds current segment */ char line[MAX_LINE]; /* holds one line */ char* items[MAX_ARGS]; /* split line into items (split on ' ' and '\t') */ int segment; /* holds current segment id */ int count, i, size; /* loop variables */ long long params[MAX_ARGS]; /* parsed items array */ char sbuffer[1024]; /* 1K string buffer */ char* sourcefile; /* current source file */ Label* label; /* initialize variables */ assembly = new_assembly(); labelid = 0; linenr = 0; segment = UNKNOWN; sourcefile = NULL; /* read a line lines (returns nr of characters read, -1 if eof) */ while(read_line(file, line, MAX_LINE) >= 0) { linenr++; /* get rid of spaces/tabs in front of the line */ trim_line(line); /* split the line on spaces/tabs */ count = split_line(line, items); /* note: line == items[0] */ /* check if the line was not empty */ if (strlen(line) > 0) { if (strcmp(line, "code") == 0) { /* code segment */ segment = CODE; current_segment = assembly->code; } else if (strcmp(line, "bss") == 0) { /* bss segment */ segment = BSS; /* bss has no segment structure */ /* (no point in saving uninitialized data */ current_segment = 0; } else if (strcmp(line, "lit") == 0) { /* lit segment */ segment = LIT; current_segment = assembly->lit; } else if (strcmp(line, "data") == 0) { /* data segment */ segment = DATA; current_segment = assembly->data; } else if (strcmp(line, "export") == 0) { /* mark label as public */ if (count != 2) error(linenr, "invalid number of parameters"); label = get_label(assembly, items[1]); /* any exported function should be included */ label->accessed = 1; label->exported = TRUE; } else if (strcmp(line, "import") == 0) { /* mark label as imported */ if (count != 2) error(linenr, "invalid number of parameters"); get_label(assembly, items[1])->imported = TRUE; } else if (segment == UNKNOWN) { /* all other things must be in segments */ error(linenr, "code outside segment"); } else if (strcmp(line, "align") == 0) { /* align a segment */ if (count != 2) error(linenr, "invalid number of parameters"); params[0] = parse_numeric(items[1]); if (segment == BSS) { /* align bss just by size */ while(assembly->bss_size % params[0]) assembly->bss_size++; } else { align_segment(current_segment, params[0]); } } else if (strcmp(line, "byte") == 0) { /* one byte of data */ if (count != 3) error(linenr, "invalid number of parameters"); if (segment == BSS) { error(linenr, "can't put initialized data in bss, use data segment instead"); } else { /* parse */ params[0] = parse_numeric(items[1]); params[1] = parse_numeric(items[2]); /* write to segment */ MS_WriteBE(current_segment->data, params[1], (int)params[0]); for (i = 0; i < (int)params[0]; i++) MS_WriteBit(current_segment->mask, FALSE); } } else if (strcmp(line, "skip") == 0) { /* some empty space */ if (count != 2) error(linenr, "invalid number of parameters"); /* parse */ params[0] = parse_numeric(items[1]); if (segment == BSS) { /* for bss: just update the size */ assembly->bss_size += params[0]; } else { /* for other segment: write zeros */ MS_Write(current_segment->data, 0, (int)params[0]); for (i = 0; i < (int)params[0]; i++) MS_WriteBit(current_segment->mask, FALSE); } } else if (strcmp(line, "address") == 0) { /* insert address to label here */ /* some empty space */ if (count != 2) error(linenr, "invalid number of parameters"); /* write the id to the current segment */ MS_WriteBE(current_segment->data, get_label(assembly, items[1])->id, PTR_SIZE); /* needs to be resolved */ for (i = 0; i < PTR_SIZE; i++) MS_WriteBit(current_segment->mask, TRUE); } else if (strcmp(line, "line") == 0) { if (count < 2) error(linenr, "invalid number of parameters"); if (sourcefile == NULL) error(linenr, "file directive must precede line directive"); size = sprintf(sbuffer, "$%s:", sourcefile); for (i = 1; i < count; i++) { size += sprintf(sbuffer+size, "%s", items[i]); if (i == count-1) { sbuffer[size++] = 0; } else { sbuffer[size++] = ' '; } } /* register debug label */ label = get_label(assembly, sbuffer); if (label->segment == UNKNOWN) { if (segment == BSS) { label->location = assembly->bss_size; } else { label->location = current_segment->data->size; } label->segment = segment; } /* mark as debug function, set accessed to 1 to include it in the assembly */ label->accessed = 1; label->debuginfo = LABEL_DEBUG_LINE; } else if (strcmp(line, "file") == 0) { if (count < 2) error(linenr, "invalid number of parameters"); size = sprintf(sbuffer, "$"); for (i = 1; i < count; i++) { size += sprintf(sbuffer+size, "%s", items[i]); if (i == count-1) { sbuffer[size++] = 0; } else { sbuffer[size++] = ' '; } } if (sourcefile != NULL) free(sourcefile); sourcefile = malloc(size-1); strcpy(sourcefile, sbuffer+1); /* register debug label */ label = get_label(assembly, sbuffer); if (segment == BSS) { label->location = assembly->bss_size; } else { label->location = current_segment->data->size; } label->segment = segment; /* mark as debug function, set accessed to 1 to include it in the assembly */ label->accessed = 1; label->debuginfo = LABEL_DEBUG_FILE; } else if (strcmp(line, "local") == 0) { if (count < 3) error(linenr, "invalid number of parameters"); size = sprintf(sbuffer, "$"); for (i = 1; i < count; i++) { if (i != 2) { size += sprintf(sbuffer+size, "%s", items[i]); if (i == count-1) { sbuffer[size++] = 0; } else { sbuffer[size++] = ' '; } } } /* register debug label */ label = get_label(assembly, sbuffer); label->location = parse_numeric(items[2]); label->segment = UNKNOWN; /* mark as debug function, set accessed to 1 to include it in the assembly */ label->accessed = 1; label->debuginfo = LABEL_DEBUG_LOCAL; } else if (strcmp(line, "param") == 0) { if (count < 3) error(linenr, "invalid number of parameters"); size = sprintf(sbuffer, "$"); for (i = 1; i < count; i++) { if (i != 2) { size += sprintf(sbuffer+size, "%s", items[i]); if (i == count-1) { sbuffer[size++] = 0; } else { sbuffer[size++] = ' '; } } } /* register debug label */ label = get_label(assembly, sbuffer); label->location = parse_numeric(items[2]); label->segment = UNKNOWN; /* mark as debug function, set accessed to 1 to include it in the assembly */ label->accessed = 1; label->debuginfo = LABEL_DEBUG_PARAM; } else if (strcmp(line, "global") == 0) { if (count < 2) error(linenr, "invalid number of parameters"); size = sprintf(sbuffer, "$"); for (i = 1; i < count; i++) { size += sprintf(sbuffer+size, "%s", items[i]); if (i == count-1) { sbuffer[size++] = 0; } else { sbuffer[size++] = ' '; } } /* register debug label */ label = get_label(assembly, sbuffer); label->ref = get_label(assembly, items[1]); /* mark as debug function, set accessed to 1 to include it in the assembly */ label->accessed = 1; label->debuginfo = LABEL_DEBUG_GLOBAL; } else if (strcmp(line, "function") == 0) { if (count < 2) error(linenr, "invalid number of parameters"); size = sprintf(sbuffer, "$"); for (i = 1; i < count; i++) { size += sprintf(sbuffer+size, "%s", items[i]); if (i == count-1) { sbuffer[size++] = 0; } else { sbuffer[size++] = ' '; } } /* register debug label */ label = get_label(assembly, sbuffer); label->ref = get_label(assembly, items[1]); /* mark as debug function, set accessed to 1 to include it in the assembly */ label->accessed = 1; label->debuginfo = LABEL_DEBUG_FUNCTION; } else if (strcmp(line, "label") == 0) { /* a label; register */ if (count != 2) error(linenr, "invalid number of parameters"); if (segment == BSS) { register_label(assembly, items[1], segment, assembly->bss_size); } else { register_label(assembly, items[1], segment, current_segment->data->size); } } else if (strcmp(line, "typedef") == 0) { if (count < 2) error(linenr, "invalid number of parameters"); size = sprintf(sbuffer, "$"); for (i = 1; i < count; i++) { size += sprintf(sbuffer+size, "%s", items[i]); if (i == count-1) { sbuffer[size++] = 0; } else { sbuffer[size++] = ' '; } } /* register debug label */ label = get_label(assembly, sbuffer); /* mark as debug function, set accessed to 1 to include it in the assembly */ label->accessed = 1; label->debuginfo = LABEL_DEBUG_TYPEDEF; } else if (strcmp(line, "field") == 0) { if (count < 2) error(linenr, "invalid number of parameters"); size = sprintf(sbuffer, "$"); for (i = 1; i < count; i++) { if (i != 2) { size += sprintf(sbuffer+size, "%s", items[i]); if (i == count-1) { sbuffer[size++] = 0; } else { sbuffer[size++] = ' '; } } } /* register debug label */ label = get_label(assembly, sbuffer); label->location = parse_numeric(items[2]); label->segment = UNKNOWN; /* mark as debug function, set accessed to 1 to include it in the assembly */ label->accessed = 1; label->debuginfo = LABEL_DEBUG_FIELD; } else { /* not identified; should be an instruction */ write_instruction(assembly, items, count, current_segment); } } } if (sourcefile != NULL) free(sourcefile); /* return the structure */ return assembly; }
/** Tries to register the local game server on the master server. */ static INT32 AddToMasterServer(boolean firstadd) { #ifdef NONET (void)firstadd; #else static INT32 retry = 0; int i, res; socklen_t j; msg_t msg; msg_server_t *info = (msg_server_t *)msg.buffer; INT32 room = -1; fd_set tset; time_t timestamp = time(NULL); UINT32 signature, tmp; const char *insname; M_Memcpy(&tset, &wset, sizeof (tset)); res = select(255, NULL, &tset, NULL, &select_timeout); if (res != ERRSOCKET && !res) { if (retry++ > 30) // an about 30 second timeout { retry = 0; CONS_Printf("Timeout on masterserver\n"); MSLastPing = timestamp; return ConnectionFailed(); } return MS_CONNECT_ERROR; } retry = 0; if (res == ERRSOCKET) { if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0)) { CONS_Printf("Mastserver error on select #%u: %s\n", errno, strerror(errno)); MSLastPing = timestamp; return ConnectionFailed(); } } // so, the socket is writable, but what does that mean, that the connection is // ok, or bad... let see that! j = (socklen_t)sizeof (i); getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, (char *)&i, &j); if (i) // it was bad { CONS_Printf("Masterserver getsockopt error #%u: %s\n", errno, strerror(errno)); MSLastPing = timestamp; return ConnectionFailed(); } if (dedicated && (M_CheckParm("-room") && M_IsNextParm())) { room = atoi(M_GetNextParm()); if(room == 0) room = -1; } else if(dedicated) room = -1; else room = cv_chooseroom.value; for(signature = 0, insname = cv_servername.string; *insname; signature += *insname++); tmp = (UINT32)(signature * (size_t)&MSLastPing); signature *= tmp; signature &= 0xAAAAAAAA; M_Memcpy(&info->header.signature, &signature, sizeof (UINT32)); strcpy(info->ip, ""); strcpy(info->port, int2str(current_port)); strcpy(info->name, cv_servername.string); M_Memcpy(&info->room, & room, sizeof (INT32)); sprintf(info->version, "%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION); strcpy(registered_server.name, cv_servername.string); if(firstadd) msg.type = ADD_SERVER_MSG; else msg.type = PING_SERVER_MSG; msg.length = (UINT32)sizeof (msg_server_t); msg.room = 0; if (MS_Write(&msg) < 0) { MSLastPing = timestamp; return ConnectionFailed(); } if(con_state != MSCS_REGISTERED) CONS_Printf("Master Server Updated Successfully!\n"); MSLastPing = timestamp; con_state = MSCS_REGISTERED; CloseConnection(); #endif return MS_NO_ERROR; }
INT32 GetRoomsList(boolean hosting) { static msg_ban_t banned_info[1]; msg_t msg; INT32 i; // we must be connected to the master server before writing to it if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0)) { CONS_Printf("cannot connect to the master server\n"); M_StartMessage("There was a problem connecting to\nthe Master Server", NULL, MM_NOTHING); return -1; } if (hosting) msg.type = GET_ROOMS_HOST_MSG; else msg.type = GET_ROOMS_MSG; msg.length = 0; msg.room = 0; if (MS_Write(&msg) < 0) { room_list[0].id = 1; strcpy(room_list[0].motd,"Master Server Offline."); strcpy(room_list[0].name,"Offline"); return -1; } for (i = 0; i < NUM_LIST_ROOMS && MS_Read(&msg) >= 0; i++) { if(msg.type == GET_BANNED_MSG) { char banmsg[1000]; M_Memcpy(&banned_info[0], msg.buffer, sizeof (msg_ban_t)); if (hosting) sprintf(banmsg, "You have been banned from\nhosting netgames.\n\nUnder the following IP Range:\n%s - %s\n\nFor the following reason:\n%s\n\nYour ban will expire on:\n%s",banned_info[0].ipstart,banned_info[0].ipend,banned_info[0].reason,banned_info[0].endstamp); else sprintf(banmsg, "You have been banned from\njoining netgames.\n\nUnder the following IP Range:\n%s - %s\n\nFor the following reason:\n%s\n\nYour ban will expire on:\n%s",banned_info[0].ipstart,banned_info[0].ipend,banned_info[0].reason,banned_info[0].endstamp); M_StartMessage(banmsg, NULL, MM_NOTHING); cv_internetserver.value = false; return -2; } if (!msg.length) { room_list[i].header.buffer[0] = 0; CloseConnection(); return 1; } M_Memcpy(&room_list[i], msg.buffer, sizeof (msg_rooms_t)); room_list[i].header.buffer[0] = 1; } CloseConnection(); if (i == NUM_LIST_ROOMS) { room_list[i].header.buffer[0] = 0; return 1; } else { room_list[0].id = 1; strcpy(room_list[0].motd,"Master Server Offline."); strcpy(room_list[0].name,"Offline"); return -1; } }
/* * align a memorystream */ BOOL MS_Align(Memstream* memstream, int alignment) { /* write zeros until alignment is ok */ while (memstream->size % alignment) { MS_Write(memstream, 0, 1); } }