Removes now-unreachable #ifdef _WIN32 branches across Common/ and the three server binaries (all builds are Linux-only), deletes the entirely unused SEH exception-handling shim and an orphaned vendored MySQL client header. Enables LTO and -march=x86-64-v2 in Release builds for a small free perf win. Also seeds a default GM account (gmadmin/changeme) via database sql files/gm_account.sql so a fresh deploy has something to log into the web admin panel with, switches the MariaDB data directory from a Docker named volume to a host bind mount for visibility/backup, and expands the README with a fuller Docker deployment walkthrough. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
236 lines
8.0 KiB
C++
236 lines
8.0 KiB
C++
/*
|
|
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.
|
|
|
|
developed 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 )
|
|
{
|
|
try
|
|
{
|
|
thisclient->CryptStatus.CurAddValue = rand( ) | (rand( )<<16);
|
|
STARTPACKET( pak, 0x7FF, 11 );
|
|
SETBYTE ( pak, 0x00, 0x02 );
|
|
SETDWORD ( pak, 0x01, thisclient->CryptStatus.CurAddValue );
|
|
thisclient->SendPacket( &pak );
|
|
return true;
|
|
}
|
|
catch(...)
|
|
{
|
|
Log(MSG_ERROR, "pakEncryptionRequest");
|
|
}
|
|
}
|
|
|
|
// Packet when user login (chck user and pass)
|
|
bool CLoginServer::pakUserLogin( CLoginClient* thisclient, CPacket* P )
|
|
{
|
|
Log(MSG_DEBUG,"User Login request received");
|
|
try
|
|
{
|
|
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 FROM accounts WHERE username='%s'", thisclient->username.c_str() );
|
|
if(result == NULL)
|
|
{
|
|
Log(MSG_WARNING,"DB Query returned a NULL result");
|
|
return false;
|
|
}
|
|
if( mysql_num_rows( result ) == 1 )
|
|
{
|
|
row = mysql_fetch_row(result);
|
|
int res = strcasecmp( row[1], thisclient->password.c_str() );
|
|
if ( res == 0 )
|
|
{
|
|
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( );
|
|
DB->QExecute( "update accounts set login_count=1 WHERE username='%s'", thisclient->username.c_str());
|
|
return true;
|
|
}
|
|
thisclient->accesslevel = atoi(row[2]);
|
|
if( thisclient->accesslevel < Config.MinimumAccessLevel )
|
|
{ //The server are under inspection
|
|
Log(MSG_WARNING,"User accesslevel %i is lower than minimum %i",thisclient->accesslevel,Config.MinimumAccessLevel);
|
|
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!
|
|
Log(MSG_WARNING,"User %s passed to charserver",thisclient->username.c_str());
|
|
ADDDWORD( pak, 0x0c000000 );//ADDDWORD( pak, 0x6f000000 );
|
|
ADDBYTE( pak, 0 );
|
|
result = DB->QStore( "SELECT id,name FROM channels WHERE owner=0" );
|
|
if(result==NULL) return false;
|
|
while( row = mysql_fetch_row(result) )
|
|
{
|
|
if (Config.Testserver){ADDBYTE( pak, 63 + atoi( row[0] ) );}
|
|
else{
|
|
ADDBYTE( pak, 48 + atoi( row[0] ) );}
|
|
ADDSTRING( pak, row[1] );
|
|
ADDBYTE( pak, 0 );
|
|
ADDDWORD(pak, atoi( row[0] ) );
|
|
}
|
|
DB->QFree( );
|
|
}
|
|
else
|
|
{
|
|
//BANNED
|
|
Log(MSG_WARNING,"User %s banned",thisclient->username.c_str());
|
|
ADDBYTE( pak, 5 );
|
|
ADDDWORD( pak, 0 );
|
|
DB->QFree( );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//BAD PASSWORD
|
|
Log(MSG_WARNING,"User %s attempted to log in with invalid password",thisclient->username.c_str());
|
|
ADDBYTE( pak, 3 );
|
|
ADDDWORD( pak, 0 );
|
|
DB->QFree( );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DB->QFree( );
|
|
if(Config.CreateLoginAccount)
|
|
{
|
|
if(!DB->QExecute("INSERT into accounts (username,password,accesslevel,lastlogin,logtime) values ('%s','%s',100,'',0)",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;
|
|
}
|
|
catch(...)
|
|
{
|
|
Log(MSG_ERROR, "Error in pakUserLogin");
|
|
}
|
|
|
|
}
|
|
|
|
// Send server list
|
|
bool CLoginServer::pakGetServers( CLoginClient* thisclient, CPacket* P )
|
|
{
|
|
try
|
|
{
|
|
if( !thisclient->isLoggedIn ) return false;
|
|
MYSQL_ROW row;
|
|
unsigned servernum = GETDWORD( (*P), 0 );
|
|
MYSQL_RES *result = DB->QStore( "SELECT id,name,connected,maxconnections FROM channels WHERE owner=%i", servernum );
|
|
if(result==NULL) return false;
|
|
BEGINPACKET( pak, 0x704 );
|
|
ADDDWORD ( pak, servernum );
|
|
ADDBYTE ( pak, (BYTE)mysql_num_rows( result ) ); //old function
|
|
while(row = mysql_fetch_row(result))
|
|
{
|
|
UINT connected = atoi(row[2]);
|
|
UINT maxconnections = atoi(row[3]);
|
|
BYTE id = atoi( row[0] );
|
|
BYTE status = ((100 * connected) / (maxconnections == 0 ? 1 : maxconnections)) & 0xff;
|
|
|
|
ADDWORD( pak, id );
|
|
ADDBYTE( pak, 0 );
|
|
ADDWORD( pak, status );
|
|
ADDSTRING( pak, row[1] ); // Name
|
|
ADDBYTE( pak, 0 );
|
|
}
|
|
DB->QFree( );
|
|
thisclient->SendPacket ( &pak );
|
|
return true;
|
|
}
|
|
catch(...)
|
|
{
|
|
Log(MSG_ERROR, "Error in pakGetServers");
|
|
}
|
|
}
|
|
|
|
// Send server IP
|
|
bool CLoginServer::pakGetIP( CLoginClient* thisclient, CPacket* P )
|
|
{
|
|
try
|
|
{
|
|
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,connected,maxconnections FROM channels WHERE id=%i", 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[2]);
|
|
UINT maxconnections = atoi(row[3]);
|
|
|
|
Log(MSG_DEBUG, "IP from database. Sent to client: %s ",row[0] );
|
|
|
|
ADDBYTE( pak, 0 ); //atoi(row[0]) ); // What is status? It's NULL in tables - Drakia
|
|
ADDDWORD( pak, thisclient->userid );
|
|
ADDDWORD( pak, 0x87654321 );
|
|
ADDSTRING( pak, row[0] );
|
|
ADDBYTE( pak, 0 );
|
|
ADDWORD( pak, atoi(row[1]) );
|
|
DB->QFree( );
|
|
thisclient->SendPacket ( &pak );
|
|
return true;
|
|
}
|
|
catch(...)
|
|
{
|
|
Log(MSG_ERROR, "Error in pakGetIP");
|
|
}
|
|
}
|
|
|