本文整理汇总了C++中IPList类的典型用法代码示例。如果您正苦于以下问题:C++ IPList类的具体用法?C++ IPList怎么用?C++ IPList使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了IPList类的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: copy
//*****************************************************************************
//
void IPList::copy( IPList &destination )
{
destination.clear( );
for ( ULONG ulIdx = 0; ulIdx < _ipVector.size( ); ulIdx++ )
destination.push_back( _ipVector[ulIdx] );
destination.sort( );
}
示例2: MASTERSERVER_RefreshIPList
//*****************************************************************************
//
bool MASTERSERVER_RefreshIPList( IPList &List, const char *FileName )
{
std::stringstream oldIPs;
for ( ULONG ulIdx = 0; ulIdx < List.size(); ulIdx++ )
oldIPs << List.getEntryAsString ( ulIdx, false ).c_str() << "-";
if ( !(List.clearAndLoadFromFile( FileName )) )
std::cerr << List.getErrorMessage();
std::stringstream newIPs;
for ( ULONG ulIdx = 0; ulIdx < List.size(); ulIdx++ )
newIPs << List.getEntryAsString ( ulIdx, false ).c_str() << "-";
return ( strcmp ( newIPs.str().c_str(), oldIPs.str().c_str() ) != 0 );
}
示例3: MASTERSERVER_InitializeBans
//*****************************************************************************
//
void MASTERSERVER_InitializeBans( void )
{
const bool BannedIPsChanged = MASTERSERVER_RefreshIPList ( g_BannedIPs, "banlist.txt" );
const bool BannedIPExemptionsChanged = MASTERSERVER_RefreshIPList ( g_BannedIPExemptions, "whitelist.txt" );
if ( !(g_MultiServerExceptions.clearAndLoadFromFile( "multiserver_whitelist.txt" )) )
std::cerr << g_MultiServerExceptions.getErrorMessage();
if ( !(g_BlockedIPs.clearAndLoadFromFile( "blocklist.txt" )) )
std::cerr << g_BlockedIPs.getErrorMessage();
std::cerr << "\nBan list: " << g_BannedIPs.size() << " banned IPs, " << g_BlockedIPs.size( ) << " blocked IPs, " << g_BannedIPExemptions.size() << " exemptions." << std::endl;
std::cerr << "Multi-server exceptions: " << g_MultiServerExceptions.size() << "." << std::endl;
if ( BannedIPsChanged || BannedIPExemptionsChanged )
{
// [BB] The ban list was changed, so no server has the latest list anymore.
for( std::set<SERVER_s, SERVERCompFunc>::iterator it = g_Servers.begin(); it != g_Servers.end(); ++it )
{
it->bHasLatestBanList = false;
it->bVerifiedLatestBanList = false;
}
std::cerr << "Ban lists were changed since last refresh\n";
}
/*
// [BB] Print all banned IPs, to make sure the IP list has been parsed successfully.
std::cerr << "Entries in blacklist:\n";
for ( ULONG ulIdx = 0; ulIdx < g_BannedIPs.size(); ulIdx++ )
std::cerr << g_BannedIPs.getEntryAsString(ulIdx).c_str();
// [BB] Print all exemption-IPs, to make sure the IP list has been parsed successfully.
std::cerr << "Entries in whitelist:\n";
for ( ULONG ulIdx = 0; ulIdx < g_BannedIPExemptions.size(); ulIdx++ )
std::cerr << g_BannedIPExemptions.getEntryAsString(ulIdx).c_str();
*/
}
示例4: addPermissions
void IAllocation::addPermissions(const IPList& ips)
{
for (auto it = ips.begin(); it != ips.end(); ++it) {
addPermission(*it);
}
}
示例5: MASTERSERVER_SendBanlistToServer
//*****************************************************************************
//
void MASTERSERVER_SendBanlistToServer( const SERVER_s &Server )
{
// [BB] If the server supports it, potentially split the ban list over multiple packets.
if ( Server.iServerRevision >= 2907 )
{
BanlistPacketSender sender ( Server );
sender.start();
// Write all the bans.
for ( unsigned int i = 0; i < g_BannedIPs.size( ); ++i )
sender.writeBanEntry ( g_BannedIPs.getEntryAsString( i, false, false, false ).c_str( ), MSB_BAN );
// Write all the exceptions.
for ( unsigned int i = 0; i < g_BannedIPExemptions.size( ); ++i )
sender.writeBanEntry ( g_BannedIPExemptions.getEntryAsString( i, false, false, false ).c_str( ), MSB_BANEXEMPTION );
sender.end();
}
else
{
NETWORK_ClearBuffer( &g_MessageBuffer );
NETWORK_WriteByte( &g_MessageBuffer.ByteStream, MASTER_SERVER_BANLIST );
// [BB] If the server sent us a verification string, send it along with the ban list.
// This allows the server to verify that the list actually was sent from our master
// (and is not just a packet with forged source IP).
if ( Server.MasterBanlistVerificationString.size() )
NETWORK_WriteString( &g_MessageBuffer.ByteStream, Server.MasterBanlistVerificationString.c_str() );
// Write all the bans.
NETWORK_WriteLong( &g_MessageBuffer.ByteStream, g_BannedIPs.size( ));
for ( ULONG i = 0; i < g_BannedIPs.size( ); i++ )
NETWORK_WriteString( &g_MessageBuffer.ByteStream, g_BannedIPs.getEntryAsString( i, false, false, false ).c_str( ));
// Write all the exceptions.
NETWORK_WriteLong( &g_MessageBuffer.ByteStream, g_BannedIPExemptions.size( ));
for ( ULONG i = 0; i < g_BannedIPExemptions.size( ); i++ )
NETWORK_WriteString( &g_MessageBuffer.ByteStream, g_BannedIPExemptions.getEntryAsString( i, false, false, false ).c_str( ));
NETWORK_LaunchPacket( &g_MessageBuffer, Server.Address );
}
Server.bHasLatestBanList = true;
Server.bVerifiedLatestBanList = false;
printf( "-> Banlist sent to %s.\n", NETWORK_AddressToString( Server.Address ));
}
示例6: getCharacterList
void ProtocolLogin::getCharacterList(uint32_t accountName, const std::string& password)
{
uint32_t serverIp = serverIPs[0].first;
for (uint32_t i = 0; i < serverIPs.size(); i++) {
if ((serverIPs[i].first & serverIPs[i].second) == (getConnection()->getIP() & serverIPs[i].second)) {
serverIp = serverIPs[i].first;
break;
}
}
Account account;
if (!IOLoginData::loginserverAuthentication(accountName, password, account)) {
disconnectClient("Account name or password is not correct.");
return;
}
auto output = OutputMessagePool::getOutputMessage();
//Update premium days
Game::updatePremium(account);
const std::string& motd = g_config.getString(ConfigManager::MOTD);
if (!motd.empty()) {
//Add MOTD
output->addByte(0x14);
std::ostringstream ss;
ss << g_game.getMotdNum() << "\n" << motd;
output->addString(ss.str());
}
//Add char list
output->addByte(0x64);
uint8_t size = std::min<size_t>(std::numeric_limits<uint8_t>::max(), account.characters.size());
output->addByte(size);
for (uint8_t i = 0; i < size; i++) {
output->addString(account.characters[i]);
output->addString(g_config.getString(ConfigManager::SERVER_NAME));
output->add<uint32_t>(serverIp);
output->add<uint16_t>(g_config.getNumber(ConfigManager::GAME_PORT));
}
//Add premium days
if (g_config.getBoolean(ConfigManager::FREE_PREMIUM)) {
output->add<uint16_t>(0xFFFF); //client displays free premium
} else {
output->add<uint16_t>(account.premiumDays);
}
send(output);
disconnect();
}
示例7: MASTERSERVER_ParseCommands
//*****************************************************************************
//
void MASTERSERVER_ParseCommands( BYTESTREAM_s *pByteStream )
{
long lCommand;
NETADDRESS_s AddressFrom;
AddressFrom = NETWORK_GetFromAddress( );
// [RC] If this IP is in our flood queue, ignore it completely.
if ( g_floodProtectionIPQueue.addressInQueue( AddressFrom ) || g_ShortFloodQueue.addressInQueue( AddressFrom ))
{
while ( NETWORK_ReadByte( pByteStream ) != -1 ) // [RC] Is this really necessary?
;
return;
}
// Is this IP banned? Send the user an explanation, and ignore the IP for 30 seconds.
if ( !g_BannedIPExemptions.isIPInList( AddressFrom ) && g_BannedIPs.isIPInList( AddressFrom ))
{
NETWORK_ClearBuffer( &g_MessageBuffer );
NETWORK_WriteLong( &g_MessageBuffer.ByteStream, MSC_IPISBANNED );
NETWORK_LaunchPacket( &g_MessageBuffer, AddressFrom );
printf( "* Received challenge from banned IP (%s). Ignoring for 10 seconds.\n", NETWORK_AddressToString( AddressFrom ));
g_queryIPQueue.addAddress( AddressFrom, g_lCurrentTime, &std::cerr );
return;
}
lCommand = NETWORK_ReadLong( pByteStream );
switch ( lCommand )
{
// Server is telling master server of its existence.
case SERVER_MASTER_CHALLENGE:
{
// Certain IPs can be blocked from just hosting.
if ( !g_BannedIPExemptions.isIPInList( AddressFrom ) && g_BlockedIPs.isIPInList( AddressFrom ))
{
NETWORK_ClearBuffer( &g_MessageBuffer );
NETWORK_WriteLong( &g_MessageBuffer.ByteStream, MSC_IPISBANNED );
NETWORK_LaunchPacket( &g_MessageBuffer, AddressFrom );
printf( "* Received server challenge from blocked IP (%s). Ignoring for 10 seconds.\n", NETWORK_AddressToString( AddressFrom ));
g_queryIPQueue.addAddress( AddressFrom, g_lCurrentTime, &std::cerr );
return;
}
SERVER_s newServer;
newServer.Address = AddressFrom;
// [BB] If no verification string was send, NETWORK_ReadString just returns an empty string.
// Thus, this is still compatible with older servers that don't send the string.
newServer.MasterBanlistVerificationString = NETWORK_ReadString( pByteStream );
// [BB] If no value was send, NETWORK_ReadByte just returns -1.
// Thus, this is still compatible with older servers that don't tell us whether they enforce our bans
// and gives them the benefit of the doubt, i.e. it assumes that they enforce our bans.
const int temp = NETWORK_ReadByte( pByteStream );
newServer.bEnforcesBanList = ( temp != 0 );
newServer.bNewFormatServer = ( temp != -1 );
newServer.iServerRevision = ( ( pByteStream->pbStreamEnd - pByteStream->pbStream ) >= 4 ) ? NETWORK_ReadLong( pByteStream ) : NETWORK_ReadShort( pByteStream );
std::set<SERVER_s, SERVERCompFunc>::iterator currentServer = g_Servers.find ( newServer );
// This is a new server; add it to the list.
if ( currentServer == g_Servers.end() )
{
unsigned int iNumOtherServers = 0;
// First count the number of servers from this IP.
for( std::set<SERVER_s, SERVERCompFunc>::const_iterator it = g_Servers.begin(); it != g_Servers.end(); ++it )
{
if ( NETWORK_CompareAddress( it->Address, AddressFrom, true ))
iNumOtherServers++;
}
if ( iNumOtherServers >= 10 && !g_MultiServerExceptions.isIPInList( AddressFrom ))
printf( "* More than 10 servers received from %s. Ignoring request...\n", NETWORK_AddressToString( AddressFrom ));
else
{
// [BB] 3021 is 98d, don't put those servers on the list.
if ( ( newServer.bNewFormatServer ) && ( newServer.iServerRevision != 3021 ) )
{
std::set<SERVER_s, SERVERCompFunc>::iterator currentUnverifiedServer = g_UnverifiedServers.find ( newServer );
// [BB] This is a new server, but we still need to verify it.
if ( currentUnverifiedServer == g_UnverifiedServers.end() )
{
srand ( time(NULL) );
newServer.ServerVerificationInt = rand() + rand() * rand() + rand() * rand() * rand();
// [BB] We don't send the ban list to unverified servers, so just pretent the server already has the list.
newServer.bHasLatestBanList = true;
MASTERSERVER_RequestServerVerification ( newServer );
MASTERSERVER_AddServer( newServer, g_UnverifiedServers );
}
}
else
{
printf( "* Received server challenge from old server (%s). Ignoring IP for 10 seconds.\n", NETWORK_AddressToString( newServer.Address ));
g_queryIPQueue.addAddress( newServer.Address, g_lCurrentTime, &std::cerr );
}
}
//.........这里部分代码省略.........
示例8: parseFirstPacket
bool ProtocolLogin::parseFirstPacket(NetworkMessage& msg)
{
if(
#ifndef _CONSOLE
!GUI::getInstance()->m_connections ||
#endif
g_game.getGameState() == GAME_STATE_SHUTDOWN)
{
getConnection()->closeConnection();
return false;
}
uint32_t clientip = getConnection()->getIP();
/*uint16_t clientos = */msg.GetU16();
uint16_t version = msg.GetU16();
msg.SkipBytes(12);
if(version <= 760)
{
disconnectClient(0x0A, "Only clients with protocol " CLIENT_VERSION_STR " allowed!");
return false;
}
if(!RSA_decrypt(msg))
{
getConnection()->closeConnection();
return false;
}
uint32_t key[4];
key[0] = msg.GetU32();
key[1] = msg.GetU32();
key[2] = msg.GetU32();
key[3] = msg.GetU32();
enableXTEAEncryption();
setXTEAKey(key);
std::string accountName = msg.GetString();
std::string password = msg.GetString();
if(accountName.empty())
{
if(g_config.getBoolean(ConfigManager::ACCOUNT_MANAGER))
{
accountName = "1";
password = "1";
}
else
{
disconnectClient(0x0A, "Invalid Account Name.");
return false;
}
}
if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX)
{
disconnectClient(0x0A, "Only clients with protocol " CLIENT_VERSION_STR " allowed!");
return false;
}
if(g_game.getGameState() == GAME_STATE_STARTUP)
{
disconnectClient(0x0A, "Gameworld is starting up. Please wait.");
return false;
}
if(g_game.getGameState() == GAME_STATE_MAINTAIN)
{
disconnectClient(0x0A, "Gameworld is under maintenance. Please re-connect in a while.");
return false;
}
if(g_bans.isIpDisabled(clientip))
{
disconnectClient(0x0A, "Too many connections attempts from this IP. Try again later.");
return false;
}
if(IOBan::getInstance()->isIpBanished(clientip))
{
disconnectClient(0x0A, "Your IP is banished!");
return false;
}
uint32_t serverip = serverIPs[0].first;
for(uint32_t i = 0; i < serverIPs.size(); i++)
{
if((serverIPs[i].first & serverIPs[i].second) == (clientip & serverIPs[i].second))
{
serverip = serverIPs[i].first;
break;
}
}
Account account = IOLoginData::getInstance()->loadAccount(accountName);
if(account.id == 0 || !passwordTest(password, account.password))
{
g_bans.addLoginAttempt(clientip, false);
disconnectClient(0x0A, "Account name or password is not correct.");
//.........这里部分代码省略.........
示例9: mainLoader
void mainLoader(int argc, char* argv[], ServiceManager* services)
{
//dispatcher thread
g_game.setGameState(GAME_STATE_STARTUP);
srand((unsigned int)OTSYS_TIME());
#ifdef _WIN32
SetConsoleTitle(STATUS_SERVER_NAME);
#endif
std::cout << STATUS_SERVER_NAME << " - Version " << STATUS_SERVER_VERSION << std::endl;
std::cout << "Compilied on " << __DATE__ << ' ' << __TIME__ << " for arch ";
#if defined(__amd64__) || defined(_M_X64)
std::cout << "x64" << std::endl;
#elif defined(__i386__) || defined(_M_IX86) || defined(_X86_)
std::cout << "x86" << std::endl;
#elif defined(__arm__)
std::cout << "ARM" << std::endl;
#elif defined(__mips__)
std::cout << "MIPS" << std::endl;
#else
std::cout << "unk" << std::endl;
#endif
std::cout << std::endl;
std::cout << "A server developed by " << STATUS_SERVER_DEVELOPERS << std::endl;
std::cout << "Visit our forum for updates, support, and resources: http://otland.net/." << std::endl;
std::cout << std::endl;
// read global config
std::cout << ">> Loading config" << std::endl;
if (!g_config.load()) {
startupErrorMessage("Unable to load config.lua!");
return;
}
#ifdef _WIN32
std::string defaultPriority = asLowerCaseString(g_config.getString(ConfigManager::DEFAULT_PRIORITY));
if (defaultPriority == "realtime") {
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
} else if (defaultPriority == "high") {
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
} else if (defaultPriority == "higher") {
SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
}
std::ostringstream mutexName;
mutexName << "forgottenserver_" << g_config.getNumber(ConfigManager::LOGIN_PORT);
CreateMutex(nullptr, FALSE, mutexName.str().c_str());
if (GetLastError() == ERROR_ALREADY_EXISTS) {
startupErrorMessage("Another instance of The Forgotten Server is already running with the same login port, please shut it down first or change ports for this one.");
return;
}
#endif
#ifdef __PROTOCOL_77__
//set RSA key
const char* p("14299623962416399520070177382898895550795403345466153217470516082934737582776038882967213386204600674145392845853859217990626450972452084065728686565928113");
const char* q("7630979195970404721891201847792002125535401292779123937207447574596692788513647179235335529307251350570728407373705564708871762033017096809910315212884101");
g_RSA.setKey(p, q);
#endif
std::cout << ">> Establishing database connection..." << std::flush;
Database* db = Database::getInstance();
if (!db->connect()) {
startupErrorMessage("Failed to connect to database.");
return;
}
std::cout << " MySQL " << db->getClientVersion() << std::endl;
// run database manager
std::cout << ">> Running database manager" << std::endl;
DatabaseManager* dbManager = DatabaseManager::getInstance();
if (!dbManager->isDatabaseSetup()) {
startupErrorMessage("The database you have specified in config.lua is empty, please import the schema to the database.");
return;
}
dbManager->updateDatabase();
dbManager->checkTriggers();
dbManager->checkEncryption();
if (g_config.getBoolean(ConfigManager::OPTIMIZE_DATABASE) && !dbManager->optimizeTables()) {
std::cout << "> No tables were optimized." << std::endl;
}
//load vocations
std::cout << ">> Loading vocations" << std::endl;
if (!g_vocations.loadFromXml()) {
startupErrorMessage("Unable to load vocations!");
return;
}
//load commands
std::cout << ">> Loading commands" << std::endl;
if (!g_commands.loadFromXml()) {
startupErrorMessage("Unable to load commands!");
//.........这里部分代码省略.........
示例10: parseFirstPacket
bool ProtocolLogin::parseFirstPacket(NetworkMessage& msg)
{
if(g_game.getGameState() == GAME_STATE_SHUTDOWN){
getConnection()->closeConnection();
return false;
}
uint32_t clientip = getConnection()->getIP();
/*uint16_t clientos =*/ msg.GetU16();
uint16_t version = msg.GetU16();
msg.SkipBytes(12);
if(version <= 760){
disconnectClient(0x0A, STRING_CLIENT_VERSION);
}
if(!RSA_decrypt(g_otservRSA, msg)){
getConnection()->closeConnection();
return false;
}
uint32_t key[4];
key[0] = msg.GetU32();
key[1] = msg.GetU32();
key[2] = msg.GetU32();
key[3] = msg.GetU32();
enableXTEAEncryption();
setXTEAKey(key);
uint32_t accnumber = msg.GetU32();
std::string password = msg.GetString();
if(!accnumber){
disconnectClient(0x0A, "You must enter your account number.");
return false;
}
if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX){
disconnectClient(0x0A, STRING_CLIENT_VERSION);
return false;
}
if(g_game.getGameState() == GAME_STATE_STARTUP){
disconnectClient(0x0A, "Gameworld is starting up. Please wait.");
return false;
}
if(g_bans.isIpDisabled(clientip)){
disconnectClient(0x0A, "Too many connections attempts from this IP. Try again later.");
return false;
}
if(g_bans.isIpBanished(clientip)){
disconnectClient(0x0A, "Your IP is banished!");
return false;
}
uint32_t serverip = serverIPs[0].first;
for(uint32_t i = 0; i < serverIPs.size(); i++){
if((serverIPs[i].first & serverIPs[i].second) == (clientip & serverIPs[i].second)){
serverip = serverIPs[i].first;
break;
}
}
Account account = IOAccount::instance()->loadAccount(accnumber);
if(!(accnumber != 0 && account.accnumber == accnumber &&
passwordTest(password, account.password))){
g_bans.addLoginAttempt(clientip, false);
disconnectClient(0x0A, "Please enter a valid account number and password.");
return false;
}
g_bans.addLoginAttempt(clientip, true);
OutputMessage* output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
//Add MOTD
std::stringstream motd;
output->AddByte(0x14);
motd << g_config.getNumber(ConfigManager::MOTD_NUM) << "\n";
motd << g_config.getString(ConfigManager::MOTD);
output->AddString(motd.str());
//Add char list
output->AddByte(0x64);
output->AddByte((uint8_t)account.charList.size());
std::list<std::string>::iterator it;
for(it = account.charList.begin(); it != account.charList.end(); it++){
output->AddString((*it));
output->AddString(g_config.getString(ConfigManager::WORLD_NAME));
output->AddU32(serverip);
output->AddU16(g_config.getNumber(ConfigManager::PORT));
}
//Add premium days
output->AddU16(account.premiumDays);//output->AddU16(0);
OutputMessagePool::getInstance()->send(output);
getConnection()->closeConnection();
//.........这里部分代码省略.........
示例11: parseFirstPacket
bool ProtocolLogin::parseFirstPacket(NetworkMessage& msg)
{
if (g_game.getGameState() == GAME_STATE_SHUTDOWN) {
getConnection()->closeConnection();
return false;
}
uint32_t clientip = getConnection()->getIP();
/*uint16_t clientos = */
msg.GetU16();
uint16_t version = msg.GetU16();
msg.SkipBytes(12);
/*
* Skipped bytes:
* 12 bytes: dat, spr, pic signatures (4 bytes each)
*/
#ifdef __PROTOCOL_77__
if (!RSA_decrypt(msg)) {
getConnection()->closeConnection();
return false;
}
uint32_t key[4];
key[0] = msg.GetU32();
key[1] = msg.GetU32();
key[2] = msg.GetU32();
key[3] = msg.GetU32();
enableXTEAEncryption();
setXTEAKey(key);
#endif
uint32_t accountName = msg.GetU32();
std::string password = msg.GetString();
if (version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX) {
disconnectClient(0x0A, "Only clients with protocol " CLIENT_VERSION_STR " allowed!");
return false;
}
if (g_game.getGameState() == GAME_STATE_STARTUP) {
disconnectClient(0x0A, "Gameworld is starting up. Please wait.");
return false;
}
if (g_game.getGameState() == GAME_STATE_MAINTAIN) {
disconnectClient(0x0A, "Gameworld is under maintenance. Please re-connect in a while.");
return false;
}
BanInfo banInfo;
if (IOBan::getInstance()->isIpBanned(clientip, banInfo)) {
if (banInfo.reason.empty()) {
banInfo.reason = "(none)";
}
std::ostringstream ss;
ss << "Your IP has been banned until " << formatDateShort(banInfo.expiresAt) << " by " << banInfo.bannedBy << ".\n\nReason specified:\n" << banInfo.reason;
disconnectClient(0x0A, ss.str().c_str());
return false;
}
uint32_t serverip = serverIPs[0].first;
for (uint32_t i = 0; i < serverIPs.size(); i++) {
if ((serverIPs[i].first & serverIPs[i].second) == (clientip & serverIPs[i].second)) {
serverip = serverIPs[i].first;
break;
}
}
if (!accountName) {
disconnectClient(0x0A, "Invalid account id.");
return false;
}
Account account;
if (!IOLoginData::getInstance()->loginserverAuthentication(accountName, password, account)) {
disconnectClient(0x0A, "Account id or password is not correct.");
return false;
}
OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
if (output) {
//Update premium days
g_game.updatePremium(account);
//Add MOTD
output->AddByte(0x14);
std::ostringstream ss;
ss << g_game.getMotdNum() << "\n" << g_config.getString(ConfigManager::MOTD);
output->AddString(ss.str());
//Add char list
output->AddByte(0x64);
output->AddByte((uint8_t)account.charList.size());
for (const std::string& characterName : account.charList) {
//.........这里部分代码省略.........