⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    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 + -