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; }
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 ); }
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; }