bool PPatchServer::ProcessClient(PClient *Client, PPatchState *State) { static const u8 HANDSHAKE0A[6]={0xfe, 0x03, 0x00, 0x80, 0x03, 0x6b}; if(!State) { PatchStateMap::iterator node = ClientStates.find(Client); if(node == ClientStates.end()) return false; State = node->second; } ConnectionTCP *Socket = Client->getTCPConn(); if(State->mWaitSend && Socket->getSendBufferSize()==0) return false; if(State->mState==PPatchState::PS_CONNECTED) { Console->Print("Sending Handshake 0A"); Socket->write(HANDSHAKE0A, sizeof(HANDSHAKE0A)); //short unsigned int packet = (short unsigned int) HANDSHAKE0A; //Socket->write(htons(packet)); State->mState = PPatchState::PS_HANDSHAKE0; Socket->flushSendBuffer(); } int PacketSize=0; const u8 *Packet = Socket->read(&PacketSize); if(PacketSize > 0) { switch(State->mState) { case PPatchState::PS_HANDSHAKE1 : case PPatchState::PS_HANDSHAKE0 : Console->Print("Handling Handshake 0 and 1"); return HandleHandshake(Client, State, Packet, PacketSize); case PPatchState::PS_VERSIONREQUEST : Console->Print("Handling Client Versionsrequest"); return HandleVersionRequest(Client, State, Packet, PacketSize); case PPatchState::PS_GETPATCHORFILE : case PPatchState::PS_SENDPATCH : case PPatchState::PS_SENDFILE : Console->Print("Getpatchforfile, sendpatch, sendfile"); return HandleFileRequests(Client, State, Packet, PacketSize); default: break; } } return true; }
bool PGameServer::HandleGameInfo( PClient *Client, PGameState *State, const u8 *Packet ) { // Console->Print("Inside HandleGameInfo");//NEW added static u8 GameInfo[31] = {0xfe, 0x1c, 0x00, 0x83, 0x05, // header 0x00, 0x00, 0x00, 0x00, // account id 0x00, 0x00, 0x00, 0x00, // char id 0x00, 0x00, 0x00, 0x00, // udp ip 0x00, 0x00, // udp port 0x00, 0x00, 0x00, 0x00, // unknown 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // session key }; ConnectionTCP *Socket = Client->getTCPConn(); if ( *( u16* )&Packet[3] == 0x3c87 ) { //int PortFix = Config->GetOptionInt("debug_mode"); ConnectionUDP* udpConn = ServerSock->getUDPConnection( IPStringToDWord( Client->GetAddress() ), Client->GetRemoteUDPPort() ); Client->setUDPConnection( udpConn ); if ( !udpConn ) { Console->Print( RED, BLACK, "Client %d: UDP port setup failed", Client->GetID() ); ClientDisconnected( Client ); } u16 Port = Client->getUDPConn()->getPort(); if ( Port == 0 ) Console->Print( RED, BLACK, "Client->OpenUDP() failed" ); /* if(PortFix == 1) // removed, no more use { Port = Config->GetOptionInt("useudpport"); Console->Print(YELLOW, BLACK, "UDP Port set to non-standard for debugging!"); }; */ u32 IP; std::string IPServerString; // use [server_nat_ip] for server if client is NOT on [no_nat_net] (and [no_nat_net]!=0) if ( strcmp( Config->GetOption( "no_nat_net" ).c_str(), "0" ) && strncmp( Client->GetAddress(), Config->GetOption( "no_nat_net" ).c_str(), strlen( Config->GetOption( "no_nat_net" ).c_str() ) ) ) { IPServerString = Config->GetOption( "server_nat_ip" ); } else // else client is "local" so use [server_ip] { IPServerString = Config->GetOption( "server_ip" ); } IP = IPStringToDWord( IPServerString.c_str() ); //Console->Print("IP-1 %d", IP); if ( IP == 0 ) IP = 0x0100007f; //Console->Print("IP-2 %d", IP); *( u32* )&GameInfo[13] = IP; *( u16* )&GameInfo[17] = Port; Console->Print( GREEN, BLACK, "[Info] Using UDP %s:%d on server", IPServerString.c_str(), Port ); *( u32* )&GameInfo[5] = Client->GetAccountID(); *( u32* )&GameInfo[9] = Client->GetCharID(); Console->Print( GREEN, BLACK, "[Info] Serving char id :%d", Client->GetCharID() ); Socket->write( GameInfo, 31 ); Socket->flushSendBuffer(); static const u8 READY[7] = {0xfe, 0x04, 0x00, 0x83, 0x0d, 0x00, 0x00}; Socket->write( READY, 7 ); State->TCP.mState = PGameState::TCP::GS_INGAME; State->UDP.mState = PGameState::UDP::GUS_SYNC0; //Console->Print("Sync Reset"); Client->ResetTransactionID(); // Mark char as Online PChar *Char = Client->GetChar(); Char->SetOnlineStatus( true ); //Also using this info to check if Char may have to be saved at client disconnect Client->ChangeCharLocation( Char->GetLocation(), true ); // hello-message from server.. /* std::string serverName = Config->GetOption("server_name"); std::string helloMessage = "Welcome to " + serverName + " - A TinNS Neocron Server."; char* message = (char*) helloMessage.c_str(); Chat->send(Client, CHAT_DIRECT, "System", message, false); */ bool SendBC = false; if ( Config->GetOptionInt( "broadcast_new" ) == 1 ) { if ( Config->GetOptionInt( "broadcast_new_hidestaff" ) == 1 ) { if ( Client->GetAccountLevel() > PAL_REGPLAYER ) SendBC = false; else SendBC = true; } else { SendBC = true; } } if ( SendBC == true ) { std::string playerName = Chars->GetChar( Client->GetCharID() )->GetName(); std::string serverName = Config->GetOption( "server_name" ); std::string helloMessage = "Hello " + playerName + "! Welcome to " + serverName + " - A TinNS Neocron Server."; char* message = ( char* ) helloMessage.c_str(); Chat->sendOOCBroadcast( message ); } //Console->Print("UDP Setup: %s", nlGetErrorStr(nlGetError())); } else { Console->Print( RED, BLACK, "[Notice] Gameserver protocol error (GS_GAMEINFO): invalid packet [%04x]", *( u16* )&Packet[3] ); return ( false ); } return ( true ); }