Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include <conio.h>
- #include <map>
- //90.227.223.129
- void error_handler( const char *msg, bool is_fatal = false );
- // session vars - needed to login to game server
- unsigned char ls_sessionKey1[8] = {0,0,0,0, 0,0,0,0};
- unsigned char ls_sessionKey2[8] = {0,0,0,0, 0,0,0,0};
- // session vars - needed to parse game packets
- L2Game_KeyPacket *p_game_key = NULL;
- unsigned char p_initialGameKey[8] = {0,0,0,0, 0,0,0,0};
- // Ready / Recv params
- int readyRead = 0, readyWrite = 0, recvBytes = 0;
- // Game Server network stuff
- SOCKET pGameSocket=NULL;
- unsigned char *GameNetBuffer = 0;
- unsigned int GameRcvdLen = 0, GameSentLen = 0;
- // Timer Stuff
- long timerResolutionMsec = 10;
- DWORD lastWorldTickTime;
- // Std map that include all world objects for your client.
- std::map< int, L2Player* > mGameWorldObjects;
- void ProcessLoginState( const char *l2login, const char *l2pass )
- {
- SOCKET s = L2PNet_TCPsocket_create( true ); // create async TCP socket
- if( s == INVALID_SOCKET )
- {
- error_handler( "socket creation" );
- return;
- }
- printf( "Socket created to Auth Server...\n" );
- // start connecting
- printf( "Connecting to Auth Server... " );
- L2PNet_connect( s, "90.227.223.129", 2106 );
- // network vars
- int nTries;
- nTries = 10;
- recvBytes = 0;
- while( nTries>0 && recvBytes==0 )
- {
- printf( "." );
- recvBytes = L2PNet_select( s, L2PNET_SELECT_WRITE, 1000, &readyRead, &readyWrite );
- if( recvBytes == 1 ) break;
- nTries--;
- }
- if( recvBytes == 0 )
- {
- error_handler( "Connect failed!" );
- return;
- }
- printf( "Connected to Auth Server.\n" );
- // network receive bufer
- unsigned char *netbuffer = (unsigned char *)malloc( 20*1024 ); // 20 kb ok?
- unsigned int rcvdLen = 0, sentLen = 0; // bytes
- int i = 0;
- // packets objects
- L2LoginPacket *p_l = NULL;
- L2Login_Init *p_Init = NULL;
- L2Login_RequestGGAuth *p_rggauth = NULL;
- L2Login_GGAuthResponse *p_ggar = NULL;
- L2Login_RequestAuthLogin *p_ral = NULL;
- L2Login_LoginOK *p_lok = NULL;
- L2Login_LoginFail *p_lfail = NULL;
- L2Login_AccountKicked *p_acckick = NULL;
- L2Login_RequestServerList *p_rslist = NULL;
- L2Login_ServerList *p_slist = NULL;
- L2Login_RequestServerLogin *p_rgsl = NULL;
- L2Login_PlayOK *p_pok = NULL;
- L2Login_PlayFail *p_pfail = NULL;
- // receive Init packet
- recvBytes = L2PacketReceive_buffer( s, 5000, &rcvdLen, netbuffer );
- if( recvBytes <= 0 ) // read timeout or read error
- {
- error_handler( "Recv Init" );
- goto cleanup;
- }
- printf( "Recv init: rcvd %u bytes\n", rcvdLen );
- if( rcvdLen != 186 ) // T1-T23 Init packet must be 186 bytes
- printf( "Warning: Init packet len != 186!\n" );
- else
- printf( "Received Init packet OK\n" );
- p_Init = new L2Login_Init( netbuffer, rcvdLen );
- if( !p_Init->parse() )
- printf( "Init parse error!\n" );
- else
- printf( "Init parse OK\n" );
- // out some info
- printf( "Login protocol version: %08x (%u)\n", p_Init->p_protoVer, p_Init->p_protoVer );
- printf( "Login sessionId: %02x %02x %02x %02x\n",
- p_Init->p_sessionId[0], p_Init->p_sessionId[1],
- p_Init->p_sessionId[2], p_Init->p_sessionId[3] );
- // check protocol
- if( p_Init->p_protoVer != 0x0000C621 )
- {
- error_handler( "Login protocol version invalid!" );
- goto cleanup;
- }
- // send RequestGGAuth
- p_rggauth = new L2Login_RequestGGAuth();
- memcpy( p_rggauth->sessionId, p_Init->p_sessionId, 4 );
- p_rggauth->create();
- p_rggauth->encodeAndPrepareToSend( p_Init->p_BF_dyn_key );
- recvBytes = L2PacketSend( s, p_rggauth, 5000, &sentLen );
- if( recvBytes <= 0 )
- {
- error_handler( "Send RequestGGAuth failed!" );
- goto cleanup;
- }
- printf( "RequestGGAuth: Sent %u bytes\n", sentLen );
- delete p_rggauth;
- // recv GGAuthResponse
- recvBytes = L2PacketReceive_buffer( s, 5000, &rcvdLen, netbuffer );
- printf( "Recv GGAuthResponse: rcvd %u bytes\n", rcvdLen );
- if( recvBytes <= 0 ) // read timeout or read error
- {
- error_handler( "Recv GGAuthResponse" );
- goto cleanup;
- }
- p_ggar = new L2Login_GGAuthResponse( netbuffer, rcvdLen );
- p_ggar->decodeBlowfish( p_Init->p_BF_dyn_key );
- p_ggar->parse();
- printf( "GGAuth response: %02X %08X\n", p_ggar->getPacketType(), p_ggar->p_ggAuthResponse );
- // create RequestAuthLogin
- p_ral = new L2Login_RequestAuthLogin();
- p_ral->create( l2login, l2pass, p_ggar->p_ggAuthResponse,
- p_Init->p_RSA_pubKeyMod );
- p_ral->encodeAndPrepareToSend( p_Init->p_BF_dyn_key );
- recvBytes = L2PacketSend( s, p_ral, 5000, &sentLen );
- delete p_ggar;
- delete p_ral;
- if( recvBytes <= 0 )
- {
- error_handler( "Send RequestAuthLogin failed!" );
- goto cleanup;
- }
- printf( "Sent %u bytes RequestAuthLogin\n", sentLen );
- // receive answer to RequestAuthLogin
- recvBytes = L2PacketReceive_buffer( s, 5000, &rcvdLen, netbuffer );
- printf( "Received %u bytes\n", rcvdLen );
- if( recvBytes <= 0 )
- {
- error_handler( "Recv answer to RequestAuthLogin failed!" );
- goto cleanup;
- }
- p_l = new L2LoginPacket( netbuffer, rcvdLen );
- p_l->decodeBlowfish( p_Init->p_BF_dyn_key );
- switch( p_l->getPacketType() )
- {
- case 0x01:
- {
- printf( "Login failed!\n" );
- p_lfail = new L2Login_LoginFail( p_l->getBytesPtr(), p_l->getPacketSize() );
- // no parse() func here ><
- p_lfail->getPacketType();
- unsigned int reason = p_lfail->read_reason();
- char reason_str[64];
- p_lfail->getReasonStr( reason, reason_str );
- printf( "Reason: %s\n", reason_str );
- delete p_l;
- delete p_lfail;
- goto cleanup;
- } break;
- case 0x02:
- {
- printf( "Account kicked!\n" );
- p_acckick = new L2Login_AccountKicked( p_l->getBytesPtr(),
- p_l->getPacketSize() );
- p_acckick->parse();
- char reason_str[64];
- p_acckick->getReasonStr( reason_str );
- printf( "Reason: %s\n", reason_str );
- delete p_acckick;
- delete p_l;
- goto cleanup;
- }
- case 0x03:
- {
- printf( "Login OK!\n" );
- p_lok = new L2Login_LoginOK( p_l->getBytesPtr(), p_l->getPacketSize() );
- p_lok->getPacketType();
- p_lok->read_sessionKey1( ls_sessionKey1 );
- delete p_lok;
- } break;
- default:
- printf( "Unknown response to RequestAuthLogin: %02X\n", p_l->getPacketType() );
- break;
- }
- delete p_l;
- printf( "SessionKey1: " );
- for( i=0; i<8; i++ ) printf( "%02X ", ls_sessionKey1[i] );
- printf( "\n" );
- // send RequestServerList
- p_rslist = new L2Login_RequestServerList();
- p_rslist->create( ls_sessionKey1 );
- p_rslist->encodeAndPrepareToSend( p_Init->p_BF_dyn_key );
- recvBytes = L2PacketSend( s, p_rslist, 5000, &sentLen );
- delete p_rslist;
- if( recvBytes <= 0 )
- {
- error_handler( "Send RequestServerList failed!" );
- goto cleanup;
- }
- printf( "Sent %u bytes: RequestServerList\n", sentLen );
- // receive ServerList
- recvBytes = L2PacketReceive_buffer( s, 5000, &rcvdLen, netbuffer );
- printf( "Received %u bytes: ServerList\n", rcvdLen );
- if( recvBytes <= 0 )
- {
- error_handler( "Recv ServerList" );
- goto cleanup;
- }
- // parse
- p_slist = new L2Login_ServerList( netbuffer, rcvdLen );
- p_slist->decodeBlowfish( p_Init->p_BF_dyn_key );
- unsigned char gsCount, lastServerID;
- p_slist->read_header( &gsCount, &lastServerID );
- printf( "ServerList: %d game servers, last server: %d\n",
- (int)gsCount, (int)lastServerID );
- // array of game servers info
- L2GameServerInfo gsi[32];
- for( i=0; i<gsCount; i++ )
- {
- p_slist->read_next_GS_Info( &(gsi[i]) );
- printf( "\n==== Server ID %d ====\n", (int)gsi[i].gsID );
- printf( "Addr: %d.%d.%d.%d:%d\n", (int)gsi[i].gsIP[0], (int)gsi[i].gsIP[1],
- (int)gsi[i].gsIP[2], (int)gsi[i].gsIP[3], (int)gsi[i].gsPort );
- if( gsi[i].gsIsUp )
- {
- printf( "Online; Players %d / %d (%3.2f%% load)\n",
- gsi[i].gsPlayersOnline, gsi[i].gsPlayersMax,
- (100.0f * (float)gsi[i].gsPlayersOnline / (float)gsi[i].gsPlayersMax) );
- }
- else printf( "Offline\n" );
- }
- delete p_slist;
- int choose_gsID;
- printf( "Enter game server ID to play: " );
- scanf( "%d", &choose_gsID );
- // send RequestServerLogin with selected server ID
- p_rgsl = new L2Login_RequestServerLogin();
- p_rgsl->create( ls_sessionKey1, (unsigned char)choose_gsID );
- p_rgsl->encodeAndPrepareToSend( p_Init->p_BF_dyn_key );
- recvBytes = L2PacketSend( s, p_rgsl, 5000, &sentLen );
- delete p_rgsl;
- if( recvBytes <= 0 )
- {
- error_handler( "Send RequestServerLogin failed!" );
- goto cleanup;
- }
- printf( "Sent %u bytes: RequestServerLogin\n", sentLen );
- // receive server response: PlayOK or PlayFail
- recvBytes = L2PacketReceive_buffer( s, 5000, &rcvdLen, netbuffer );
- printf( "Recv %u bytes: response to RequestServerLogin\n", rcvdLen );
- if( recvBytes <= 0 )
- {
- error_handler( "Recv PlayOK/PlayFail error" );
- goto cleanup;
- }
- // parse
- p_l = new L2LoginPacket( netbuffer, rcvdLen );
- p_l->decodeBlowfish( p_Init->p_BF_dyn_key );
- switch( p_l->getPacketType() )
- {
- case 0x06: // PlayFail
- {
- printf( "PlayFail!\n" );
- p_pfail = new L2Login_PlayFail( p_l->getBytesPtr(), p_l->getPacketSize() );
- p_pfail->getPacketType();
- unsigned char reasonCode = p_pfail->read_reason();
- char reasonStr[64];
- p_pfail->getReasonStr( reasonCode, reasonStr );
- delete p_pfail;
- delete p_l;
- printf( "Reason: %s\n", reasonStr );
- goto cleanup;
- } break;
- case 0x07: // PlayOK
- {
- printf( "Play OK!\n" );
- p_pok = new L2Login_PlayOK( p_l->getBytesPtr(), p_l->getPacketSize() );
- p_pok->getPacketType();
- p_pok->read_sessionKey2( ls_sessionKey2 );
- delete p_pok;
- } break;
- default:
- printf( "Unknows response to RequestServerLogin: %02X\n", p_l->getPacketType() );
- break;
- }
- delete p_l;
- printf( "SessionKey2: " );
- for( i=0; i<8; i++ ) printf( "%02X ", ls_sessionKey2[i] );
- printf( "\n" );
- // new we got all info to connect to game server:
- // server id, ip, port, session keys, account name
- // we can close login server connection and then connect to game server
- for( i=0; i<gsCount; i++ )
- {
- if( gsi[i].gsID == (unsigned char)choose_gsID )
- {
- printf( "You choose to play on gs #%d ID %d\n", i, choose_gsID );
- printf( "Connect to address: %d.%d.%d.%d port %d\n",
- (int)gsi[i].gsIP[0], (int)gsi[i].gsIP[1],
- (int)gsi[i].gsIP[2], (int)gsi[i].gsIP[3],
- (int)gsi[i].gsPort );
- break;
- }
- }
- cleanup:
- delete p_Init;
- free( netbuffer );
- L2PNet_shutdown( s );
- L2PNet_closesocket( s );
- }
- void ProcessServerState( char *login )
- {
- pGameSocket = L2PNet_TCPsocket_create( true ); // create async TCP socket
- if( pGameSocket == INVALID_SOCKET )
- {
- error_handler( "socket creation" );
- return;
- }
- printf( "Socket created to Game Server...\n" );
- // start connecting
- L2PNet_connect( pGameSocket, "90.227.223.129", 7777 );
- // network vars
- int readyRead, readyWrite;
- recvBytes = L2PNet_select( pGameSocket, L2PNET_SELECT_WRITE, 1000, &readyRead, &readyWrite );
- if( recvBytes == 0 )
- {
- error_handler( "Connect failed!" );
- return;
- }
- printf( "Connected to Game Server.\n" );
- // network receive bufer
- GameNetBuffer = (unsigned char *)malloc( 20*1024 ); // 20 kb ok?
- // packets
- L2Game_ProtocolVersion *p_game_pv = NULL;
- L2Game_AuthLogin *p_game_al = NULL;
- // send ProtocolVersion
- p_game_pv = new L2Game_ProtocolVersion();
- p_game_pv->createDefaultKamael();
- recvBytes = L2PacketSend( pGameSocket, p_game_pv, 5000, &GameSentLen );
- delete p_game_pv;
- if( recvBytes <= 0 )
- {
- error_handler( "Send L2Game ProtocolVersion failed!" );
- goto cleanup;
- }
- printf( "Sent %u bytes: L2Game ProtocolVersion\n", GameSentLen );
- //Get Game Key
- recvBytes = L2PacketReceive_buffer( pGameSocket, 5000, &GameRcvdLen, GameNetBuffer );
- p_game_key = new L2Game_KeyPacket( GameNetBuffer, GameRcvdLen );
- p_game_key->parse( L2_VERSION_T1 );
- delete p_game_key;
- if( recvBytes <= 0 )
- {
- error_handler( "Request L2Game KeyPacket failed!" );
- goto cleanup;
- }
- printf( "Receive %u bytes: L2Game KeyPacket\n", GameRcvdLen );
- p_game_al = new L2Game_AuthLogin();
- p_game_al->create( login, ls_sessionKey1, ls_sessionKey2 );
- recvBytes = L2PacketSend( pGameSocket, p_game_al, 5000, &GameSentLen );
- delete p_game_al;
- if( recvBytes <= 0 )
- {
- error_handler( "Send L2Game AuthLogin failed!" );
- goto cleanup;
- }
- printf( "Sent %u bytes: L2Game AuthLogin\n", GameSentLen );
- cleanup:
- printf( "Finish" );
- // free( GameNetBuffer );
- // L2PNet_shutdown( pGameSocket );
- // L2PNet_closesocket( pGameSocket );
- };
- void ProcessGamePackets()
- {
- recvBytes = L2PNet_select( pGameSocket, L2PNET_SELECT_READ, timerResolutionMsec, &readyRead, &readyWrite );
- DWORD curTick = GetTickCount();
- if( curTick - lastWorldTickTime >= (unsigned)timerResolutionMsec )
- {
- //printf("Tick: process world tick\n" );
- lastWorldTickTime = curTick;
- }
- // select result
- if( recvBytes == -1 ) return;
- if( L2PacketReceive_buffer( pGameSocket, timerResolutionMsec, &GameRcvdLen, GameNetBuffer ) > 0 )
- {
- unsigned int opCode = (unsigned int)GameNetBuffer[ 2 ];
- if( opCode == 0x18 ) return; //Remove info packet.
- printf( "OpCode: 0x%02x\n", opCode );
- printf( "Receive %u bytes\n", GameRcvdLen );
- L2GamePacket *pGamePacket = new L2GamePacket( GameNetBuffer, GameRcvdLen );
- switch( opCode )
- {
- case 0x09:
- {
- printf( "Character List:\n\n" );
- // vars
- unsigned int nCharsInCharSelection = 0;
- unsigned int nServerMaxChars = 0;
- L2Game_CharSelectionInfo *pCharSel = new L2Game_CharSelectionInfo( GameNetBuffer, GameRcvdLen );
- // parse CharSelectionInfo
- pCharSel->read_nChars( &nCharsInCharSelection );
- pCharSel->read_server_maxChars( &nServerMaxChars );
- L2Game_CharSelectionInfoBlock csb_chars[ 10 ];
- memset( csb_chars, 0, sizeof(csb_chars) );
- printf( "Char sel: %d chars (max %d)\n", nCharsInCharSelection, nServerMaxChars );
- for( int i = 0; i < (int)nCharsInCharSelection; i++ )
- {
- pCharSel->read_next_charSelectInfoBlock( L2_VERSION_T1, &csb_chars[i] );
- printf( "#Slot: ( %i ) - Name: %S, Level: %i\n", i, csb_chars[ i ].charName,
- csb_chars[ i ].level );
- //ToDo: Add players to GUI List.
- }
- char CharSlot[10];
- printf( "SelectChar: " );
- scanf( "%s", CharSlot );
- int SlotID = atoi( CharSlot );
- printf( "You selected Character Slot %i\n", SlotID );
- //ToDo: Select players from GUI List.
- L2Game_CharacterSelect *pCharSlot = new L2Game_CharacterSelect();
- pCharSlot->create( (unsigned int)SlotID );
- recvBytes = L2PacketSend( pGameSocket, pCharSlot, 5000, &GameSentLen );
- delete pCharSlot;
- if( recvBytes <= 0 )
- {
- error_handler( "Send L2Ganetwome CharacterSelect failed!" );
- break;
- }
- printf( "Sent %u bytes: L2Game CharacterSelect\n", GameSentLen );
- break;
- }
- case 0x0B:
- {
- printf( "Character Selected!\n" );
- // RequestManorList
- GameNetBuffer[0] = 5; GameNetBuffer[1] = 0;
- GameNetBuffer[2] = 0xD0; GameNetBuffer[3] = 0x01; GameNetBuffer[4] = 0x00;
- recvBytes = L2PacketSend2( GameNetBuffer, pGameSocket, 5000, &GameSentLen );
- if( recvBytes <= 0 )
- {
- error_handler( "Send RequestManorList failed!" );
- break;
- }
- printf( "Sent %u bytes: RequestManorList\n", GameSentLen );
- // RequestKeyMapping
- GameNetBuffer[0] = 5; GameNetBuffer[1] = 0;
- GameNetBuffer[2] = 0xD0; GameNetBuffer[3] = 0x21; GameNetBuffer[4] = 0x00;
- recvBytes = L2PacketSend2( GameNetBuffer, pGameSocket, 5000, &GameSentLen );
- if( recvBytes <= 0 )
- {
- error_handler( "Send RequestKeyMapping failed!" );
- break;
- }
- printf( "Sent %u bytes: RequestKeyMapping\n", GameSentLen );
- char EnterGame[10];
- printf( "EnterGame: yes/no : " );
- scanf( "%s", EnterGame );
- if( !strcmp( EnterGame, "yes" ) )
- {
- printf( "Enter Game!\n" );
- // Enter world packet ( Make the char enter the world )
- L2Game_EnterWorld *ew = new L2Game_EnterWorld();
- ew->create( L2_VERSION_T1 );
- recvBytes = L2PacketSend( pGameSocket, ew, 5000, &GameSentLen );
- delete ew;
- if( recvBytes <= 0 )
- {
- error_handler( "Send L2Ganetwome L2Game EnterWorld failed!" );
- break;
- }
- printf( "Sent %u bytes: L2Game L2Game EnterWorld\n", GameSentLen );
- }
- break;
- }
- case 0x62: // System Messages
- {
- L2Game_SystemMessage *pSysMsg = new L2Game_SystemMessage();
- pSysMsg->parse_SystemMessage( pGamePacket );
- delete pSysMsg;
- break;
- }
- case 0x31: // Char Info ( This is information from other players and NPC's / Mobs )
- {
- L2Player *pUser = new L2Player();
- pUser->parse_CharInfo( pGamePacket, L2_VERSION_T1 );
- //objectID is unique in game world, You can use pUser->objectID to store players in some sort of map.
- printf( "::GamePacket:: -> CharInfo->: %S -> X: %i, Y: %i, Z: %i\n", pUser->charName, pUser->x, pUser->y, pUser->z );
- //printf( "::GamePacket:: -> CharInfo->ObjID( %i ): %S -> X: %i, Y: %i, Z: %i\n", pUser->objectID, pUser->charName, pUser->x, pUser->y, pUser->z );
- // Add object to world list.
- mGameWorldObjects[ pUser->objectID ] = pUser;
- L2GamePacket *gp=new L2GamePacket();
- gp->writeChar(0x0f);
- /*gp->writeDouble(-73571.0f);
- gp->writeDouble(255868.0f);
- gp->writeDouble(-3120.0f);
- gp->writeDouble(pUser->x);
- gp->writeDouble(pUser->y);
- gp->writeDouble(pUser->z);*/
- gp->writeInt(-73571);
- gp->writeInt(255868);
- gp->writeInt(-3120);
- gp->writeInt(pUser->x);
- gp->writeInt(pUser->y);
- gp->writeInt(pUser->z);
- break;
- }
- case 0x32: // User Info ( This is your information )
- {
- L2Player *pUser = new L2Player();
- pUser->parse_UserInfo( pGamePacket, L2_VERSION_T1 );
- //objectID is unique in game world, You can use pUser->objectID to store players in some sort of map.
- printf( "::GamePacket:: -> UserInfo->: %S -> X: %i, Y: %i, Z: %i\n", pUser->charName, pUser->x, pUser->y, pUser->z );
- //printf( "::GamePacket:: -> CharInfo->ObjID( %i ): %S -> X: %i, Y: %i, Z: %i\n", pUser->objectID, pUser->charName, pUser->x, pUser->y, pUser->z );
- // Add object to world list.
- mGameWorldObjects[ pUser->objectID ] = pUser;
- break;
- }
- case 0x08: // Remove object from world.
- {
- pGamePacket->getPacketType();
- unsigned int pObjID = pGamePacket->readUInt();
- mGameWorldObjects.erase( mGameWorldObjects.find( pObjID ) );
- printf( "::GamePacket:: -> Remove Object ( %i )\n", pObjID );
- break;
- }
- case 0xD9:
- {
- printf( "::GamePacket:: -> Ping Packet\n" );
- break;
- }
- }
- delete pGamePacket;
- pGamePacket = NULL;
- }
- }
- int main()
- {
- L2PNet_InitDefault(); // library init?
- char l2login[32];
- char l2pass[32];
- printf( "Login: " );
- scanf( "%s", l2login );
- printf( "Pass: " );
- scanf( "%s", l2pass );
- ProcessLoginState( l2login, l2pass );
- printf( "\n\nGame Server Section!\n" );
- ProcessServerState( l2login );
- lastWorldTickTime = GetTickCount();
- // Process Game Packets
- while( TRUE ) ProcessGamePackets();
- getch();
- mGameWorldObjects.clear();
- L2PNet_shutdown( pGameSocket );
- L2PNet_closesocket( pGameSocket );
- return 0;
- }
- void error_handler( const char *msg, bool is_fatal )
- {
- if( msg ) perror( msg ); else perror( "ERROR: " );
- if( is_fatal ) exit( 1 );
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement