📄 server.cpp
字号:
S9xNPStopServer ();}bool8 S9xNPStartServer (int port){ static int p;#ifdef NP_DEBUG printf ("SERVER: Starting server on port %d @%ld\n", port, S9xGetMilliTime () - START);#endif p = port; server_continue = TRUE; if (S9xNPServerInit (port))#ifdef __WIN32__ return (_beginthread (S9xNPServerLoop, 0, &p) != ~0);#else return (TRUE);#endif return (FALSE);}void S9xNPStopServer (){#ifdef NP_DEBUG printf ("SERVER: Stopping server @%ld\n", S9xGetMilliTime () - START);#endif server_continue = FALSE; close (NPServer.Socket); for (int i = 0; i < NP_MAX_CLIENTS; i++) { if (NPServer.Clients [i].Connected) { close (NPServer.Clients [i].Socket); NPServer.Clients [i].Connected = FALSE; NPServer.Clients [i].SaidHello = FALSE; } }}#ifdef __WIN32__void S9xGetTimeOfDay (struct timeval *n){ unsigned long t = S9xGetMilliTime (); n->tv_sec = t / 1000; n->tv_usec = (t % 1000) * 1000;}#endifvoid S9xNPSendROMImageToAllClients (){ S9xNPNoClientReady (); S9xNPWaitForEmulationToComplete (); int c; for (c = NP_ONE_CLIENT; c < NP_MAX_CLIENTS; c++) { if (NPServer.Clients [c].SaidHello) S9xNPSendROMImageToClient (c); } if (NPServer.SyncByReset) { S9xNPServerAddTask (NP_SERVER_SEND_SRAM_ALL, 0); S9xNPServerAddTask (NP_SERVER_RESET_ALL, 0); } else S9xNPSyncClient (-1);}bool8 S9xNPSendROMImageToClient (int c){#ifdef NP_DEBUG printf ("SERVER: Sending ROM image to player %d @%ld\n", c + 1, S9xGetMilliTime () - START);#endif sprintf (NetPlay.ActionMsg, "Sending ROM image to player %d...", c + 1); S9xNPSetAction (NetPlay.ActionMsg, TRUE); uint8 header [7 + 1 + 4]; uint8 *ptr = header; int len = sizeof (header) + Memory.CalculatedSize + strlen (Memory.ROMFilename) + 1; *ptr++ = NP_SERV_MAGIC; *ptr++ = NPServer.Clients [c].SendSequenceNum++; *ptr++ = NP_SERV_ROM_IMAGE; WRITE_LONG (ptr, len); ptr += 4; *ptr++ = Memory.HiROM; WRITE_LONG (ptr, Memory.CalculatedSize); if (!S9xNPSSendData (NPServer.Clients [c].Socket, header, sizeof (header)) || !S9xNPSSendData (NPServer.Clients [c].Socket, Memory.ROM, Memory.CalculatedSize) || !S9xNPSSendData (NPServer.Clients [c].Socket, (uint8 *) Memory.ROMFilename, strlen (Memory.ROMFilename) + 1)) { S9xNPShutdownClient (c, TRUE); return (FALSE); } return (TRUE);}void S9xNPSyncClients (){ S9xNPNoClientReady (); S9xNPSyncClient (-1);}void S9xNPSyncClient (int client){ char fname [L_tmpnam]; S9xNPWaitForEmulationToComplete (); S9xNPSetAction ("SERVER: Freezing game...", TRUE); if (tmpnam (fname) && S9xFreezeGame (fname)) { uint8 *data; uint32 len; S9xNPSetAction ("SERVER: Loading freeze file...", TRUE); if (S9xNPLoadFreezeFile (fname, data, len)) { int c; if (client < 0) { for (c = NP_ONE_CLIENT; c < NP_MAX_CLIENTS; c++) { if (NPServer.Clients [c].SaidHello) { NPServer.Clients [client].Ready = FALSE; S9xNPRecomputePause (); S9xNPSendFreezeFile (c, data, len); } } } else { NPServer.Clients [client].Ready = FALSE; S9xNPRecomputePause (); S9xNPSendFreezeFile (client, data, len); } delete data; } (void) remove (fname); }}bool8 S9xNPLoadFreezeFile (const char *fname, uint8 *&data, uint32 &len){ FILE *ff; if ((ff = fopen (fname, "rb"))) { fseek (ff, 0, SEEK_END); len = ftell (ff); fseek (ff, 0, SEEK_SET); data = new uint8 [len]; bool8 ok = (fread (data, 1, len, ff) == len); fclose (ff); return (ok); } return (FALSE);}void S9xNPSendFreezeFile (int c, uint8 *data, uint32 len){#ifdef NP_DEBUG printf ("SERVER: Sending freeze file to player %d @%ld\n", c + 1, S9xGetMilliTime () - START);#endif sprintf (NetPlay.ActionMsg, "SERVER: Sending freeze-file to player %d...", c + 1); S9xNPSetAction (NetPlay.ActionMsg, TRUE); uint8 header [7 + 4]; uint8 *ptr = header; *ptr++ = NP_SERV_MAGIC; *ptr++ = NPServer.Clients [c].SendSequenceNum++; *ptr++ = NP_SERV_FREEZE_FILE; WRITE_LONG (ptr, len + 7 + 4); ptr += 4; WRITE_LONG (ptr, NPServer.FrameCount); if (!S9xNPSSendData (NPServer.Clients [c].Socket, header, 7 + 4) || !S9xNPSSendData (NPServer.Clients [c].Socket, data, len)) { S9xNPShutdownClient (c, TRUE); }}void S9xNPRecomputePause (){ int c; for (c = 0; c < NP_MAX_CLIENTS; c++) { if (NPServer.Clients [c].SaidHello && (!NPServer.Clients [c].Ready || NPServer.Clients [c].Paused)) {#if defined(NP_DEBUG) && NP_DEBUG == 2 printf ("SERVER: Paused because of client %d (%d,%d) @%ld\n", c, NPServer.Clients [c].Ready, NPServer.Clients [c].Paused, S9xGetMilliTime () - START);#endif NPServer.Paused = TRUE; return; } }#if defined(NP_DEBUG) && NP_DEBUG == 2 printf ("SERVER: not paused @%ld\n", S9xGetMilliTime () - START);#endif NPServer.Paused = FALSE;}void S9xNPNoClientReady (int start_index){ int c; for (c = start_index; c < NP_MAX_CLIENTS; c++) NPServer.Clients [c].Ready = FALSE; S9xNPRecomputePause ();}void S9xNPSendROMLoadRequest (const char *filename){ S9xNPNoClientReady (); int len = 7 + strlen (filename) + 1; uint8 *data = new uint8 [len]; uint8 *ptr = data; *ptr++ = NP_SERV_MAGIC; *ptr++ = 0; *ptr++ = NP_SERV_LOAD_ROM; WRITE_LONG (ptr, len); ptr += 4; strcpy ((char *) ptr, filename); for (int i = NP_ONE_CLIENT; i < NP_MAX_CLIENTS; i++) { if (NPServer.Clients [i].SaidHello) {#ifdef NP_DEBUG printf ("SERVER: Sending load ROM requesting to player %d @%ld\n", i + 1, S9xGetMilliTime () - START);#endif sprintf (NetPlay.WarningMsg, "SERVER: sending ROM load request to player %d...", i + 1); S9xNPSetAction (NetPlay.WarningMsg, TRUE); data [1] = NPServer.Clients [i].SendSequenceNum++; if (!S9xNPSSendData (NPServer.Clients [i].Socket, data, len)) { S9xNPShutdownClient (i, TRUE); } } } delete data;}void S9xNPSendSRAMToAllClients (){ int i; for (i = NP_ONE_CLIENT; i < NP_MAX_CLIENTS; i++) { if (NPServer.Clients [i].SaidHello) S9xNPSendSRAMToClient (i); }}void S9xNPSendSRAMToClient (int c){#ifdef NP_DEBUG printf ("SERVER: Sending S-RAM data to player %d @%ld\n", c + 1, S9xGetMilliTime () - START);#endif uint8 sram [7]; int SRAMSize = Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0; if (SRAMSize > 0x10000) SRAMSize = 0x10000; int len = 7 + SRAMSize; sprintf (NetPlay.ActionMsg, "SERVER: Sending S-RAM to player %d...", c + 1); S9xNPSetAction (NetPlay.ActionMsg, TRUE); uint8 *ptr = sram; *ptr++ = NP_SERV_MAGIC; *ptr++ = NPServer.Clients [c].SendSequenceNum++; *ptr++ = NP_SERV_SRAM_DATA; WRITE_LONG (ptr, len); if (!S9xNPSSendData (NPServer.Clients [c].Socket, sram, sizeof (sram)) || (len > 7 && !S9xNPSSendData (NPServer.Clients [c].Socket, ::SRAM, len - 7))) { S9xNPShutdownClient (c, TRUE); }}void S9xNPSendFreezeFileToAllClients (const char *filename){ uint8 *data; uint32 len; if (NPServer.NumClients > NP_ONE_CLIENT && S9xNPLoadFreezeFile (filename, data, len)) { S9xNPNoClientReady (); for (int c = NP_ONE_CLIENT; c < NP_MAX_CLIENTS; c++) { if (NPServer.Clients [c].SaidHello) S9xNPSendFreezeFile (c, data, len); } delete data; }}void S9xNPServerAddTask (uint32 task, void *data){ NPServer.TaskQueue [NPServer.TaskTail].Task = task; NPServer.TaskQueue [NPServer.TaskTail].Data = data; NPServer.TaskTail = (NPServer.TaskTail + 1) % NP_MAX_TASKS;}void S9xNPReset (){ S9xNPNoClientReady (0); S9xNPServerAddTask (NP_SERVER_RESET_ALL, 0);}void S9xNPWaitForEmulationToComplete (){#ifdef NP_DEBUG printf ("SERVER: WaitForEmulationToComplete start @%ld\n", S9xGetMilliTime () - START);#endif while (!NetPlay.PendingWait4Sync && NetPlay.Connected && !Settings.ForcedPause && !Settings.StopEmulation && !Settings.Paused) {#ifdef __WIN32__ Sleep (40);#endif }#ifdef NP_DEBUG printf ("SERVER: WaitForEmulationToComplete end @%ld\n", S9xGetMilliTime () - START);#endif}void S9xNPServerQueueSyncAll (){ if (Settings.NetPlay && Settings.NetPlayServer && NPServer.NumClients > NP_ONE_CLIENT) { S9xNPNoClientReady (); S9xNPDiscardHeartbeats (); S9xNPServerAddTask (NP_SERVER_SYNC_ALL, 0); }}void S9xNPServerQueueSendingROMImage (){ if (Settings.NetPlay && Settings.NetPlayServer && NPServer.NumClients > NP_ONE_CLIENT) { S9xNPNoClientReady (); S9xNPDiscardHeartbeats (); S9xNPServerAddTask (NP_SERVER_SEND_ROM_IMAGE, 0); }}void S9xNPServerQueueSendingFreezeFile (const char *filename){ if (Settings.NetPlay && Settings.NetPlayServer && NPServer.NumClients > NP_ONE_CLIENT) { S9xNPNoClientReady (); S9xNPDiscardHeartbeats (); S9xNPServerAddTask (NP_SERVER_SEND_FREEZE_FILE_ALL, (void *) strdup (filename)); }}void S9xNPServerQueueSendingLoadROMRequest (const char *filename){ if (Settings.NetPlay && Settings.NetPlayServer && NPServer.NumClients > NP_ONE_CLIENT) { S9xNPNoClientReady (); S9xNPDiscardHeartbeats (); S9xNPServerAddTask (NP_SERVER_SEND_ROM_LOAD_REQUEST_ALL, (void *) strdup (filename)); }}#ifndef __WIN32__uint32 S9xGetMilliTime (){ static bool8 first = TRUE; static long start_sec; struct timeval tv; gettimeofday (&tv, NULL); if (first) { start_sec = tv.tv_sec; first = FALSE; } return ((uint32) ((tv.tv_sec - start_sec) * 1000 + tv.tv_usec / 1000));}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -