void PlayerHandler::handleMapChangeMessage(MessageIn &msg) { const std::string mapName = msg.readString(); const unsigned short x = msg.readInt16(); const unsigned short y = msg.readInt16(); Game *game = Game::instance(); const bool sameMap = (game->getCurrentMapName() == mapName); logger->log("Changing map to %s (%d, %d)", mapName.c_str(), x, y); // Switch the actual map, deleting the previous one game->changeMap(mapName); const Vector &playerPos = local_player->getPosition(); float scrollOffsetX = 0.0f; float scrollOffsetY = 0.0f; /* Scroll if neccessary */ if (!sameMap || (abs(x - (int) playerPos.x) > MAP_TELEPORT_SCROLL_DISTANCE) || (abs(y - (int) playerPos.y) > MAP_TELEPORT_SCROLL_DISTANCE)) { scrollOffsetX = x - (int) playerPos.x; scrollOffsetY = y - (int) playerPos.y; } local_player->setAction(Being::STAND); local_player->setPosition(x, y); local_player->setDestination(x, y); logger->log("Adjust scrolling by %d,%d", (int) scrollOffsetX, (int) scrollOffsetY); viewport->scrollBy(scrollOffsetX, scrollOffsetY); }
void ChatHandler::handlePrivateMessage(MessageIn &msg) { std::string userNick = msg.readString(); std::string chatMsg = msg.readString(); chatWindow->whisper(userNick, chatMsg); }
void ItemHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { case GPMSG_ITEM_APPEAR: case GPMSG_ITEMS: { while (msg.getUnreadLength()) { int itemId = msg.readInt16(); int x = msg.readInt16(); int y = msg.readInt16(); int id = (x << 16) | y; // dummy id if (itemId) { actorSpriteManager->createItem(id, itemId, Vector(x, y)); } else if (FloorItem *item = actorSpriteManager->findItem(id)) { actorSpriteManager->destroy(item); } } } break; } }
void GameHandler::handleNpc(GameClient &client, MessageIn &message) { int id = message.readInt16(); Actor *actor = findActorNear(client.character, id); if (!actor || actor->getType() != OBJECT_NPC) { sendNpcError(client, id, "Not close enough to NPC\n"); return; } Being *npc = static_cast<Being*>(actor); switch (message.getId()) { case PGMSG_NPC_SELECT: Npc::integerReceived(client.character, message.readInt8()); break; case PGMSG_NPC_NUMBER: Npc::integerReceived(client.character, message.readInt32()); break; case PGMSG_NPC_STRING: Npc::stringReceived(client.character, message.readString()); break; case PGMSG_NPC_TALK: Npc::start(npc, client.character); break; case PGMSG_NPC_TALK_NEXT: default: Npc::resume(client.character); break; } }
void ChatHandler::handleChatMessage(ChatClient &client, MessageIn &msg) { std::string text = msg.readString(); // Pass it through the slang filter (false when it contains bad words) if (!stringFilter->filterContent(text)) { warnPlayerAboutBadWords(client); return; } short channelId = msg.readShort(); ChatChannel *channel = chatChannelManager->getChannel(channelId); if (channel) { LOG_DEBUG(client.characterName << " says in channel " << channelId << ": " << text); MessageOut result(CPMSG_PUBMSG); result.writeShort(channelId); result.writeString(client.characterName); result.writeString(text); sendInChannel(channel, result); } // log transaction Transaction trans; trans.mCharacterId = client.characterId; trans.mAction = TRANS_MSG_PUBLIC; trans.mMessage = "User said " + text; storage->addTransaction(trans); }
void ItemHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { case GPMSG_ITEM_APPEAR: case GPMSG_ITEMS: { while (msg.getUnreadLength()) { int itemId = msg.readInt16(); int x = msg.readInt16(); int y = msg.readInt16(); int id = (x << 16) | y; // dummy id if (itemId) { floorItemManager->create(id, itemId, x / 32, y / 32, engine->getCurrentMap()); } else if (FloorItem *item = floorItemManager->findById(id)) { floorItemManager->destroy(item); } } } break; } }
void ChatHandler::handleGuildMemberLevelChange(ChatClient &client, MessageIn &msg) { // get the guild, the user to change the permissions, and the new permission // check theyre valid, and then change them MessageOut reply(CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE); short guildId = msg.readInt16(); std::string user = msg.readString(); short level = msg.readInt8(); Guild *guild = guildManager->findById(guildId); CharacterData *c = storage->getCharacter(user); if (guild && c) { int rights = guild->getUserPermissions(c->getDatabaseID()) | level; if (guildManager->changeMemberLevel(&client, guild, c->getDatabaseID(), rights) == 0) { reply.writeInt8(ERRMSG_OK); client.send(reply); } } reply.writeInt8(ERRMSG_FAILURE); client.send(reply); }
void EffectHandler::handleCreateEffectPos(MessageIn &msg) { int id = msg.readInt16(); uint16_t x = msg.readInt16(); uint16_t y = msg.readInt16(); effectManager->trigger(id, x, y); }
void LoginHandler::readUpdateHost(MessageIn &msg) { // Set the update host when included in the message if (msg.getUnreadLength() > 0) { mLoginData->updateHost = msg.readString(); } }
void ChatHandler::handleGuildInvite(ChatClient &client, MessageIn &msg) { MessageOut reply(CPMSG_GUILD_INVITE_RESPONSE); MessageOut invite(CPMSG_GUILD_INVITED); // send an invitation from sender to character to join guild int guildId = msg.readInt16(); std::string character = msg.readString(); // get the chat client and the guild ChatClient *invitedClient = getClient(character); Guild *guild = guildManager->findById(guildId); if (invitedClient && guild) { // check permissions of inviter, and that they arent inviting themself, // and arent someone already in the guild if (guild->canInvite(client.characterId) && client.characterName != character && guild->checkInGuild(client.characterId)) { if ((int)invitedClient->guilds.size() >= Configuration::getValue("account_maxGuildsPerCharacter", 1)) { reply.writeInt8(ERRMSG_LIMIT_REACHED); } else if (guild->checkInGuild(invitedClient->characterId)) { reply.writeInt8(ERRMSG_ALREADY_MEMBER); } else { // send the name of the inviter and the name of the guild // that the character has been invited to join std::string senderName = client.characterName; std::string guildName = guild->getName(); invite.writeString(senderName); invite.writeString(guildName); invite.writeInt16(guildId); invitedClient->send(invite); reply.writeInt8(ERRMSG_OK); // add member to list of invited members to the guild guild->addInvited(invitedClient->characterId); } } else { reply.writeInt8(ERRMSG_FAILURE); } } else { reply.writeInt8(ERRMSG_FAILURE); } client.send(reply); }
void ChatHandler::handleQuitChannelResponse(MessageIn &msg) { if(msg.readInt8() == ERRMSG_OK) { short channelId = msg.readInt16(); Channel *channel = channelManager->findById(channelId); channelManager->removeChannel(channel); } }
void ChatHandler::handleChatMessage(MessageIn &msg) { short channelId = msg.readInt16(); std::string userNick = msg.readString(); std::string chatMsg = msg.readString(); Channel *channel = channelManager->findById(channelId); channel->getTab()->chatLog(userNick, chatMsg); }
void GameHandler::handleNpcBuySell(GameClient &client, MessageIn &message) { BuySell *t = client.character->getBuySell(); if (!t) return; const int id = message.readInt16(); const int amount = message.readInt16(); t->perform(id, amount); }
Character::Character(MessageIn &msg): Being(OBJECT_CHARACTER), mClient(NULL), mConnected(true), mTransactionHandler(NULL), mSpecialUpdateNeeded(false), mDatabaseID(-1), mHairStyle(0), mHairColor(0), mLevel(1), mLevelProgress(0), mUpdateLevelProgress(false), mRecalculateLevel(true), mParty(0), mTransaction(TRANS_NONE), mTalkNpcId(0), mNpcThread(0), mKnuckleAttackInfo(0) { const AttributeManager::AttributeScope &attr = attributeManager->getAttributeScope(CharacterScope); LOG_DEBUG("Character creation: initialisation of " << attr.size() << " attributes."); for (AttributeManager::AttributeScope::const_iterator it1 = attr.begin(), it1_end = attr.end(); it1 != it1_end; ++it1) mAttributes.insert(std::make_pair(it1->first, Attribute(*it1->second))); setWalkMask(Map::BLOCKMASK_WALL); setBlockType(BLOCKTYPE_CHARACTER); // Get character data. mDatabaseID = msg.readInt32(); setName(msg.readString()); deserializeCharacterData(*this, msg); mOld = getPosition(); Inventory(this).initialize(); modifiedAllAttribute(); setSize(16); // Default knuckle attack int damageBase = this->getModifiedAttribute(ATTR_STR); int damageDelta = damageBase / 2; Damage knuckleDamage; knuckleDamage.skill = skillManager->getDefaultSkillId(); knuckleDamage.base = damageBase; knuckleDamage.delta = damageDelta; knuckleDamage.cth = 2; knuckleDamage.element = ELEMENT_NEUTRAL; knuckleDamage.type = DAMAGE_PHYSICAL; knuckleDamage.range = DEFAULT_TILE_LENGTH; mKnuckleAttackInfo = new AttackInfo(0, knuckleDamage, 7, 3, 0); addAttack(mKnuckleAttackInfo); }
void ChatHandler::handleChannelEvent(MessageIn &msg) { short channelId = msg.readInt16(); char eventId = msg.readInt8(); std::string line = msg.readString(); Channel *channel = channelManager->findById(channelId); if(channel) { switch(eventId) { case CHAT_EVENT_NEW_PLAYER: channel->getTab()->chatLog(strprintf(_("%s entered the " "channel."), line.c_str()), BY_CHANNEL); break; case CHAT_EVENT_LEAVING_PLAYER: channel->getTab()->chatLog(strprintf(_("%s left the channel."), line.c_str()), BY_CHANNEL); break; case CHAT_EVENT_TOPIC_CHANGE: channel->getTab()->chatLog(strprintf(_("Topic: %s"), line.c_str()), BY_CHANNEL); break; case CHAT_EVENT_MODE_CHANGE: { int first = line.find(":"); int second = line.find(":", first+1); std::string user1 = line.substr(0, first); std::string user2 = line.substr(first+1, second); std::string mode = line.substr(second+1, line.length()); channel->getTab()->chatLog(strprintf(_("%s has set mode %s " "on user %s."), user1.c_str(), mode.c_str(), user2.c_str()), BY_CHANNEL); } break; case CHAT_EVENT_KICKED_PLAYER: { int first = line.find(":"); std::string user1 = line.substr(0, first); std::string user2 = line.substr(first+1, line.length()); channel->getTab()->chatLog(strprintf(_("%s has kicked %s."), user1.c_str(), user2.c_str()), BY_CHANNEL); } break; default: channel->getTab()->chatLog(_("Unknown channel event."), BY_CHANNEL); } } }
void GameHandler::handleUseSpecialOnPoint(GameClient &client, MessageIn &message) { if (client.character->getAction() == DEAD) return; const int specialID = message.readInt8(); const int x = message.readInt16(); const int y = message.readInt16(); LOG_DEBUG("Character " << client.character->getPublicID() << " tries to use his special attack " << specialID); client.character->useSpecialOnPoint(specialID, x, y); }
CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg): mClient(nullptr), mConnected(true), mTransactionHandler(nullptr), mDatabaseID(-1), mHairStyle(0), mHairColor(0), mSendAttributePointsStatus(false), mAttributePoints(0), mCorrectionPoints(0), mSendAbilityCooldown(false), mParty(0), mTransaction(TRANS_NONE), mTalkNpcId(0), mNpcThread(0), mBaseEntity(&entity) { auto *beingComponent = entity.getComponent<BeingComponent>(); auto &attributeScope = attributeManager->getAttributeScope(CharacterScope); LOG_DEBUG("Character creation: initialisation of " << attributeScope.size() << " attributes."); for (auto &attribute : attributeScope) beingComponent->createAttribute(attribute); auto *actorComponent = entity.getComponent<ActorComponent>(); actorComponent->setWalkMask(Map::BLOCKMASK_WALL); actorComponent->setBlockType(BLOCKTYPE_CHARACTER); actorComponent->setSize(16); auto *abilityComponent = new AbilityComponent(); entity.addComponent(abilityComponent); abilityComponent->signal_ability_changed.connect( sigc::mem_fun(this, &CharacterComponent::abilityStatusChanged)); abilityComponent->signal_global_cooldown_activated.connect( sigc::mem_fun(this, &CharacterComponent::abilityCooldownActivated)); // Get character data. mDatabaseID = msg.readInt32(); beingComponent->setName(msg.readString()); deserialize(entity, msg); Inventory(&entity, mPossessions).initialize(); beingComponent->signal_attribute_changed.connect(sigc::mem_fun( this, &CharacterComponent::attributeChanged)); }
void ChatHandler::handleGuildKickMember(ChatClient &client, MessageIn &msg) { MessageOut reply(CPMSG_GUILD_KICK_MEMBER_RESPONSE); short guildId = msg.readInt16(); std::string otherCharName = msg.readString(); Guild *guild = guildManager->findById(guildId); if (!guild) { reply.writeInt8(ERRMSG_INVALID_ARGUMENT); client.send(reply); return; } ChatClient *otherClient = getClient(otherCharName); unsigned otherCharId; if (otherClient) otherCharId = otherClient->characterId; else otherCharId = storage->getCharacterId(otherCharName); if (otherCharId == 0) { reply.writeInt8(ERRMSG_INVALID_ARGUMENT); client.send(reply); return; } if (!((guild->getUserPermissions(client.characterId) & GAL_KICK) && guild->checkInGuild(otherCharId) && otherCharId != client.characterId)) { reply.writeInt8(ERRMSG_INSUFFICIENT_RIGHTS); client.send(reply); return; } if (otherClient) { // Client is online. Inform him about that he got kicked MessageOut kickMsg(CPMSG_GUILD_KICK_NOTIFICATION); kickMsg.writeInt16(guild->getId()); kickMsg.writeString(client.characterName); otherClient->send(kickMsg); } guildManager->removeGuildMember(guild, otherCharId, otherCharName, otherClient); reply.writeInt8(ERRMSG_OK); client.send(reply); }
void ChatHandler::handleWhoResponse(MessageIn &msg) { std::string userNick; while(msg.getUnreadLength()) { userNick = msg.readString(); if (userNick == "") { break; } localChatTab->chatLog(userNick, BY_SERVER); } }
void GameHandler::handleUseSpecialOnBeing(GameClient &client, MessageIn &message) { if (client.character->getAction() == DEAD) return; const int specialID = message.readInt8(); const int targetID = message.readInt16(); // 0 when no target is selected Being *being = 0; if (targetID != 0) being = findBeingNear(client.character, targetID); LOG_DEBUG("Character " << client.character->getPublicID() << " tries to use his special attack " << specialID); client.character->useSpecialOnBeing(specialID, being); }
void GameHandler::handleMoveItem(GameClient &client, MessageIn &message) { const int slot1 = message.readInt16(); const int slot2 = message.readInt16(); const int amount = message.readInt16(); Inventory(client.character).move(slot1, slot2, amount); // log transaction std::stringstream str; str << "User moved item " << " from slot " << slot1 << " to slot " << slot2; accountHandler->sendTransaction(client.character->getDatabaseID(), TRANS_ITEM_MOVE, str.str()); }
void LoginHandler::handleLoginResponse(MessageIn &msg) { const int errMsg = msg.readInt8(); if (errMsg == ERRMSG_OK) { readUpdateHost(msg); state = STATE_CHAR_SELECT; } else { switch (errMsg) { case LOGIN_INVALID_VERSION: errorMessage = _("Client version is too old"); break; case ERRMSG_INVALID_ARGUMENT: errorMessage = _("Wrong username or password"); break; case ERRMSG_FAILURE: errorMessage = _("Already logged in"); break; case LOGIN_SERVER_FULL: errorMessage = _("Server is full"); break; default: errorMessage = _("Unknown error"); break; } state = STATE_LOGIN_ERROR; } }
void ChatHandler::handleGuildGetMembers(ChatClient &client, MessageIn &msg) { MessageOut reply(CPMSG_GUILD_GET_MEMBERS_RESPONSE); short guildId = msg.readInt16(); Guild *guild = guildManager->findById(guildId); // check for valid guild // write a list of member names that belong to the guild if (guild) { // make sure the requestor is in the guild if (guild->checkInGuild(client.characterId)) { reply.writeInt8(ERRMSG_OK); reply.writeInt16(guildId); std::list<GuildMember*> memberList = guild->getMembers(); std::list<GuildMember*>::const_iterator itr_end = memberList.end(); for (std::list<GuildMember*>::iterator itr = memberList.begin(); itr != itr_end; ++itr) { CharacterData *c = storage->getCharacter((*itr)->mId, nullptr); std::string memberName = c->getName(); reply.writeString(memberName); reply.writeInt8(mPlayerMap.find(memberName) != mPlayerMap.end()); } } } else { reply.writeInt8(ERRMSG_FAILURE); } client.send(reply); }
void LoginHandler::handleRegisterResponse(MessageIn &msg) { const int errMsg = msg.readInt8(); if (errMsg == ERRMSG_OK) { readUpdateHost(msg); state = STATE_CHAR_SELECT; } else { switch (errMsg) { case REGISTER_INVALID_VERSION: errorMessage = _("Client version is too old"); break; case ERRMSG_INVALID_ARGUMENT: errorMessage = _("Wrong username, password or email address"); break; case REGISTER_EXISTS_USERNAME: errorMessage = _("Username already exists"); break; case REGISTER_EXISTS_EMAIL: errorMessage = _("Email address already exists"); break; default: errorMessage = _("Unknown error"); break; } state = STATE_LOGIN_ERROR; } }
void GameHandler::handleLowerAttribute(GameClient &client, MessageIn &message) { const int attribute = message.readInt32(); AttribmodResponseCode retCode; retCode = client.character->useCorrectionPoint(attribute); MessageOut result(GPMSG_LOWER_ATTRIBUTE_RESPONSE); result.writeInt8(retCode); result.writeInt16(attribute); client.send(result); if (retCode == ATTRIBMOD_OK) { accountHandler->updateCharacterPoints( client.character->getDatabaseID(), client.character->getCharacterPoints(), client.character->getCorrectionPoints()); // log transaction std::stringstream str; str << "User decreased attribute " << attribute; accountHandler->sendTransaction(client.character->getDatabaseID(), TRANS_ATTR_DECREASE, str.str()); } }
void AccountHandler::handlePasswordChangeMessage(AccountClient &client, MessageIn &msg) { std::string oldPassword = sha256(msg.readString()); std::string newPassword = sha256(msg.readString()); MessageOut reply(APMSG_PASSWORD_CHANGE_RESPONSE); Account *acc = client.getAccount(); if (!acc) { reply.writeInt8(ERRMSG_NO_LOGIN); } else if (stringFilter->findDoubleQuotes(newPassword)) { reply.writeInt8(ERRMSG_INVALID_ARGUMENT); } else if (oldPassword != acc->getPassword()) { reply.writeInt8(ERRMSG_FAILURE); } else { acc->setPassword(newPassword); // Keep the database up to date otherwise we will go out of sync storage->flush(acc); reply.writeInt8(ERRMSG_OK); } client.send(reply); }
void GameHandler::handleDisconnect(GameClient &client, MessageIn &message) { const bool reconnectAccount = (bool) message.readInt8(); MessageOut result(GPMSG_DISCONNECT_RESPONSE); result.writeInt8(ERRMSG_OK); // It is, when control reaches here if (reconnectAccount) { std::string magic_token(utils::getMagicToken()); result.writeString(magic_token, MAGIC_TOKEN_LENGTH); // No accountserver data, the client should remember that accountHandler->playerReconnectAccount( client.character->getDatabaseID(), magic_token); } accountHandler->sendCharacterData(client.character); // Done with the character, also handle possible respawn case client.character->disconnected(); delete client.character; client.character = 0; client.status = CLIENT_LOGIN; client.send(result); }
void ChatHandler::handleListChannelUsersMessage(ChatClient &client, MessageIn &msg) { MessageOut reply(CPMSG_LIST_CHANNELUSERS_RESPONSE); std::string channelName = msg.readString(); ChatChannel *channel = chatChannelManager->getChannel(channelName); if (channel) { reply.writeString(channel->getName()); const ChatChannel::ChannelUsers &users = channel->getUserList(); for (ChatChannel::ChannelUsers::const_iterator i = users.begin(), i_end = users.end(); i != i_end; ++i) { reply.writeString((*i)->characterName); reply.writeString(channel->getUserMode((*i))); } client.send(reply); } // log transaction Transaction trans; trans.mCharacterId = client.characterId; trans.mAction = TRANS_CHANNEL_USERLIST; trans.mMessage = ""; storage->addTransaction(trans); }
void ChatHandler::handleListChannelsResponse(MessageIn &msg) { localChatTab->chatLog(_("Listing channels."), BY_SERVER); while(msg.getUnreadLength()) { std::string channelName = msg.readString(); if (channelName == "") return; std::ostringstream numUsers; numUsers << msg.readInt16(); channelName += " - "; channelName += numUsers.str(); localChatTab->chatLog(channelName, BY_SERVER); } localChatTab->chatLog(_("End of channel list."), BY_SERVER); }
void GameHandler::handleRaiseAttribute(GameClient &client, MessageIn &message) { auto *characterComponent = client.character->getComponent<CharacterComponent>(); const int attribute = message.readInt16(); AttribmodResponseCode retCode; retCode = characterComponent->useCharacterPoint(*client.character, attribute); MessageOut result(GPMSG_RAISE_ATTRIBUTE_RESPONSE); result.writeInt8(retCode); result.writeInt16(attribute); client.send(result); if (retCode == ATTRIBMOD_OK) { accountHandler->updateCharacterPoints( characterComponent->getDatabaseID(), characterComponent->getCharacterPoints(), characterComponent->getCorrectionPoints()); // log transaction std::stringstream str; str << "User increased attribute " << attribute; accountHandler->sendTransaction(characterComponent->getDatabaseID(), TRANS_ATTR_INCREASE, str.str()); } }