コード例 #1
0
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;
}
コード例 #2
0
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 );
}