📄 charserver.cpp.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 "charserver.h"
// Constructor
CCharServer::CCharServer( string fn )
{
LoadConfigurations( (char*)fn.c_str() );
GServer = this;
}
// Deconstructor
CCharServer::~CCharServer( )
{
}
// Return a new clientsocket structure
CCharClient* CCharServer::CreateClientSocket( )
{
CCharClient* thisclient = new (nothrow) CCharClient( );
return thisclient;
}
//LMA BEGIN
//20070623, 224500
bool CCharServer::Ping()
{
//Bogus request (checking if quest 1 exists).
if(DB->QStore( "SELECT id FROM quest_data WHERE id='1'")==NULL)
{
Log( MSG_INFO, "MySQL Ping Time Error on port %u",DB->Port);
}
else
{
Log( MSG_INFO, "MySQL Ping Time Ok on port %u",DB->Port);
DB->QFree( );
}
return true;
}
//LMA END
// When Server is ready
bool CCharServer::OnServerReady( )
{
DB->QExecute( "DELETE FROM channels WHERE id=%u and type=%i", Config.ServerID, Config.ServerType );
if(!DB->QExecute("INSERT INTO channels (id,type,name,host,port,lanip,lansubmask,connected,maxconnections,owner) VALUES (%i,%i,'%s','%s',%i,'%s','%s',0,%i,%i)",
Config.ServerID, Config.ServerType, Config.ServerName, Config.CharIP, Config.CharPort, Config.LanIP, Config.LanSubnet, Config.MaxConnections, Config.ParentID))
{
Log(MSG_WARNING, "Error accessing to database, the other server will not connect to CharServer" );
}
MYSQL_RES *result;
MYSQL_ROW row;
bool pflag = false;
//Get IP and Port from Login
result = DB->QStore( "SELECT host,port,lanip FROM channels WHERE id=%u and type=0", Config.ParentID );
if(result==NULL) return false;
if (mysql_num_rows( result ) == 1)
{
row = mysql_fetch_row( result );
switch(Config.Connection)
{
case 0://wanip
Config.LoginIP = row[0];
break;
case 1://lanip
Config.LoginIP = row[2];
break;
default://localhost
Config.LoginIP = "127.0.0.1";
break;
}
Config.LoginPort = atoi(row[1]);
pflag = true;
}
DB->QFree( );
if(pflag)
{
Log( MSG_INFO, "Initialized loginserver connection" );
// Connect To LoginServer
lsock = socket( AF_INET, SOCK_STREAM, 0 );
if (lsock == INVALID_SOCKET)
{
Log( MSG_WARNING, "Could not access login server" );
}
struct sockaddr_in ain;
ain.sin_family = AF_INET;
ain.sin_addr.s_addr = inet_addr( Config.LoginIP );
ain.sin_port = htons( Config.LoginPort );
memset(&(ain.sin_zero), '\0', 8);
if ( connect( lsock, (SOCKADDR*) &ain, sizeof(ain) ) == SOCKET_ERROR )
Log( MSG_WARNING, "Could not access login server" );
BEGINPACKET( pak, 0x500 );
ADDDWORD ( pak, Config.LoginPass );
ADDDWORD ( pak, Config.ServerID );
ADDWORD ( pak, Config.CharPort );
cryptPacket( (char*)&pak, NULL );
send( lsock, (char*)&pak, pak.Size, 0 );
}
// Load all our clans
result = DB->QStore("SELECT id,logo,back,name,cp,grade,slogan,news FROM list_clan");
if(result==NULL) return false;
while(row = mysql_fetch_row(result))
{
CClans* thisclan = new CClans;
assert(thisclan);
thisclan->id = atoi(row[0]);
thisclan->logo = atoi(row[1]);
thisclan->back = atoi(row[2]);
strcpy(thisclan->name,row[3]);
thisclan->cp = atoi(row[4]);
thisclan->grade = atoi(row[5]);
strcpy(thisclan->slogan,row[6]);
strcpy(thisclan->news,row[7]);
ClanList.push_back( thisclan );
}
DB->QFree( );
// Load Clans
for(UINT i=0;i<ClanList.size( );i++)
{
CClans* Clan = ClanList.at( i );
result = DB->QStore("SELECT id,char_name,clan_rank FROM characters WHERE clanid=%i order by clan_rank",Clan->id);
if(result==NULL) return false;
while(row = mysql_fetch_row(result))
{
CClanMembers* newmember = new CClanMembers;
assert(newmember);
newmember->id = atoi(row[0]);
strcpy(newmember->name,row[1]);
newmember->clan_rank = atoi(row[2]);
Clan->ClanMembers.push_back( newmember );
}
DB->QFree( );
}
Log( MSG_INFO, "Clans Information Loaded" );
return true;
}
// When a a client is disconnected
void CCharServer::OnClientDisconnect( CClientSocket* thisclient )
{
CCharClient* thisclientwc = (CCharClient*)thisclient;
if(!thisclientwc->logout)
{
// Send logout message to friends
for(UINT i=0;i<thisclientwc->FriendList.size( );i++)
{
CFriendList* Friend = thisclientwc->FriendList.at( i );;
CCharClient* otherclient = GetClientByID( Friend->id );
if(otherclient!=NULL)
{
ChangeMessengerStatus ( thisclientwc, otherclient, 0x08);
}
}
//set logout messga to clan
CClans* thisclan = GetClanByID(thisclientwc->clanid);
if(thisclan==NULL)
return;
for(UINT i=0;i<thisclan->ClanMembers.size( );i++)
{
CClanMembers* ClanMember = thisclan->ClanMembers.at( i );
CCharClient* otherclient = GetClientByID( ClanMember->id );
if(otherclient!=NULL)
ChangeClanStatus (thisclientwc, otherclient, 0xff);
}
}
}
// Deletes an old clientsocket structure
void CCharServer::DeleteClientSocket( CClientSocket* thisclient )
{
CCharClient* client = (CCharClient*) thisclient;
if(client->accesslevel==0xffff) //is a channel
{
for(UINT i=0;i<ChannelList.size();i++)
{
CChanels* thischannel = ChannelList.at( i );
if(client->userid = thischannel->id)
{
Log( MSG_INFO, "Channel #%i disconnected", thischannel->id );
DB->QExecute( "DELETE FROM channels WHERE id=%i and type=2", thischannel->id );
ChannelList.erase( ChannelList.begin()+i );
delete thischannel;
break;
}
}
}
else
{
Log( MSG_INFO, "User disconnected" );
}
delete (CCharClient*)thisclient;
}
// Load Server configuration
void CCharServer::LoadConfigurations( char* file )
{
//Database
Config.SQLServer.pcServer = ConfigGetString ( file, "mysql_host", "localhost" );
Config.SQLServer.pcDatabase = ConfigGetString ( file, "mysql_database", "roseon_beta" );
Config.SQLServer.pcUserName = ConfigGetString ( file, "mysql_user", "root" );
Config.SQLServer.pcPassword = ConfigGetString ( file, "mysql_pass", "" );
Config.SQLServer.pcPort = ConfigGetInt ( file, "mysql_port", 3306 );
//Server
Config.ServerID = ConfigGetInt ( file, "serverid", 1 );
Config.ServerType = ConfigGetInt ( file, "servertype", 1 );
Config.CharIP = ConfigGetString ( file, "serverip", "127.0.0.1" );
Config.CharPort = ConfigGetInt ( file, "serverport", 29100 );
Config.ParentID = ConfigGetInt ( file, "parentid", 0 );
Config.ServerName = ConfigGetString ( file, "servername", "Server" );
Config.Connection = ConfigGetInt ( file, "connection", 0 );
Config.LanIP = ConfigGetString ( file, "lanip", "192.168.0.1" );
Config.LanSubnet = ConfigGetString ( file, "lansubmask", "192.168.0" );
//Char
Config.usethreads = ConfigGetInt ( file, "usethreads", 0 )==0?false:true;
Config.DeleteTime = ConfigGetInt ( file, "deletetime", 36000 );
Config.MinimumAccessLevel = ConfigGetInt ( file, "accesslevel", 100 );
//Password
Config.LoginPass = ConfigGetInt ( file, "loginpass", 123456 );
Config.CharPass = ConfigGetInt ( file, "charpass", 123456 );
Config.WorldPass = ConfigGetInt ( file, "worldpass", 123456 );
}
// Incoming packet
bool CCharServer::OnReceivePacket( CClientSocket* thisclient, CPacket *P )
{
//Log( MSG_WARNING, "(SID:%i) Received packet. Command:%04x Size:%04x", thisclient->sock, P->Command, P->Size );
switch( P->Command )
{
case 0x0500: return pakWSReady ( (CCharClient*)thisclient, P );
case 0x0501: return pakLoginConnected ( (CCharClient*)thisclient, P );
case 0x0502: return pakLoginDSClient ( (CCharClient*)thisclient, P );
case 0x0505: return pakWSCharSelect ( (CCharClient*)thisclient, P );
case 0x070b: return pakDoIdentify ( (CCharClient*)thisclient, P );
case 0x0712: return pakGetCharacters ( (CCharClient*)thisclient, P );
case 0x0713: return pakCreateChar ( (CCharClient*)thisclient, P );
case 0x0714: return pakDeleteChar ( (CCharClient*)thisclient, P );
case 0x0715: return pakRequestWorld ( (CCharClient*)thisclient, P );
case 0x0787: return pakClanChat ( (CCharClient*)thisclient, P );
case 0x07e0: return pakClanManager ( (CCharClient*)thisclient, P );
case 0x07e1: return pakMessengerManager ( (CCharClient*)thisclient, P );
case 0x07e2: return pakMessengerChat ( (CCharClient*)thisclient, P );
case 0x07e3: return pakChatrooms ( (CCharClient*)thisclient, P );
case 0x07e5: return pak7e5 ( (CCharClient*)thisclient, P );
case 0x07e6: return pakUploadCM ( (CCharClient*)thisclient, P );
case 0x07e7: return pakDownloadCM ( (CCharClient*)thisclient, P );
case 0x07e8: return pakClanIconTime ( (CCharClient*)thisclient, P );
case 0x079e: return pakUpdateLevel ( (CCharClient*)thisclient, P );
default:
Log( MSG_WARNING, "(SID:%i) Received unknown packet. Command:%04x Size:%04x", thisclient->sock, P->Command, P->Size );
break;
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -