⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loginpackets.cpp.svn-base

📁 ROSE的源代码。了解的自己研究,编译通过
💻 SVN-BASE
字号:
/*
    Rose Online Server Emulator
    Copyright (C) 2006,2007 OSRose Team http://osroseon.to.md
    
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

    depeloped with Main erose/hrose source server + some change from the original eich source        
*/
#include "loginserver.h"

// Send Server encryption
bool CLoginServer::pakEncryptionRequest( CLoginClient* thisclient, CPacket* P )
{
	BEGINPACKET( pak, 0x7ff );
	ADDWORD    ( pak, 0xaf02 );
	ADDWORD    ( pak, 0xbd46 );
	ADDWORD    ( pak, 0x0009 );
	ADDWORD    ( pak, 0x0012 );
	ADDBYTE    ( pak, 0x0000 );
	ADDDWORD   ( pak, 0xcdcdcdcd );
	ADDDWORD   ( pak, 0xcdcdcdcd );
	ADDDWORD   ( pak, 0xcdcdcdcd );
	ADDDWORD   ( pak, 0xcdcdcdcd );
	ADDWORD    ( pak, 0xcdcd );
	ADDBYTE    ( pak, 0xd3 );	    
	thisclient->SendPacket( &pak );	
    return true;
}

// Packet when user login (chck user and pass and active)
bool CLoginServer::pakUserLogin( CLoginClient* thisclient, CPacket* P )
{
    if ( thisclient->isLoggedIn ) return false;
    MYSQL_ROW row;
    thisclient->username.assign( (const char*)&P->Buffer, 32, (P->Size-6-32)>16?16:P->Size-6-32 );
    thisclient->password.assign( (const char*)&P->Buffer, 0, 32 );
    BEGINPACKET( pak, 0x708 );
    MYSQL_RES *result = DB->QStore( "SELECT id,password,accesslevel,online,active FROM accounts WHERE username='%s'", thisclient->username.c_str() );
    if(result==NULL) return false;
    if( mysql_num_rows( result ) == 1 ) 
    {
        row = mysql_fetch_row(result);
        int res = 0;
        #ifdef _WIN32
            res = _stricmp( row[1], thisclient->password.c_str() );
        #else
            res = strcasecmp( row[1], thisclient->password.c_str() );
        #endif        
        if ( res == 0 ) 
        {
            if(atoi(row[4])==1)
            {
                // Activation Fix By Rifke 
                Log( MSG_INFO, "Success login '%s' : Account verfified.", thisclient->username.c_str() );
                if(atoi(row[3])==1)
                {   // characters is already logged
                    Log(MSG_WARNING, "Account %s try re-login", thisclient->username.c_str() );
                    ADDBYTE( pak, 4 );
                    ADDDWORD( pak, 0 );        
                    thisclient->SendPacket( &pak );
                    DB->QFree( );
                    if(!DB->QExecute( "update accounts set online=0 WHERE username='%s'", thisclient->username.c_str() ))
                      return false;
                       BEGINPACKET( pak2, 0x502 );
                       ADDBYTE    ( pak2, 1 );
                       ADDDWORD   ( pak2, atoi(row[0]) );
                      cryptPacket( (char*)&pak2, NULL );                  
                    for(UINT i=0;i<ServerList.size();i++)
                        send( ServerList.at(i)->sock , (char*)&pak2, pak2.Size, 0 ); 
                    return false;                
                }
                thisclient->accesslevel = atoi(row[2]);
                if( thisclient->accesslevel < Config.MinimumAccessLevel )
                { //The server are under inspection
                    ADDBYTE( pak, 0 );
                    ADDDWORD( pak, 0 );
                    thisclient->SendPacket( &pak );
                    DB->QFree( );
                    return true;
                }
                if ( thisclient->accesslevel > 0 ) 
                {
                    thisclient->userid = atoi(row[0]);
                    thisclient->isLoggedIn = true;
                    DB->QFree( );
                    //OK!                
                    ADDDWORD( pak, 0x0c000000 );
                    ADDBYTE( pak, 0 );
                    result = DB->QStore( "SELECT id,name FROM channels WHERE type=1" );
                    if(result==NULL) return false;
                    while( row = mysql_fetch_row(result) ) 
                    {
                        ADDBYTE( pak, 48 + atoi( row[0] ) );
                        ADDSTRING( pak, row[1] );
                        ADDBYTE( pak, 0 );
                        ADDBYTE(pak, atoi( row[0] ) );
                        ADDBYTE( pak, 0 );
                        ADDWORD( pak, 0 );
                    }
                    DB->QFree( );
                }else{
                    //BANNED
                    ADDBYTE( pak, 5 );
                    ADDDWORD( pak, 0 );
                    DB->QFree( );
                }
            }else{
                // Not activated
                Log( MSG_INFO, "Failed login attempt '%s' : Account not verified ", thisclient->username.c_str() );
                ADDBYTE( pak, 9 );
                ADDDWORD( pak, 0 );
                DB->QFree( );            
            }
        }else{
            //BAD PASSWORD
            ADDBYTE( pak, 3 );
            ADDDWORD( pak, 0 );
            DB->QFree( );
        }
    }
    else
    {
        DB->QFree( );
        if(Config.CreateLoginAccount)
        {
            if(!DB->QExecute("INSERT into accounts (username,password,accesslevel) values ('%s','%s',100)",thisclient->username.c_str(),thisclient->password.c_str()))                            
               return true;
            Log( MSG_INFO, "New Account created '%s'", thisclient->username.c_str() );       
        }
        //BAD USERNAME
        ADDBYTE( pak, 2 );
        ADDDWORD( pak, 0 );    
    }
/*
1 - general error   | 4 - your account is already logged 
6 - topup account   | 7 - cannot connect to server please try again
8 - server exceeded | 9 - account have not been verified
10 - login failed   | 11 - ip capacity is full
*/
    thisclient->SendPacket ( &pak );
    return true;
}

