void ProtocolOld::onRecvFirstMessage(NetworkMessage& msg) { if (g_game.getGameState() == GAME_STATE_SHUTDOWN) { disconnect(); return; } /*uint16_t clientOS =*/ msg.get<uint16_t>(); uint16_t version = msg.get<uint16_t>(); msg.skipBytes(12); if (version <= 760) { disconnectClient("Only clients with protocol " CLIENT_VERSION_STR " allowed!"); return; } if (!Protocol::RSA_decrypt(msg)) { disconnect(); return; } uint32_t key[4]; key[0] = msg.get<uint32_t>(); key[1] = msg.get<uint32_t>(); key[2] = msg.get<uint32_t>(); key[3] = msg.get<uint32_t>(); enableXTEAEncryption(); setXTEAKey(key); if (version <= 822) { disableChecksum(); } disconnectClient("Only clients with protocol " CLIENT_VERSION_STR " allowed!"); }
void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg) { if (g_game.getGameState() == GAME_STATE_SHUTDOWN) { getConnection()->close(); return; } msg.skipBytes(2); // client OS uint16_t version = msg.get<uint16_t>(); if (version >= 971) { msg.skipBytes(17); } else { msg.skipBytes(12); } /* * Skipped bytes: * 4 bytes: protocolVersion * 12 bytes: dat, spr, pic signatures (4 bytes each) * 1 byte: 0 */ #define dispatchDisconnectClient(err) g_dispatcher.addTask(createTask(std::bind(&ProtocolLogin::disconnectClient, this, err, version))) if (version <= 760) { dispatchDisconnectClient("Only clients with protocol " CLIENT_VERSION_STR " allowed!"); return; } if (!Protocol::RSA_decrypt(msg)) { getConnection()->close(); return; } uint32_t key[4]; key[0] = msg.get<uint32_t>(); key[1] = msg.get<uint32_t>(); key[2] = msg.get<uint32_t>(); key[3] = msg.get<uint32_t>(); enableXTEAEncryption(); setXTEAKey(key); if (version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX) { dispatchDisconnectClient("Only clients with protocol " CLIENT_VERSION_STR " allowed!"); return; } if (g_game.getGameState() == GAME_STATE_STARTUP) { dispatchDisconnectClient("Gameworld is starting up. Please wait."); return; } if (g_game.getGameState() == GAME_STATE_MAINTAIN) { dispatchDisconnectClient("Gameworld is under maintenance.\nPlease re-connect in a while."); return; } BanInfo banInfo; if (IOBan::isIpBanned(getConnection()->getIP(), 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; dispatchDisconnectClient(ss.str()); return; } std::string accountName = msg.getString(); std::string password = msg.getString(); if (accountName.empty()) { if (!g_config.getBoolean(ConfigManager::ENABLE_LIVE_CASTING)) { dispatchDisconnectClient("Invalid account name."); } else { g_dispatcher.addTask(createTask(std::bind(&ProtocolLogin::getCastingStreamsList, this, password, version))); } return; } #undef dispatchDisconnectClient g_dispatcher.addTask(createTask(std::bind(&ProtocolLogin::getCharacterList, this, accountName, password, version))); }
void ProtocolSpectator::onRecvFirstMessage(NetworkMessage& msg) { if (g_game.getGameState() == GAME_STATE_SHUTDOWN) { getConnection()->close(); return; } operatingSystem = (OperatingSystem_t)msg.get<uint16_t>(); version = msg.get<uint16_t>(); msg.skipBytes(7); // U32 clientVersion, U8 clientType if (!RSA_decrypt(msg)) { getConnection()->close(); return; } uint32_t key[4]; key[0] = msg.get<uint32_t>(); key[1] = msg.get<uint32_t>(); key[2] = msg.get<uint32_t>(); key[3] = msg.get<uint32_t>(); enableXTEAEncryption(); setXTEAKey(key); if (operatingSystem >= CLIENTOS_OTCLIENT_LINUX) { NetworkMessage opcodeMessage; opcodeMessage.addByte(0x32); opcodeMessage.addByte(0x00); opcodeMessage.add<uint16_t>(0x00); writeToOutputBuffer(opcodeMessage); } msg.skipBytes(1); // gamemaster flag std::string password = msg.getString(); std::string characterName = msg.getString(); uint32_t timeStamp = msg.get<uint32_t>(); uint8_t randNumber = msg.getByte(); if (m_challengeTimestamp != timeStamp || m_challengeRandom != randNumber) { getConnection()->close(); return; } auto dispatchDisconnectClient = [this](const std::string& msg) { g_dispatcher.addTask(createTask( std::bind(&ProtocolSpectator::disconnectSpectator, this, msg))); }; if (version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX) { dispatchDisconnectClient("Only clients with protocol " CLIENT_VERSION_STR " allowed!"); return; } if (g_game.getGameState() == GAME_STATE_STARTUP) { dispatchDisconnectClient("Gameworld is starting up. Please wait."); return; } if (g_game.getGameState() == GAME_STATE_MAINTAIN) { dispatchDisconnectClient("Gameworld is under maintenance. Please re-connect in a while."); return; } BanInfo banInfo; if (IOBan::isIpBanned(getIP(), 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; dispatchDisconnectClient(ss.str()); return; } password.erase(password.begin()); g_dispatcher.addTask(createTask(std::bind(&ProtocolSpectator::login, this, characterName, password))); }
void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg) { if (g_game.getGameState() == GAME_STATE_SHUTDOWN) { disconnect(); return; } /*uint16_t clientos = */ msg.get<uint16_t>(); uint16_t version = msg.get<uint16_t>(); msg.skipBytes(12); /* * Skipped bytes: * 4 bytes: protocolVersion * 12 bytes: dat, spr, pic signatures (4 bytes each) * 1 byte: 0 */ if (version <= 760) { disconnectClient("Only clients with protocol " CLIENT_VERSION_STR " allowed!"); return; } if (!Protocol::RSA_decrypt(msg)) { disconnect(); return; } uint32_t key[4]; key[0] = msg.get<uint32_t>(); key[1] = msg.get<uint32_t>(); key[2] = msg.get<uint32_t>(); key[3] = msg.get<uint32_t>(); enableXTEAEncryption(); setXTEAKey(key); uint32_t accountName = msg.get<uint32_t>(); std::string password = msg.getString(); if (version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX) { disconnectClient("Only clients with protocol " CLIENT_VERSION_STR " allowed!"); return; } if (g_game.getGameState() == GAME_STATE_STARTUP) { disconnectClient("Gameworld is starting up. Please wait."); return; } if (g_game.getGameState() == GAME_STATE_MAINTAIN) { disconnectClient("Gameworld is under maintenance.\nPlease re-connect in a while."); return; } BanInfo banInfo; auto connection = getConnection(); if (!connection) { return; } if (IOBan::isIpBanned(connection->getIP(), 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(ss.str()); return; } if (accountName == 0) { disconnectClient("Invalid account name."); return; } auto thisPtr = std::dynamic_pointer_cast<ProtocolLogin>(shared_from_this()); g_dispatcher.addTask(createTask(std::bind(&ProtocolLogin::getCharacterList, thisPtr, accountName, password))); }