Shadowrun: Awakened 29 September 2011 - Build 871
Classes | Public Member Functions | Private Member Functions | Private Attributes
SraNetwork::ZoneServer Class Reference

#include <ZoneServer.h>

List of all members.

Classes

struct  ZoneInfo

Public Member Functions

void Run ()
 ZoneServer (void)
 ~ZoneServer (void)

Private Member Functions

void shutdownZone (int zoneID)
bool spawnZone (int zoneID, int port)

Private Attributes

std::map< int, ZoneInfom_mZones
RakPeerInterfacem_rServerInterface

Detailed Description

Definition at line 38 of file ZoneServer.h.


Constructor & Destructor Documentation

SraNetwork::ZoneServer::ZoneServer ( void  )

Definition at line 4 of file ZoneServer.cpp.

    {
    }
SraNetwork::ZoneServer::~ZoneServer ( void  )

Definition at line 9 of file ZoneServer.cpp.

    {
    }

Member Function Documentation

void SraNetwork::ZoneServer::Run ( )

Definition at line 13 of file ZoneServer.cpp.

References SraNetwork::SraZonePacket::clientID, RakNet::RakPeerInterface::Connect(), RakNet::Packet::data, RakNet::RakPeerInterface::DeallocatePacket(), SraNetwork::SraZonePacket::fromZoneID, HIGH_PRIORITY, ID_CONNECTION_ATTEMPT_FAILED, ID_CONNECTION_LOST, ID_CONNECTION_REQUEST_ACCEPTED, m_mZones, m_rServerInterface, RakNet::RakPeerInterface::Receive(), RELIABLE_ORDERED, RakNet::RakPeerInterface::Send(), SraNetwork::SERVER_ZONE_PORT, RakNet::RakPeerInterface::Shutdown(), shutdownZone(), spawnZone(), RakNet::RakPeerInterface::Startup(), SraNetwork::SraZonePacket::toZoneID, RakNet::UNASSIGNED_SYSTEM_ADDRESS, SraNetwork::WORLD_SERVER_ADDR, and SraNetwork::ZONE_SERVER_PORT.

