static void ReadNet() { char Buffer[MAX_MSGLEN]; // Check if there's any packet waiting. if (recvfrom(AcceptSocket, Buffer, MAX_MSGLEN, MSG_PEEK, NULL, NULL) < 0) { return; } // Read packet. sockaddr clientaddr; socklen_t addrlen = sizeof(sockaddr); int len = recvfrom(AcceptSocket, Buffer, MAX_MSGLEN, 0, &clientaddr, &addrlen); if (len < 1) { return; } switch (Buffer[0]) { case MCREQ_JOIN: { for (int i = 0; i < SrvList.Num(); i++) { if (!AddrCompare(&SrvList[i].Addr, &clientaddr)) { SrvList[i].Time = time(0); return; } } TSrvItem& I = SrvList.Alloc(); I.Addr = clientaddr; I.Time = time(0); } break; case MCREQ_QUIT: for (int i = 0; i < SrvList.Num(); i++) { if (!AddrCompare(&SrvList[i].Addr, &clientaddr)) { SrvList.RemoveIndex(i); break; } } break; case MCREQ_LIST: { Buffer[0] = MCREP_LIST; int Len = 1; for (int i = 0; i < SrvList.Num() && i < (MAX_MSGLEN - 1) / 6; i++) { memcpy(&Buffer[Len], SrvList[i].Addr.sa_data + 2, 4); memcpy(&Buffer[Len + 4], SrvList[i].Addr.sa_data, 2); Len += 6; } sendto(AcceptSocket, Buffer, Len, 0, &clientaddr, sizeof(sockaddr)); } break; } }
int main(int argc, const char** argv) { printf("Vavoom master server.\n"); #ifdef _WIN32 WSADATA winsockdata; //MAKEWORD(2, 2) int r = WSAStartup(MAKEWORD(1, 1), &winsockdata); if (r) { printf("Winsock initialisation failed.\n"); return -1; } TWinSockHelper Helper; #endif // Open socket for listening for requests. AcceptSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (AcceptSocket == -1) { printf("Unable to open accept socket\n"); return -1; } // Make socket non-blocking int trueval = true; #ifdef _WIN32 if (ioctlsocket(AcceptSocket, FIONBIO, (u_long*)&trueval) == -1) #else if (ioctl(AcceptSocket, FIONBIO, (char*)&trueval) == -1) #endif { closesocket(AcceptSocket); printf("Unable to make socket non-blocking\n"); return -1; } // Bind socket to the port. sockaddr_in address; address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(MASTER_SERVER_PORT); if (bind(AcceptSocket, (sockaddr*)&address, sizeof(address)) == -1) { closesocket(AcceptSocket); printf("Unable to bind socket to a port\n"); return -1; } // Main loop. while (1) { for (int i = 0; i < 1000; i++) { ReadNet(); #ifdef _WIN32 Sleep(1); #else // usleep(1); static const struct timespec sleepTime = {0, 28500000}; nanosleep(&sleepTime, NULL); #endif } // Clean up list from old records. time_t CurTime = time(0); for (size_t i = 0; i < (unsigned int)SrvList.Num(); i++) { if (CurTime - SrvList[i].Time > 15 * 60) { SrvList.RemoveIndex(i); i--; } } } // Close socket. closesocket(AcceptSocket); return 0; }
static void ParseEpisodeDef(VScriptParser* sc) { guard(ParseEpisodeDef); VEpisodeDef* EDef = NULL; int EIdx = 0; sc->ExpectName8(); // Check for replaced episode. for (int i = 0; i < EpisodeDefs.Num(); i++) { if (sc->Name8 == EpisodeDefs[i].Name) { EDef = &EpisodeDefs[i]; EIdx = i; break; } } if (!EDef) { EDef = &EpisodeDefs.Alloc(); EIdx = EpisodeDefs.Num() - 1; } // Check for removal of an episode. if (sc->Check("remove")) { EpisodeDefs.RemoveIndex(EIdx); return; } // Set defaults. EDef->Name = sc->Name8; EDef->TeaserName = NAME_None; EDef->Text = VStr(); EDef->PicName = NAME_None; EDef->Flags = 0; EDef->Key = VStr(); if (sc->Check("teaser")) { sc->ExpectName8(); EDef->TeaserName = sc->Name8; } while (1) { if (sc->Check("name")) { if (sc->Check("lookup")) { EDef->Flags |= EPISODEF_LookupText; sc->ExpectString(); EDef->Text = sc->String.ToLower(); } else { EDef->Flags &= ~EPISODEF_LookupText; sc->ExpectString(); EDef->Text = sc->String; } } else if (sc->Check("picname")) { sc->ExpectName8(); EDef->PicName = sc->Name8; } else if (sc->Check("key")) { sc->ExpectString(); EDef->Key = sc->String.ToLower(); } else if (sc->Check("noskillmenu")) { EDef->Flags |= EPISODEF_NoSkillMenu; } else if (sc->Check("optional")) { EDef->Flags |= EPISODEF_Optional; } else { break; } } unguard; }