void ProtocolSpectator::parseSpectatorSay(NetworkMessage& msg) { SpeakClasses type = (SpeakClasses)msg.getByte(); uint16_t channelId = 0; if (type == TALKTYPE_CHANNEL_Y) { channelId = msg.get<uint16_t>(); } else { return; } const std::string text = msg.getString(); if (text.length() > 255 || channelId != CHANNEL_CAST || !client) { return; } if (client) { if (client->isSpectatorMuted(spectatorId)) { sendTextMessage(TextMessage(MESSAGE_STATUS_SMALL, "You have been muted.")); return; } if (parseCoomand(text)) { return; } g_dispatcher.addTask(createTask(std::bind(&ProtocolCaster::broadcastSpectatorMessage, client, spectatorName, text))); } }
Protocol_ptr ServicePort::make_protocol(bool checksummed, NetworkMessage& msg, const Connection_ptr& connection) const { uint8_t protocolID = msg.getByte(); for (auto& service : m_services) { if (protocolID != service->get_protocol_identifier()) { continue; } if ((checksummed && service->is_checksummed()) || !service->is_checksummed()) { return service->make_protocol(connection); } } return nullptr; }
void ProtocolStatus::onRecvFirstMessage(NetworkMessage& msg) { uint32_t ip = getIP(); if (ip != 0x0100007F) { std::string ipStr = convertIPToString(ip); if (ipStr != g_config.getString(ConfigManager::IP)) { std::map<uint32_t, int64_t>::const_iterator it = ipConnectMap.find(ip); if (it != ipConnectMap.end()) { if (OTSYS_TIME() < (it->second + g_config.getNumber(ConfigManager::STATUSQUERY_TIMEOUT))) { getConnection()->close(); return; } } } } ipConnectMap[ip] = OTSYS_TIME(); switch (msg.getByte()) { //XML info protocol case 0xFF: { if (msg.getString(4) == "info") { g_dispatcher.addTask(createTask(std::bind(&ProtocolStatus::sendStatusString, this))); return; } break; } //Another ServerInfo protocol case 0x01: { uint16_t requestedInfo = msg.get<uint16_t>(); // only a Byte is necessary, though we could add new info here std::string characterName; if (requestedInfo & REQUEST_PLAYER_STATUS_INFO) { characterName = msg.getString(); } g_dispatcher.addTask(createTask(std::bind(&ProtocolStatus::sendInfo, this, requestedInfo, characterName))); return; } default: break; } getConnection()->close(); }
void ProtocolSpectator::parseSpectatorSay(NetworkMessage& msg) { SpeakClasses type = (SpeakClasses)msg.getByte(); uint16_t channelId = 0; if (type == TALKTYPE_CHANNEL_Y) { channelId = msg.get<uint16_t>(); } else { return; } const std::string text = msg.getString(); if (text.length() > 255 || channelId != CHANNEL_CAST || !client) { return; } if (client) { g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::broadcastSpectatorMessage, client, text))); } }
void ProtocolSpectator::parsePacket(NetworkMessage& msg) { if (!m_acceptPackets || g_game.getGameState() == GAME_STATE_SHUTDOWN || msg.getLength() <= 0) { return; } uint8_t recvbyte = msg.getByte(); if (!player) { if (recvbyte == 0x0F) { disconnect(); } return; } //a dead player can not perform actions if (player->isRemoved() || player->getHealth() <= 0) { disconnect(); return; } switch (recvbyte) { case 0x14: g_dispatcher.addTask(createTask(std::bind(&ProtocolSpectator::logout, this))); break; case 0x1D: g_dispatcher.addTask(createTask(std::bind(&ProtocolSpectator::sendPingBack, this))); break; case 0x1E: g_dispatcher.addTask(createTask(std::bind(&ProtocolSpectator::sendPing, this))); break; //Reset viewed position/direction if the spectator tries to move in any way case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F: case 0x70: case 0x71: case 0x72: g_dispatcher.addTask(createTask(std::bind(&ProtocolSpectator::sendCancelWalk, this))); break; case 0x96: parseSpectatorSay(msg); break; default: break; } if (msg.isOverrun()) { disconnect(); } }
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))); }