📄 server.cpp
字号:
} delete data;#ifdef NP_DEBUG printf ("SERVER: Waiting for a response from the client @%ld...\n", S9xGetMilliTime () - START);#endif S9xNPSetAction ("SERVER: Waiting for a response from the client...", TRUE); break; case NP_CLNT_LOADED_ROM:#ifdef NP_DEBUG printf ("SERVER: Client %d loaded requested ROM @%ld...\n", c, S9xGetMilliTime () - START);#endif NPServer.Clients [c].SaidHello = TRUE; NPServer.Clients [c].Ready = FALSE; NPServer.Clients [c].Paused = FALSE; S9xNPRecomputePause (); S9xNPWaitForEmulationToComplete (); if (NPServer.SyncByReset) { S9xNPServerAddTask (NP_SERVER_SEND_SRAM, (void *) c); S9xNPServerAddTask (NP_SERVER_RESET_ALL, 0); } else S9xNPServerAddTask (NP_SERVER_SYNC_CLIENT, (void *) c); break; case NP_CLNT_RECEIVED_ROM_IMAGE:#ifdef NP_DEBUG printf ("SERVER: Client %d received ROM image @%ld...\n", c, S9xGetMilliTime () - START);#endif NPServer.Clients [c].SaidHello = TRUE; NPServer.Clients [c].Ready = FALSE; NPServer.Clients [c].Paused = FALSE; S9xNPRecomputePause (); S9xNPWaitForEmulationToComplete (); if (NPServer.SyncByReset) { S9xNPServerAddTask (NP_SERVER_SEND_SRAM, (void *) c); S9xNPServerAddTask (NP_SERVER_RESET_ALL, 0); } else S9xNPServerAddTask (NP_SERVER_SYNC_CLIENT, (void *) c); break; case NP_CLNT_WAITING_FOR_ROM_IMAGE:#ifdef NP_DEBUG printf ("SERVER: Client %d waiting for ROM image @%ld...\n", c, S9xGetMilliTime () - START);#endif NPServer.Clients [c].SaidHello = TRUE; NPServer.Clients [c].Ready = FALSE; NPServer.Clients [c].Paused = FALSE; S9xNPRecomputePause (); S9xNPSendROMImageToClient (c); break; case NP_CLNT_READY:#ifdef NP_DEBUG printf ("SERVER: Client %d ready @%ld...\n", c, S9xGetMilliTime () - START);#endif if (NPServer.Clients [c].SaidHello) { NPServer.Clients [c].Paused = FALSE; NPServer.Clients [c].Ready = TRUE; S9xNPRecomputePause (); break; } NPServer.Clients [c].SaidHello = TRUE; NPServer.Clients [c].Ready = TRUE; NPServer.Clients [c].Paused = FALSE; S9xNPRecomputePause ();//printf ("SERVER: SaidHello = TRUE, SeqNum = %d @%d\n", NPServer.Clients [c].SendSequenceNum, S9xGetMilliTime () - START); if (NPServer.NumClients > NP_ONE_CLIENT) { if (!NPServer.SendROMImageOnConnect) { S9xNPWaitForEmulationToComplete (); if (NPServer.SyncByReset) { S9xNPServerAddTask (NP_SERVER_SEND_SRAM, (void *) c); S9xNPServerAddTask (NP_SERVER_RESET_ALL, 0); } else S9xNPServerAddTask (NP_SERVER_SYNC_CLIENT, (void *) c); } } else { NPServer.Clients [c].Ready = TRUE; S9xNPRecomputePause (); } break; case NP_CLNT_JOYPAD: NPServer.Joypads [c] = len; break; case NP_CLNT_PAUSE:#ifdef NP_DEBUG printf ("SERVER: Client %d Paused: %s @%ld\n", c, (header [2] & 0x80) ? "YES" : "NO", S9xGetMilliTime () - START);#endif NPServer.Clients [c].Paused = (header [2] & 0x80) != 0; if (NPServer.Clients [c].Paused) sprintf (NetPlay.WarningMsg, "SERVER: Client %d has paused.", c + 1); else sprintf (NetPlay.WarningMsg, "SERVER: Client %d has resumed.", c + 1); S9xNPSetWarning (NetPlay.WarningMsg); S9xNPRecomputePause (); break; }}void S9xNPAcceptClient (int Listen, bool8 block){ struct sockaddr_in remote_address; struct linger val2; struct hostent *host; int new_fd;#ifdef __WIN32__ int len;#else unsigned int len;#endif int i; #ifdef NP_DEBUG printf ("SERVER: attempting to accept new client connection @%ld\n", S9xGetMilliTime () - START);#endif S9xNPSetAction ("SERVER: Attempting to accept client connection...", TRUE); memset (&remote_address, 0, sizeof (remote_address)); len = sizeof (remote_address); new_fd = accept (Listen, (struct sockaddr *) &remote_address, &len); S9xNPSetAction ("Setting socket options...", TRUE); val2.l_onoff = 1; val2.l_linger = 0; if (setsockopt (new_fd, SOL_SOCKET, SO_LINGER, (char *) &val2, sizeof (val2)) < 0) { S9xNPSetError ("Setting socket options failed."); close (new_fd); return; } for (i = 0; i < NP_MAX_CLIENTS; i++) { if (!NPServer.Clients [i].Connected) { NPServer.NumClients++; NPServer.Clients [i].Socket = new_fd; NPServer.Clients [i].SendSequenceNum = 0; NPServer.Clients [i].ReceiveSequenceNum = 0; NPServer.Clients [i].Connected = TRUE; NPServer.Clients [i].SaidHello = FALSE; NPServer.Clients [i].Paused = FALSE; NPServer.Clients [i].Ready = FALSE; NPServer.Clients [i].ROMName = NULL; NPServer.Clients [i].HostName = NULL; NPServer.Clients [i].Who = NULL; break; } } if (i >= NP_MAX_CLIENTS) { S9xNPSetError ("SERVER: Maximum number of NetPlay Clients have already connected."); close (new_fd); return; } if (remote_address.sin_family == AF_INET) {#ifdef NP_DEBUG printf ("SERVER: Looking up new client's hostname @%ld\n", S9xGetMilliTime () - START);#endif S9xNPSetAction ("SERVER: Looking up new client's hostname...", TRUE); host = gethostbyaddr ((char *) &remote_address.sin_addr, sizeof (remote_address.sin_addr), AF_INET); if (host) {#ifdef NP_DEBUG printf ("SERVER: resolved new client's hostname (%s) @%ld\n", host->h_name, S9xGetMilliTime () - START);#endif sprintf (NetPlay.WarningMsg, "SERVER: Player %d on %s has connected.", i + 1, host->h_name); NPServer.Clients [i].HostName = strdup (host->h_name); } else { char *ip = inet_ntoa (remote_address.sin_addr); if (ip) NPServer.Clients [i].HostName = strdup (ip);#ifdef NP_DEBUG printf ("SERVER: couldn't resolve new client's hostname (%s) @%ld\n", ip ? ip : "Unknown", S9xGetMilliTime () - START);#endif sprintf (NetPlay.WarningMsg, "SERVER: Player %d on %s has connected.", i + 1, ip ? ip : "Unknown"); } S9xNPSetWarning (NetPlay.WarningMsg); }#ifdef NP_DEBUG printf ("SERVER: waiting for HELLO message from new client @%ld\n", S9xGetMilliTime () - START);#endif S9xNPSetAction ("SERVER: Waiting for HELLO message from new client...");}static bool8 server_continue = TRUE;static bool8 S9xNPServerInit (int port){ struct sockaddr_in address; int i; int val; if (!S9xNPInitialise ()) return (FALSE); for (i = 0; i < NP_MAX_CLIENTS; i++) { NPServer.Clients [i].SendSequenceNum = 0; NPServer.Clients [i].ReceiveSequenceNum = 0; NPServer.Clients [i].Connected = FALSE; NPServer.Clients [i].SaidHello = FALSE; NPServer.Clients [i].Paused = FALSE; NPServer.Clients [i].Ready = FALSE; NPServer.Clients [i].Socket = 0; NPServer.Clients [i].ROMName = NULL; NPServer.Clients [i].HostName = NULL; NPServer.Clients [i].Who = NULL; NPServer.Joypads [i] = 0; } NPServer.NumClients = 0; NPServer.FrameCount = 0;#ifdef NP_DEBUG printf ("SERVER: Creating socket @%ld\n", S9xGetMilliTime () - START);#endif if ((NPServer.Socket = socket (AF_INET, SOCK_STREAM, 0)) < 0) { S9xNPSetError ("NetPlay Server: Can't create listening socket."); return (FALSE); } val = 1; setsockopt (NPServer.Socket, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof (val)); memset (&address, 0, sizeof (address)); address.sin_family = AF_INET; address.sin_addr.s_addr = htonl (INADDR_ANY); address.sin_port = htons (port);#ifdef NP_DEBUG printf ("SERVER: Binding socket to address and port @%ld\n", S9xGetMilliTime () - START);#endif if (bind (NPServer.Socket, (struct sockaddr *) &address, sizeof (address)) < 0) { S9xNPSetError ("NetPlay Server: Can't bind socket to port number.\nPort already in use?"); return (FALSE); }#ifdef NP_DEBUG printf ("SERVER: Getting socket to listen @%ld\n", S9xGetMilliTime () - START);#endif if (listen (NPServer.Socket, NP_MAX_CLIENTS) < 0) { S9xNPSetError ("NetPlay Server: Can't get new socket to listen."); return (FALSE); }#ifdef NP_DEBUG printf ("SERVER: Init complete @%ld\n", S9xGetMilliTime () - START);#endif return (TRUE);}void S9xNPServerLoop (void *){#ifdef __WIN32__ BOOL success = FALSE;#else bool8 success = FALSE;#endif while (server_continue) { fd_set read_fds; struct timeval timeout; int res; int i; int max_fd = NPServer.Socket; #ifdef __WIN32__ Sleep (0);#endif if (success && !Settings.Paused && !Settings.StopEmulation && !Settings.ForcedPause && !NPServer.Paused) { S9xNPSendHeartBeat (); } do { FD_ZERO (&read_fds); FD_SET (NPServer.Socket, &read_fds); for (i = 0; i < NP_MAX_CLIENTS; i++) { if (NPServer.Clients [i].Connected) { FD_SET (NPServer.Clients [i].Socket, &read_fds); if (NPServer.Clients [i].Socket > max_fd) max_fd = NPServer.Clients [i].Socket; } } timeout.tv_sec = 0; timeout.tv_usec = 1000; res = select (max_fd + 1, &read_fds, NULL, NULL, &timeout); if (res > 0) { if (FD_ISSET (NPServer.Socket, &read_fds)) S9xNPAcceptClient (NPServer.Socket, FALSE); for (i = 0; i < NP_MAX_CLIENTS; i++) { if (NPServer.Clients [i].Connected && FD_ISSET (NPServer.Clients [i].Socket, &read_fds)) { S9xNPProcessClient (i); } } } } while (res > 0);#ifdef __WIN32__ success = WaitForSingleObject (GUI.ServerTimerSemaphore, 200) == WAIT_OBJECT_0;#endif while (NPServer.TaskHead != NPServer.TaskTail) { void *task_data = NPServer.TaskQueue [NPServer.TaskHead].Data;#if defined(NP_DEBUG) && NP_DEBUG == 2 printf ("SERVER: task %d @%ld\n", NPServer.TaskQueue [NPServer.TaskHead].Task, S9xGetMilliTime () - START);#endif switch (NPServer.TaskQueue [NPServer.TaskHead].Task) { case NP_SERVER_SEND_ROM_IMAGE: S9xNPSendROMImageToAllClients (); break; case NP_SERVER_SYNC_CLIENT: NPServer.Clients [(int) task_data].Ready = FALSE; S9xNPRecomputePause (); S9xNPSyncClient ((int) task_data); break; case NP_SERVER_SYNC_ALL: S9xNPSyncClients (); break; case NP_SERVER_SEND_FREEZE_FILE_ALL: S9xNPSendFreezeFileToAllClients ((char *) task_data); free ((char *) task_data); break; case NP_SERVER_SEND_ROM_LOAD_REQUEST_ALL: S9xNPSendROMLoadRequest ((char *) task_data); free ((char *) task_data); break; case NP_SERVER_RESET_ALL: S9xNPNoClientReady (0); S9xNPWaitForEmulationToComplete (); S9xNPSetAction ("SERVER: Sending RESET to all clients...", TRUE);#ifdef NP_DEBUG printf ("SERVER: Sending RESET to all clients @%ld\n", S9xGetMilliTime () - START);#endif { uint8 reset [7]; uint8 *ptr; ptr = reset; *ptr++ = NP_SERV_MAGIC; *ptr++ = 0; *ptr++ = NP_SERV_RESET; WRITE_LONG (ptr, NPServer.FrameCount); S9xNPSendToAllClients (reset, 7); } break; case NP_SERVER_SEND_SRAM: NPServer.Clients [(int) task_data].Ready = FALSE; S9xNPRecomputePause (); S9xNPWaitForEmulationToComplete (); S9xNPSendSRAMToClient ((int) task_data); break; case NP_SERVER_SEND_SRAM_ALL: S9xNPNoClientReady (); S9xNPWaitForEmulationToComplete (); S9xNPSendSRAMToAllClients (); break; default: S9xNPSetError ("SERVER: *** Unknown task ***\n"); break; } NPServer.TaskHead = (NPServer.TaskHead + 1) % NP_MAX_TASKS; } }#ifdef NP_DEBUG printf ("SERVER: Server thread exiting @%ld\n", S9xGetMilliTime () - START);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -