Пример #1
0
bool PUdpHeldItemLaunchingAction::DoAction()
{
  PClient* nClient = mDecodeData->mClient;
  PChar* tChar = nClient->GetChar();
  PWorld* CurrentWorld = Worlds->GetWorld( tChar->GetLocation() );
  const PFurnitureItemTemplate* tFurnitureTemplate = NULL;
  const PDefWorldModel* tFurnitureModel = NULL;

  u32 mRawItemID = mDecodeData->mMessage->U32Data( mDecodeData->Sub0x13Start + 24 );
  //if(gDevDebug) Console->Print("Client %d wants to hack itemID %d ***not managed yet***", mDecodeData->mClient->GetID(), mRawItemID);

  // First try to find out if we're hacking an dynamic actor
  if ( WorldActors->IsDynamicActor( mRawItemID ) == true )
  {
    // Now get the get the function value: (What kind of hackable object)
    int tFunctionVal = WorldActors->GetWorldActorFunctionID( mRawItemID );

    // Then get the FUNCTION VALUE as furniture model so we can access its subvalues etc. Here: Hack difficult
    tFurnitureModel = GameDefs->WorldModels()->GetDef( tFunctionVal );
  }
  else
  {
    // Dat files have smaller IDs
    u32 ItemID = mRawItemID / 1024 - 1;

    // Now grab the template from .dat file
    tFurnitureTemplate = CurrentWorld->GetFurnitureItemTemplate( ItemID );

    // Then get the FUNCTION VALUE as furniture model so we can access its subvalues etc
    tFurnitureModel = CurrentWorld->GetFurnitureItemModel( ItemID );
  }

  if ( tFurnitureModel ) // We have an valid worldobject? Fine. Then start the hackgame
  {
    u8 tHackDifficult = tFurnitureModel->GetHackDifficulty();
    u8 tHackPenalty = tFurnitureModel->GetHackPenalty();

    // Print it!
    if(tHackDifficult)
    {
      //if (gDevDebug)
      Console->Print( "%s Client trying to hack itemID %d. Hack difficult: %d Hack penalty %d", Console->ColorText( CYAN, BLACK, "[DEBUG]" ), mRawItemID, tHackDifficult, tHackPenalty );

      PMessage* tmpMsg = MsgBuilder->BuildStartHackGameMsg( nClient, mRawItemID, tHackDifficult );
      nClient->SendUDPMessage( tmpMsg );
      tmpMsg = NULL;
    }
  }

  mDecodeData->mState = DECODE_ACTION_DONE | DECODE_FINISHED;
  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 );
}
Пример #3
0
bool PGameServer::HandleCharList( PClient *Client, PGameState *State, const u8 *Packet, int PacketSize )
{
  static u8 Answer[10] = {0xfe, 0x07, 0x00, 0x83, 0x86, 0, 0, 0, 0, 0};
  ConnectionTCP *Socket = Client->getTCPConn();

  if ( PacketSize > 9 && *( u16* )&Packet[3] == 0x8284 )
  {
    u8 Mode = Packet[9];

    switch ( Mode )
    {
      case 6: // request list
        return ( HandleRequestChars( Client, State, Packet ) );

      case 5: // validate name
      {
        if ( PacketSize < 31 )
          return ( false );

        // check for valid name string
        bool ValidString = false;

        for ( int i = 30; i < PacketSize; i++ )
          if ( Packet[i] == 0 )
          {
            ValidString = true;
            break;
          }

        const char *Name = ( char* ) & Packet[30];
        if ( ValidString )
        {
          ValidString = PChar::IsCharnameWellFormed( Name );
        }

        if ( ValidString )
        {
          if ( Chars->CharExist( std::string( Name ) ) )
          {
            ValidString = false;
          }
        }

        if ( ValidString )
          Answer[5] = 1; // ok
        else
          Answer[5] = 2; // 2..6 => 'char name already in use!'

        // Answer[5] = 0; // => 'unknown error'
        Socket->write( Answer, 10 );
        return ( true );
      }

      case 3: // delete char
      {
        PAccount Acc( Client->GetAccountID() );
        u8 Num = Packet[PacketSize-1];

        if ( Acc.GetID() )
        {
          u32 CharID = Acc.GetCharIdBySlot( Num );

          // Also check that char is out of game
          if (( CharID != 0 ) && ( Chars->GetChar( CharID ) == NULL ) )
          {
            char query[100];
            snprintf( query, 100, "DELETE FROM characters WHERE c_id = %d LIMIT 1", CharID );
            if ( MySQL->GameQuery( query ) )
              Console->Print( RED, BLACK, "[Notice] Char %d not deleted!", CharID );
            else
            {
              Console->Print( GREEN, BLACK, "[Info] Char %d deleted!", CharID );

              snprintf( query, 100, "DELETE FROM buddy_list WHERE bud_charid = %d", CharID );
              if ( MySQL->GameQuery( query ) )
                Console->Print( YELLOW, BLACK, "[Notice] Char %d's buddy list not removed!", CharID );

              snprintf( query, 100, "DELETE FROM genrep WHERE g_charid = %d", CharID );
              if ( MySQL->GameQuery( query ) )
                Console->Print( YELLOW, BLACK, "[Notice] Char %d's genrep list not removed!", CharID );

              snprintf( query, 100, "DELETE FROM inventory WHERE inv_charid = %d", CharID );
              if ( MySQL->GameQuery( query ) )
                Console->Print( YELLOW, BLACK, "[Notice] Char %d's inventory not removed!", CharID );

              Appartements->DeleteCharAppartements( CharID );
            }
          }
          else
            return false;
        }
        return ( true );
      }

      case 7: // create char
      {
        if ( PacketSize < 64 )
          return ( false );

        u32 Slot = * ( u32* ) & Packet[30];
        //u32 nClass =* (u32*)&Packet[34]; // Not used - indirectly redundant with Profession
        u32 Profession = * ( u32* ) & Packet[38];
        u32 Gender = * ( u32* ) & Packet[42];
        u32 Head = * ( u32* ) & Packet[46];
        u32 Torso = * ( u32* ) & Packet[50];
        u32 Legs = * ( u32* ) & Packet[54];
        u32 Faction = * ( u32* ) & Packet[58];
        u8 NameLen = Packet[62];
        u8 NZSNb = Packet[63];

        char TempName[256];
        std::strncpy( TempName, ( const char* )&Packet[64], NameLen );
        TempName[NameLen] = 0;

        Answer[5] = 2; // return error if char creation fails

        if ( PChar::IsCharnameWellFormed( TempName ) )
        {
          // check for already used char name - should not happen though
          if ( ! Chars->CharExist( std::string( TempName ) ) )
          {
            PAccount Acc( Client->GetAccountID() );
            PChar* nChar = new PChar();

            if ( nChar->CreateNewChar( Acc.GetID(), TempName, Gender, Profession, Faction,
                                       Head, Torso, Legs, NZSNb, ( const char* )&Packet[64+NameLen], Slot ) )
            {
              Answer[5] = 1; // return success
            }
            delete nChar;
          }
        }

        Socket->write( Answer, 10 );
        return ( true );
      }
    }
  }
  else
  {
    Console->Print( RED, BLACK, "[Notice] Gameserver protocol error (GS_CHARLIST): invalid packet [%04x]", *( u16* )&Packet[3] );

    return ( false );
  }

  return true;
}