Referenced by main().

    {   
        //Initalizing stuff:
        int lastPortUsed = 6000; //The next unused port, we will start at port 6000. !Attention! do not try to use a port > 9999 or the udk server wont't accept connections...
        //we may need a list of used ports later so if we have started a looot of zones we may 
        //have a "port-number-overrun" so we can start from the beginning without using an already opened port.
        std::map<int, ZoneInfo>::iterator it;

        //Connect to world server
        m_rServerInterface = RakPeerInterface::GetInstance();
        SocketDescriptor chatSocket(SraNetwork::ZONE_SERVER_PORT, 0);
        m_rServerInterface->Startup(1, &chatSocket, 1);
        m_rServerInterface->Connect(SraNetwork::WORLD_SERVER_ADDR, SraNetwork::SERVER_ZONE_PORT, 0, 0, 0);

        printf("ZoneServer connecting to World ....");
        bool done = false; 
        bool result = false; //don't return in loop so we can shut down RakNet before exiting
        while (!done) //Block while connecing
        {
            Packet* m_pPacket = m_rServerInterface->Receive();
            if (m_pPacket) 
            {
                if (m_pPacket->data[0] == ID_CONNECTION_REQUEST_ACCEPTED) 
                {
                    result = true;
                } 
                else if (m_pPacket->data[0] == ID_CONNECTION_ATTEMPT_FAILED)
                {
                    printf("Failed: connection attempt failed\n");
                } else 
                {
                    printf("Failed: Unknown opcode %d\n", m_pPacket->data[0]);
                }
                m_rServerInterface->DeallocatePacket(m_pPacket);
                m_pPacket = 0;
                done = true;
            }
            Sleep(10);
        }
        if (!result)
        {
            printf("Failed to connect to world, exiting now\n");
            m_rServerInterface->Shutdown(0);
            return;
        }
        printf("Connection established, waiting for zone connections\n");

        bool running = true; //maybe we do not need this, but i don't like while(1) :P
        while (running)
        {
            Packet* m_pPacket = m_rServerInterface->Receive();
            if (m_pPacket) 
            {
                if ( m_pPacket->data[0] == ID_CONNECTION_LOST ) {
                    printf("Lost connection to world server ! Shutting down now\n");
                    running = false;
                } else {
                    SraNetwork::SraZonePacket *pack = (SraZonePacket*)m_pPacket->data;
                    printf("Client with id : %d connects to zone %d\n", pack->clientID, pack->toZoneID);
                    if ( pack->fromZoneID == -1 || (pack->toZoneID != -1 && pack->fromZoneID != -1) ) 
                    {
                        it = m_mZones.find(pack->toZoneID);
                        int currentPort;
                        if ( it == m_mZones.end() ) 
                        {
                            currentPort  = lastPortUsed++;
                            //requested zone is not running, so start it now:
                            if (!spawnZone( pack->toZoneID, currentPort) ) 
                            {
                                printf("Uh oh, could not spawn zone, this is really bad and we should do something about it\n");
                            }
                        } else {
                            //Zone is running:
                            currentPort = it->second.zonePort;
                        }
                        SraZonePacket answer;
                        ZeroMemory(&answer,sizeof(answer));
                        answer.clientID = pack->clientID;
                        answer.fromZoneID = -1;
                        answer.toZoneID = currentPort;
                        printf("Zone spawned, sending OK\n");
                        if (m_rServerInterface != 0) {
                        //Send answer to server
                        m_rServerInterface->Send( (char*)&answer, sizeof(answer), HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
                        } else {
                            printf("m_r server interface null!\n");
                        }

                    } else if (pack->toZoneID == -1)
                    {
                        //client is logging off, so we maaaay shut down zoneID
                    } else {
                        printf("Corrupted package\n");
                    }
                }
            }
            m_rServerInterface->DeallocatePacket(m_pPacket);
            Sleep(10);
        }
        //Shut down zone processes
        for (it = m_mZones.begin(); it != m_mZones.end(); ++it)
        {
            shutdownZone( it->first );
        }
        m_rServerInterface->Shutdown(0);
    }
void SraNetwork::ZoneServer::shutdownZone ( int  zoneID) [private]

Shutdown zone with the given id

Definition at line 161 of file ZoneServer.cpp.

References m_mZones.

Referenced by Run().

    {
        std::map<int, ZoneInfo>::iterator it;

        it = m_mZones.find( zoneID);
        if ( it != m_mZones.end() ) 
        {
            CloseHandle( it->second.procInfo.hProcess);
            CloseHandle( it->second.procInfo.hThread);
        }
    }
bool SraNetwork::ZoneServer::spawnZone ( int  zoneID,
int  port 
) [private]

Start zone with the given id on the given port.

Definition at line 120 of file ZoneServer.cpp.

References m_mZones, SraNetwork::ZoneServer::ZoneInfo::procInfo, and SraNetwork::ZoneServer::ZoneInfo::zonePort.

Referenced by Run().

    {
        STARTUPINFO si;
        ZeroMemory(&si, sizeof(si));
        PROCESS_INFORMATION pi;
        ZeroMemory(&pi, sizeof(pi));
        si.cb = sizeof(si);
        
        std::wostringstream str;
        //Assuming that this zone server is executed from udk\binaries\win32\usercode
        str << "..\\udk.exe server TestBox?dedicated?listen=true -port=" << port << " -console -log";
        TCHAR * command = new TCHAR[wcslen(str.str().c_str())];
        
        wcscpy(command, str.str().c_str());
        printf("Starting zone : %ws with id %d\n", command, zoneID);
        // Start the udk process. 
        if( !CreateProcess( NULL,  
            command,        // udk.exe -PORT=%port% -console -log
            NULL,
            NULL,
            FALSE,
            0,    
            NULL, 
            NULL, 
            &si,            // Pointer to STARTUPINFO structure
            &pi )           // Pointer to PROCESS_INFORMATION structure
            ) 
        {
            printf( "CreateProcess failed (%d).\n", GetLastError() );
            return false;
        }

        //Store zone info 
        ZoneInfo info;
        ZeroMemory(&info, sizeof(info));
        memcpy_s( &info.procInfo, sizeof(pi), &pi, sizeof(pi));
        info.zonePort = port;
        m_mZones.insert( std::pair<int, ZoneInfo>(zoneID, info) );
        return true;
    }

Member Data Documentation

std::map<int, ZoneInfo> SraNetwork::ZoneServer::m_mZones [private]

Map of active zones.

Definition at line 64 of file ZoneServer.h.

Referenced by Run(), shutdownZone(), and spawnZone().

Definition at line 60 of file ZoneServer.h.

Referenced by Run().


The documentation for this class was generated from the following files:

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net