// Send server list
bool CLoginServer::pakGetServers( CLoginClient* thisclient, CPacket* P )
{
	if( !thisclient->isLoggedIn ) return false;	
	MYSQL_ROW row;
	DWORD servernum = GETDWORD( (*P), 0 );
	MYSQL_RES *result = DB->QStore( "SELECT id,name,connected,maxconnections FROM channels WHERE owner=%i and type=2", servernum );
	if(result==NULL) return false;
	BEGINPACKET( pak, 0x704 );
	ADDDWORD   ( pak, servernum );
	ADDBYTE    ( pak, (BYTE)mysql_num_rows( result ) );
	while(row = mysql_fetch_row(result)) 
    {
    	UINT connected = atoi(row[2]);
    	UINT maxconnections = atoi(row[3]);
    	BYTE id = atoi( row[0] );
    	string name = row[1];
    	BYTE status = (((100 * connected) / maxconnections==0?1:maxconnections) / 5) & 0xff;  
		ADDWORD( pak, id );
		ADDBYTE( pak, 0 );
		ADDWORD( pak, status );
		ADDSTRING( pak, name.c_str() );
		ADDBYTE( pak, 0 );
	}
	DB->QFree( );
	thisclient->SendPacket ( &pak );
    return true;
}

// Send server IP
bool CLoginServer::pakGetIP( CLoginClient* thisclient, CPacket* P )
{
	if (!thisclient->isLoggedIn) return false;
	;
	MYSQL_ROW row;
	DWORD servernum = GETDWORD( (*P), 0 );
	BYTE channelnum = GETBYTE( (*P), 4 );

	BEGINPACKET( pak, 0x70a );

	if(!DB->QExecute( "UPDATE accounts SET lastsvr=%i,lastip='%s' WHERE id=%i", channelnum, inet_ntoa( thisclient->clientinfo.sin_addr ), thisclient->userid))
	   return false;
	MYSQL_RES *result = DB->QStore( "SELECT host,port,lanip,lansubmask,connected,maxconnections FROM channels WHERE id=%i and type=1", servernum );
    if(result==NULL) return false;	
	if(mysql_num_rows(result)!=1)
	{
        Log(MSG_WARNING, "Player selected a invalid channel or channel offline" );
        DB->QFree( );
        return true;
    }
	row = mysql_fetch_row(result);
	UINT connected = atoi(row[4]);
	UINT maxconnections = atoi(row[5]);	
	ADDBYTE( pak, 0 );
	ADDDWORD( pak, thisclient->userid );
	ADDDWORD( pak, 0x87654321 );
	if(strcmp(thisclient->ClientSubNet,row[3])==0)//from lan
	{
        ADDSTRING( pak, row[2] );
       	Log(MSG_INFO, "Lan: %s choice channel #%i", thisclient->username.c_str(), channelnum);
    }
    else if(strcmp( thisclient->ClientSubNet ,"127.0.0")==0)//same computer
    {
        ADDSTRING( pak, "127.0.0.1" );
       	Log(MSG_INFO, "Server: %s choice channel #%i", thisclient->username.c_str(), channelnum);        
    }
    else
    {
        ADDSTRING( pak, row[0] );
       	Log(MSG_INFO, "Inet: %s choice channel #%i", thisclient->username.c_str(), channelnum);        
    }
	ADDBYTE( pak, 0 );
	ADDWORD( pak, atoi(row[1]) );	
	DB->QFree( );
	thisclient->SendPacket ( &pak );
    return true;
}

// Connect user to charserver
bool CLoginServer::pakConnectToChar( CLoginClient* thisclient, CPacket *P )
{
	if(thisclient->isLoggedIn) return true;
	if(GETDWORD((*P),0) != Config.LoginPass) 
    {
        Log( MSG_HACK, "Charserver Tried to connect loginserver with wrong password ");
        return true;
    }
    thisclient->userid = GETDWORD((*P), 4); //our serverid
    thisclient->accesslevel = 0xffff; //this will identify thisclient as server

    // add new server        
    CServers* newserver = new (nothrow) CServers( );    
    if(newserver==NULL)
        return false;
    newserver->id = GETDWORD((*P), 4);
    newserver->ip = inet_ntoa( thisclient->clientinfo.sin_addr );
    newserver->port = GETWORD((*P),8 );            
    Log( MSG_INFO, "Server #%i connected from ip %s", newserver->id, newserver->ip );
    
    // Connect to charserver
	newserver->sock = socket( AF_INET, SOCK_STREAM, 0 );
	if (newserver->sock == INVALID_SOCKET) 
    {
		Log( MSG_WARNING, "Could not access char server IP: %s , Port: %i", newserver->ip, newserver->port );
		delete newserver;
		return false;
	}
	struct sockaddr_in ain;
	ain.sin_family		= AF_INET;
   	ain.sin_addr.s_addr	= thisclient->clientinfo.sin_addr.s_addr;	
	ain.sin_port		= htons( newserver->port );
	if ( connect( newserver->sock , (SOCKADDR*) &ain, sizeof(ain) ) == SOCKET_ERROR) 
    {
		Log( MSG_WARNING, "Could not access char server IP: %s , Port: %i", newserver->ip , newserver->port );
		delete newserver;
		return false;
	}        	
    ServerList.push_back( newserver );
    // Identify packet
    thisclient->isLoggedIn = true;
    BEGINPACKET( pak, 0x501 );
    ADDDWORD   ( pak, Config.CharPass );
    cryptPacket( (char*)&pak, NULL );
    send( newserver->sock, (char*)&pak, pak.Size, 0 );   
    return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -