![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 #include "ZoneServer.h" 00002 00003 namespace SraNetwork { 00004 ZoneServer::ZoneServer(void) 00005 { 00006 } 00007 00008 00009 ZoneServer::~ZoneServer(void) 00010 { 00011 } 00012 00013 void ZoneServer::Run() 00014 { 00015 //Initalizing stuff: 00016 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... 00017 //we may need a list of used ports later so if we have started a looot of zones we may 00018 //have a "port-number-overrun" so we can start from the beginning without using an already opened port. 00019 std::map<int, ZoneInfo>::iterator it; 00020 00021 //Connect to world server 00022 m_rServerInterface = RakPeerInterface::GetInstance(); 00023 SocketDescriptor chatSocket(SraNetwork::ZONE_SERVER_PORT, 0); 00024 m_rServerInterface->Startup(1, &chatSocket, 1); 00025 m_rServerInterface->Connect(SraNetwork::WORLD_SERVER_ADDR, SraNetwork::SERVER_ZONE_PORT, 0, 0, 0); 00026 00027 printf("ZoneServer connecting to World ...."); 00028 bool done = false; 00029 bool result = false; //don't return in loop so we can shut down RakNet before exiting 00030 while (!done) //Block while connecing 00031 { 00032 Packet* m_pPacket = m_rServerInterface->Receive(); 00033 if (m_pPacket) 00034 { 00035 if (m_pPacket->data[0] == ID_CONNECTION_REQUEST_ACCEPTED) 00036 { 00037 result = true; 00038 } 00039 else if (m_pPacket->data[0] == ID_CONNECTION_ATTEMPT_FAILED) 00040 { 00041 printf("Failed: connection attempt failed\n"); 00042 } else 00043 { 00044 printf("Failed: Unknown opcode %d\n", m_pPacket->data[0]); 00045 } 00046 m_rServerInterface->DeallocatePacket(m_pPacket); 00047 m_pPacket = 0; 00048 done = true; 00049 } 00050 Sleep(10); 00051 } 00052 if (!result) 00053 { 00054 printf("Failed to connect to world, exiting now\n"); 00055 m_rServerInterface->Shutdown(0); 00056 return; 00057 } 00058 printf("Connection established, waiting for zone connections\n"); 00059 00060 bool running = true; //maybe we do not need this, but i don't like while(1) :P 00061 while (running) 00062 { 00063 Packet* m_pPacket = m_rServerInterface->Receive(); 00064 if (m_pPacket) 00065 { 00066 if ( m_pPacket->data[0] == ID_CONNECTION_LOST ) { 00067 printf("Lost connection to world server ! Shutting down now\n"); 00068 running = false; 00069 } else { 00070 SraNetwork::SraZonePacket *pack = (SraZonePacket*)m_pPacket->data; 00071 printf("Client with id : %d connects to zone %d\n", pack->clientID, pack->toZoneID); 00072 if ( pack->fromZoneID == -1 || (pack->toZoneID != -1 && pack->fromZoneID != -1) ) 00073 { 00074 it = m_mZones.find(pack->toZoneID); 00075 int currentPort; 00076 if ( it == m_mZones.end() ) 00077 { 00078 currentPort = lastPortUsed++; 00079 //requested zone is not running, so start it now: 00080 if (!spawnZone( pack->toZoneID, currentPort) ) 00081 { 00082 printf("Uh oh, could not spawn zone, this is really bad and we should do something about it\n"); 00083 } 00084 } else { 00085 //Zone is running: 00086 currentPort = it->second.zonePort; 00087 } 00088 SraZonePacket answer; 00089 ZeroMemory(&answer,sizeof(answer)); 00090 answer.clientID = pack->clientID; 00091 answer.fromZoneID = -1; 00092 answer.toZoneID = currentPort; 00093 printf("Zone spawned, sending OK\n"); 00094 if (m_rServerInterface != 0) { 00095 //Send answer to server 00096 m_rServerInterface->Send( (char*)&answer, sizeof(answer), HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true); 00097 } else { 00098 printf("m_r server interface null!\n"); 00099 } 00100 00101 } else if (pack->toZoneID == -1) 00102 { 00103 //client is logging off, so we maaaay shut down zoneID 00104 } else { 00105 printf("Corrupted package\n"); 00106 } 00107 } 00108 } 00109 m_rServerInterface->DeallocatePacket(m_pPacket); 00110 Sleep(10); 00111 } 00112 //Shut down zone processes 00113 for (it = m_mZones.begin(); it != m_mZones.end(); ++it) 00114 { 00115 shutdownZone( it->first ); 00116 } 00117 m_rServerInterface->Shutdown(0); 00118 } 00119 00120 bool ZoneServer::spawnZone(int zoneID, int port) 00121 { 00122 STARTUPINFO si; 00123 ZeroMemory(&si, sizeof(si)); 00124 PROCESS_INFORMATION pi; 00125 ZeroMemory(&pi, sizeof(pi)); 00126 si.cb = sizeof(si); 00127 00128 std::wostringstream str; 00129 //Assuming that this zone server is executed from udk\binaries\win32\usercode 00130 str << "..\\udk.exe server TestBox?dedicated?listen=true -port=" << port << " -console -log"; 00131 TCHAR * command = new TCHAR[wcslen(str.str().c_str())]; 00132 00133 wcscpy(command, str.str().c_str()); 00134 printf("Starting zone : %ws with id %d\n", command, zoneID); 00135 // Start the udk process. 00136 if( !CreateProcess( NULL, 00137 command, // udk.exe -PORT=%port% -console -log 00138 NULL, 00139 NULL, 00140 FALSE, 00141 0, 00142 NULL, 00143 NULL, 00144 &si, // Pointer to STARTUPINFO structure 00145 &pi ) // Pointer to PROCESS_INFORMATION structure 00146 ) 00147 { 00148 printf( "CreateProcess failed (%d).\n", GetLastError() ); 00149 return false; 00150 } 00151 00152 //Store zone info 00153 ZoneInfo info; 00154 ZeroMemory(&info, sizeof(info)); 00155 memcpy_s( &info.procInfo, sizeof(pi), &pi, sizeof(pi)); 00156 info.zonePort = port; 00157 m_mZones.insert( std::pair<int, ZoneInfo>(zoneID, info) ); 00158 return true; 00159 } 00160 00161 void ZoneServer::shutdownZone( int zoneID ) 00162 { 00163 std::map<int, ZoneInfo>::iterator it; 00164 00165 it = m_mZones.find( zoneID); 00166 if ( it != m_mZones.end() ) 00167 { 00168 CloseHandle( it->second.procInfo.hProcess); 00169 CloseHandle( it->second.procInfo.hThread); 00170 } 00171 } 00172 }
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.