void ProtocolGameBase::sendChannel(uint16_t channelId, const std::string& channelName, const UsersMap* channelUsers, const InvitedMap* invitedUsers) { NetworkMessage msg; msg.addByte(0xAC); msg.add<uint16_t>(channelId); msg.addString(channelName); if (channelUsers) { msg.add<uint16_t>(channelUsers->size()); for (const auto& it : *channelUsers) { msg.addString(it.second->getName()); } } else { msg.add<uint16_t>(0x00); } if (invitedUsers) { msg.add<uint16_t>(invitedUsers->size()); for (const auto& it : *invitedUsers) { msg.addString(it.second->getName()); } } else { msg.add<uint16_t>(0x00); } writeToOutputBuffer(msg); }
void ProtocolGameBase::sendVIP(uint32_t guid, const std::string& name, const std::string& description, uint32_t icon, bool notify, VipStatus_t status) { NetworkMessage msg; msg.addByte(0xD2); msg.add<uint32_t>(guid); msg.addString(name); msg.addString(description); msg.add<uint32_t>(std::min<uint32_t>(10, icon)); msg.addByte(notify ? 0x01 : 0x00); msg.addByte(status); writeToOutputBuffer(msg); }
void ProtocolSpectator::addDummyCreature(NetworkMessage& msg, const uint32_t& creatureID, const Position& playerPos) { // add dummy creature CreatureType_t creatureType = CREATURETYPE_NPC; if(creatureID <= 0x10000000) { creatureType = CREATURETYPE_PLAYER; } else if(creatureID <= 0x40000000) { creatureType = CREATURETYPE_MONSTER; } msg.addByte(0x6A); msg.addPosition(playerPos); msg.addByte(1); //stackpos msg.add<uint16_t>(0x61); // is not known msg.add<uint32_t>(0); // remove no creature msg.add<uint32_t>(creatureID); // creature id msg.addByte(creatureType); // creature type msg.addString("Dummy"); msg.addByte(0x00); // health percent msg.addByte(DIRECTION_NORTH); // direction AddOutfit(msg, player->getCurrentOutfit()); // outfit msg.addByte(0); // light level msg.addByte(0); // light color msg.add<uint16_t>(200); // speed msg.addByte(SKULL_NONE); // skull type msg.addByte(SHIELD_NONE); // party shield msg.addByte(GUILDEMBLEM_NONE); // guild emblem msg.addByte(creatureType); // creature type msg.addByte(SPEECHBUBBLE_NONE); // speechbubble msg.addByte(0xFF); // MARK_UNMARKED msg.add<uint16_t>(0x00); // helpers msg.addByte(0); // walkThrough }
void ProtocolGameBase::sendContainer(uint8_t cid, const Container* container, bool hasParent, uint16_t firstIndex) { NetworkMessage msg; msg.addByte(0x6E); msg.addByte(cid); if (container->getID() == ITEM_BROWSEFIELD) { msg.addItem(1987, 1); msg.addString("Browse Field"); } else { msg.addItem(container); msg.addString(container->getName()); } msg.addByte(container->capacity()); msg.addByte(hasParent ? 0x01 : 0x00); msg.addByte(container->isUnlocked() ? 0x01 : 0x00); // Drag and drop msg.addByte(container->hasPagination() ? 0x01 : 0x00); // Pagination uint32_t containerSize = container->size(); msg.add<uint16_t>(containerSize); msg.add<uint16_t>(firstIndex); if (firstIndex < containerSize) { uint8_t itemsToSend = std::min<uint32_t>(std::min<uint32_t>(container->capacity(), containerSize - firstIndex), std::numeric_limits<uint8_t>::max()); msg.addByte(itemsToSend); for (ItemDeque::const_iterator it = container->getItemList().begin() + firstIndex, end = it + itemsToSend; it != end; ++it) { msg.addItem(*it); } } else { msg.addByte(0x00); } writeToOutputBuffer(msg); }
void ProtocolGameBase::sendAddCreature(const Creature* creature, const Position& pos, int32_t stackpos, bool isLogin) { if (!canSee(pos)) { return; } if (creature != player) { if (stackpos != -1) { NetworkMessage msg; msg.addByte(0x6A); msg.addPosition(pos); msg.addByte(stackpos); bool known; uint32_t removedKnown; checkCreatureAsKnown(creature->getID(), known, removedKnown); AddCreature(msg, creature, known, removedKnown); writeToOutputBuffer(msg); } if (isLogin) { sendMagicEffect(pos, CONST_ME_TELEPORT); } return; } NetworkMessage msg; msg.addByte(0x17); msg.add<uint32_t>(player->getID()); msg.add<uint16_t>(0x32); // beat duration (50) msg.addDouble(Creature::speedA, 3); msg.addDouble(Creature::speedB, 3); msg.addDouble(Creature::speedC, 3); // can report bugs? if (player->getAccountType() >= ACCOUNT_TYPE_TUTOR) { msg.addByte(0x01); } else { msg.addByte(0x00); } msg.addByte(0x00); // can change pvp framing option msg.addByte(0x00); // expert mode button enabled msg.addString("http://static.tibia.com/images/store/"); msg.addByte(3); writeToOutputBuffer(msg); sendPendingStateEntered(); sendEnterWorld(); sendMapDescription(pos); if (isLogin) { sendMagicEffect(pos, CONST_ME_TELEPORT); } sendInventoryItem(CONST_SLOT_HEAD, player->getInventoryItem(CONST_SLOT_HEAD)); sendInventoryItem(CONST_SLOT_NECKLACE, player->getInventoryItem(CONST_SLOT_NECKLACE)); sendInventoryItem(CONST_SLOT_BACKPACK, player->getInventoryItem(CONST_SLOT_BACKPACK)); sendInventoryItem(CONST_SLOT_ARMOR, player->getInventoryItem(CONST_SLOT_ARMOR)); sendInventoryItem(CONST_SLOT_RIGHT, player->getInventoryItem(CONST_SLOT_RIGHT)); sendInventoryItem(CONST_SLOT_LEFT, player->getInventoryItem(CONST_SLOT_LEFT)); sendInventoryItem(CONST_SLOT_LEGS, player->getInventoryItem(CONST_SLOT_LEGS)); sendInventoryItem(CONST_SLOT_FEET, player->getInventoryItem(CONST_SLOT_FEET)); sendInventoryItem(CONST_SLOT_RING, player->getInventoryItem(CONST_SLOT_RING)); sendInventoryItem(CONST_SLOT_AMMO, player->getInventoryItem(CONST_SLOT_AMMO)); sendStats(); sendSkills(); //gameworld light-settings LightInfo lightInfo; g_game.getWorldLightInfo(lightInfo); sendWorldLight(lightInfo); //player light level sendCreatureLight(creature); const std::forward_list<VIPEntry>& vipEntries = IOLoginData::getVIPEntries(player->getAccount()); if (player->isAccessPlayer()) { for (const VIPEntry& entry : vipEntries) { VipStatus_t vipStatus; Player* vipPlayer = g_game.getPlayerByGUID(entry.guid); if (!vipPlayer) { vipStatus = VIPSTATUS_OFFLINE; } else { vipStatus = VIPSTATUS_ONLINE; } sendVIP(entry.guid, entry.name, entry.description, entry.icon, entry.notify, vipStatus); } } else { for (const VIPEntry& entry : vipEntries) { VipStatus_t vipStatus; Player* vipPlayer = g_game.getPlayerByGUID(entry.guid); if (!vipPlayer || vipPlayer->isInGhostMode()) { vipStatus = VIPSTATUS_OFFLINE; } else { vipStatus = VIPSTATUS_ONLINE; } sendVIP(entry.guid, entry.name, entry.description, entry.icon, entry.notify, vipStatus); } } sendBasicData(); sendInventory(); player->sendIcons(); }
void ProtocolGameBase::AddCreature(NetworkMessage& msg, const Creature* creature, bool known, uint32_t remove) { CreatureType_t creatureType = creature->getType(); const Player* otherPlayer = creature->getPlayer(); if (known) { msg.add<uint16_t>(0x62); msg.add<uint32_t>(creature->getID()); } else { msg.add<uint16_t>(0x61); msg.add<uint32_t>(remove); msg.add<uint32_t>(creature->getID()); msg.addByte(creatureType); msg.addString(creature->getName()); } if (creature->isHealthHidden()) { msg.addByte(0x00); } else { msg.addByte(std::ceil((static_cast<double>(creature->getHealth()) / std::max<int32_t>(creature->getMaxHealth(), 1)) * 100)); } msg.addByte(creature->getDirection()); if (!creature->isInGhostMode() && !creature->isInvisible()) { AddOutfit(msg, creature->getCurrentOutfit()); } else { static Outfit_t outfit; AddOutfit(msg, outfit); } LightInfo lightInfo; creature->getCreatureLight(lightInfo); msg.addByte(player->isAccessPlayer() ? 0xFF : lightInfo.level); msg.addByte(lightInfo.color); msg.add<uint16_t>(creature->getStepSpeed() / 2); msg.addByte(player->getSkullClient(creature)); msg.addByte(player->getPartyShield(otherPlayer)); if (!known) { msg.addByte(player->getGuildEmblem(otherPlayer)); } if (creatureType == CREATURETYPE_MONSTER) { const Creature* master = creature->getMaster(); if (master) { const Player* masterPlayer = master->getPlayer(); if (masterPlayer) { if (masterPlayer == player) { creatureType = CREATURETYPE_SUMMON_OWN; } else { creatureType = CREATURETYPE_SUMMON_OTHERS; } } } } msg.addByte(creatureType); // Type (for summons) msg.addByte(creature->getSpeechBubble()); msg.addByte(0xFF); // MARK_UNMARKED if (otherPlayer) { msg.add<uint16_t>(otherPlayer->getHelpers()); } else { msg.add<uint16_t>(0x00); } msg.addByte(player->canWalkthroughEx(creature) ? 0x00 : 0x01); }