//////////////////////////////////////////////////////////////////////// // OpenTibia - an opensource roleplaying game //////////////////////////////////////////////////////////////////////// // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . //////////////////////////////////////////////////////////////////////// #ifndef __PROTOCOLGAME__ #define __PROTOCOLGAME__ #include "otsystem.h" #include "enums.h" #include "protocol.h" #include "creature.h" class NetworkMessage; class Player; class Game; class House; class Container; class Tile; class Connection; class Quest; enum taskFlags_t { TASK_NONE = 0, TASK_LIMIT_HARD = 1 << 0, TASK_LIMIT_EXEMPT = 1 << 1 }; enum LaspPacket_t { PACKET_DEFAULT, PACKET_SAY, PACKET_CHANNEL_INVITE, PACKET_AUTO_WALK, PACKET_SET_OUTFIT, PACKET_BATTLE_WINDOW, PACKET_SAY_TO_NPC, PACKET_SHOP, PACKET_WALK, PACKET_FIRST = PACKET_DEFAULT, PACKET_LAST = PACKET_WALK }; typedef boost::shared_ptr NetworkMessage_ptr; class ProtocolGame : public Protocol { public: #ifdef __ENABLE_SERVER_DIAGNOSTIC__ static uint32_t protocolGameCount; #endif ProtocolGame(Connection_ptr connection): Protocol(connection) { #ifdef __ENABLE_SERVER_DIAGNOSTIC__ protocolGameCount++; #endif for(uint32_t i = PACKET_FIRST; i <= PACKET_LAST; ++i) lastPacket[i] = 0; player = NULL; m_eventConnect = 0; m_debugAssertSent = m_acceptPackets = false; } virtual ~ProtocolGame() { #ifdef __ENABLE_SERVER_DIAGNOSTIC__ protocolGameCount--; #endif player = NULL; } enum {protocolId = 0x0A}; enum {isSingleSocket = true}; enum {hasChecksum = true}; static const char* protocolName() {return "game protocol";} bool login(const std::string& name, uint32_t id, const std::string& password, OperatingSystem_t operatingSystem, uint16_t version, bool gamemaster); bool logout(bool displayEffect, bool forceLogout); void setPlayer(Player* p); private: void disconnectClient(uint8_t error, const char* message); std::list knownCreatureList; void checkCreatureAsKnown(uint32_t id, bool& known, uint32_t& removedKnown); bool connect(uint32_t playerId, OperatingSystem_t operatingSystem, uint16_t version); void disconnect(); virtual void releaseProtocol(); virtual void deleteProtocolTask(); bool canSee(uint16_t x, uint16_t y, uint16_t z) const; bool canSee(const Creature*) const; bool canSee(const Position& pos) const; virtual void onConnect(); virtual void onRecvFirstMessage(NetworkMessage& msg); bool parseFirstPacket(NetworkMessage& msg); virtual void parsePacket(NetworkMessage& msg); //Parse methods void parseLogout(NetworkMessage& msg); void parseCancelMove(NetworkMessage& msg); void parseReceivePing(NetworkMessage& msg); void parseAutoWalk(NetworkMessage& msg); void parseMove(NetworkMessage& msg, Direction dir); void parseTurn(NetworkMessage& msg, Direction dir); void parseRequestOutfit(NetworkMessage& msg); void parseSetOutfit(NetworkMessage& msg); void parseSay(NetworkMessage& msg); void parseLookAt(NetworkMessage& msg); void parseFightModes(NetworkMessage& msg); void parseAttack(NetworkMessage& msg); void parseFollow(NetworkMessage& msg); void parseBugReport(NetworkMessage& msg); void parseDebugAssert(NetworkMessage& msg); void parseThrow(NetworkMessage& msg); void parseUseItemEx(NetworkMessage& msg); void parseBattleWindow(NetworkMessage& msg); void parseUseItem(NetworkMessage& msg); void parseCloseContainer(NetworkMessage& msg); void parseUpArrowContainer(NetworkMessage& msg); void parseUpdateTile(NetworkMessage& msg); void parseUpdateContainer(NetworkMessage& msg); void parseTextWindow(NetworkMessage& msg); void parseHouseWindow(NetworkMessage& msg); void parseLookInShop(NetworkMessage& msg); void parsePlayerPurchase(NetworkMessage& msg); void parsePlayerSale(NetworkMessage& msg); void parseCloseShop(NetworkMessage& msg); void parseQuests(NetworkMessage& msg); void parseQuestInfo(NetworkMessage& msg); void parseInviteToParty(NetworkMessage& msg); void parseJoinParty(NetworkMessage& msg); void parseRevokePartyInvite(NetworkMessage& msg); void parsePassPartyLeadership(NetworkMessage& msg); void parseLeaveParty(NetworkMessage& msg); void parseSharePartyExperience(NetworkMessage& msg); //trade methods void parseRequestTrade(NetworkMessage& msg); void parseLookInTrade(NetworkMessage& msg); void parseAcceptTrade(NetworkMessage& msg); void parseCloseTrade(); //VIP methods void parseAddVip(NetworkMessage& msg); void parseRemoveVip(NetworkMessage& msg); void parseRotateItem(NetworkMessage& msg); //Channel tabs void parseCreatePrivateChannel(NetworkMessage& msg); void parseChannelInvite(NetworkMessage& msg); void parseChannelExclude(NetworkMessage& msg); void parseGetChannels(NetworkMessage& msg); void parseOpenChannel(NetworkMessage& msg); void parseOpenPriv(NetworkMessage& msg); void parseCloseChannel(NetworkMessage& msg); void parseCloseNpc(NetworkMessage& msg); void parseProcessRuleViolation(NetworkMessage& msg); void parseCloseRuleViolation(NetworkMessage& msg); void parseCancelRuleViolation(NetworkMessage& msg); //Send functions void sendChannelMessage(std::string author, std::string text, SpeakClasses type, uint8_t channel); void sendClosePrivate(uint16_t channelId); void sendCreatePrivateChannel(uint16_t channelId, const std::string& channelName); void sendChannelsDialog(); void sendChannel(uint16_t channelId, const std::string& channelName); void sendRuleViolationsChannel(uint16_t channelId); void sendOpenPrivateChannel(const std::string& receiver); void sendToChannel(const Creature* creature, SpeakClasses type, const std::string& text, uint16_t channelId, uint32_t time = 0); void sendRemoveReport(const std::string& name); void sendLockRuleViolation(); void sendRuleViolationCancel(const std::string& name); void sendIcons(int32_t icons); void sendFYIBox(const std::string& message); void sendDistanceShoot(const Position& from, const Position& to, uint8_t type); void sendMagicEffect(const Position& pos, uint8_t type); void sendAnimatedText(const Position& pos, uint8_t color, std::string text); void sendCreatureHealth(const Creature* creature); void sendSkills(); void sendPing(); void sendCreatureTurn(const Creature* creature, int16_t stackpos); void sendCreatureSay(const Creature* creature, SpeakClasses type, const std::string& text, Position* pos = NULL); void sendCancel(const std::string& message); void sendCancelWalk(); void sendChangeSpeed(const Creature* creature, uint32_t speed); void sendCancelTarget(); void sendCreatureOutfit(const Creature* creature, const Outfit_t& outfit); void sendStats(); void sendTextMessage(MessageClasses mclass, const std::string& message); void sendReLoginWindow(); void sendTutorial(uint8_t tutorialId); void sendAddMarker(const Position& pos, MapMarks_t markType, const std::string& desc); void sendCreatureSkull(const Creature* creature); void sendCreatureShield(const Creature* creature); void sendCreatureEmblem(const Creature* creature); void sendShop(const ShopInfoList& shop); void sendCloseShop(); void sendGoods(const ShopInfoList& shop); void sendTradeItemRequest(const Player* player, const Item* item, bool ack); void sendCloseTrade(); void sendTextWindow(uint32_t windowTextId, Item* item, uint16_t maxLen, bool canWrite); void sendTextWindow(uint32_t windowTextId, uint32_t itemId, const std::string& text); void sendHouseWindow(uint32_t windowTextId, House* house, uint32_t listId, const std::string& text); void sendOutfitWindow(); void sendQuests(); void sendQuestInfo(Quest* quest); void sendVIPLogIn(uint32_t guid); void sendVIPLogOut(uint32_t guid); void sendVIP(uint32_t guid, const std::string& name, bool isOnline); void sendCreatureLight(const Creature* creature); void sendWorldLight(const LightInfo& lightInfo); void sendCreatureSquare(const Creature* creature, SquareColor_t color); //tiles void sendAddTileItem(const Tile* tile, const Position& pos, uint32_t stackpos, const Item* item); void sendUpdateTileItem(const Tile* tile, const Position& pos, uint32_t stackpos, const Item* item); void sendRemoveTileItem(const Tile* tile, const Position& pos, uint32_t stackpos); void sendUpdateTile(const Tile* tile, const Position& pos); void sendAddCreature(const Creature* creature, const Position& pos, uint32_t stackpos); void sendRemoveCreature(const Creature* creature, const Position& pos, uint32_t stackpos); void sendMoveCreature(const Creature* creature, const Tile* newTile, const Position& newPos, uint32_t newStackPos, const Tile* oldTile, const Position& oldPos, uint32_t oldStackpos, bool teleport); //containers void sendAddContainerItem(uint8_t cid, const Item* item); void sendUpdateContainerItem(uint8_t cid, uint8_t slot, const Item* item); void sendRemoveContainerItem(uint8_t cid, uint8_t slot); void sendContainer(uint32_t cid, const Container* container, bool hasParent); void sendCloseContainer(uint32_t cid); //inventory void sendAddInventoryItem(slots_t slot, const Item* item); void sendUpdateInventoryItem(slots_t slot, const Item* item); void sendRemoveInventoryItem(slots_t slot); //Help functions // translate a tile to clientreadable format void GetTileDescription(const Tile* tile, NetworkMessage_ptr msg); // translate a floor to clientreadable format void GetFloorDescription(NetworkMessage_ptr msg, int32_t x, int32_t y, int32_t z, int32_t width, int32_t height, int32_t offset, int32_t& skip); // translate a map area to clientreadable format void GetMapDescription(int32_t x, int32_t y, int32_t z, int32_t width, int32_t height, NetworkMessage_ptr msg); void AddMapDescription(NetworkMessage_ptr msg, const Position& pos); void AddTextMessage(NetworkMessage_ptr msg, MessageClasses mclass, const std::string& message); void AddAnimatedText(NetworkMessage_ptr msg, const Position& pos, uint8_t color, const std::string& text); void AddMagicEffect(NetworkMessage_ptr msg, const Position& pos, uint8_t type); void AddDistanceShoot(NetworkMessage_ptr msg, const Position& from, const Position& to, uint8_t type); void AddCreature(NetworkMessage_ptr msg, const Creature* creature, bool known, uint32_t remove); void AddPlayerStats(NetworkMessage_ptr msg); void AddCreatureSpeak(NetworkMessage_ptr msg, const Creature* creature, SpeakClasses type, std::string text, uint16_t channelId, uint32_t time = 0, Position* pos = NULL); void AddCreatureHealth(NetworkMessage_ptr msg, const Creature* creature); void AddCreatureOutfit(NetworkMessage_ptr msg, const Creature* creature, const Outfit_t& outfit, bool outfitWindow = false); void AddPlayerSkills(NetworkMessage_ptr msg); void AddWorldLight(NetworkMessage_ptr msg, const LightInfo& lightInfo); void AddCreatureLight(NetworkMessage_ptr msg, const Creature* creature); //tiles void AddTileItem(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos, const Item* item); void AddTileCreature(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos, const Creature* creature); void UpdateTileItem(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos, const Item* item); void RemoveTileItem(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos); void MoveUpCreature(NetworkMessage_ptr msg, const Creature* creature, const Position& newPos, const Position& oldPos, uint32_t oldStackpos); void MoveDownCreature(NetworkMessage_ptr msg, const Creature* creature, const Position& newPos, const Position& oldPos, uint32_t oldStackpos); //container void AddContainerItem(NetworkMessage_ptr msg, uint8_t cid, const Item* item); void UpdateContainerItem(NetworkMessage_ptr msg, uint8_t cid, uint8_t slot, const Item* item); void RemoveContainerItem(NetworkMessage_ptr msg, uint8_t cid, uint8_t slot); //inventory void AddInventoryItem(NetworkMessage_ptr msg, slots_t slot, const Item* item); void UpdateInventoryItem(NetworkMessage_ptr msg, slots_t slot, const Item* item); void RemoveInventoryItem(NetworkMessage_ptr msg, slots_t slot); //rule violation window void parseViolationWindow(NetworkMessage& msg); //shop void AddShopItem(NetworkMessage_ptr msg, const ShopInfo item); bool receivePacket(LaspPacket_t packet, uint32_t exhaust) { uint64_t currentTime = OTSYS_TIME(); if(lastPacket[packet] > currentTime) return false; lastPacket[packet] = currentTime+exhaust; return true; } #define addGameTask(f, ...) addGameTaskInternal(0, boost::bind(f, &g_game, __VA_ARGS__)) #define addGameTaskTimed(delay, f, ...) addGameTaskInternal(delay, boost::bind(f, &g_game, __VA_ARGS__)) template void addGameTaskInternal(uint32_t delay, const FunctionType&, taskFlags_t flags = TASK_NONE); friend class Player; Player* player; uint32_t m_eventConnect; bool m_debugAssertSent, m_acceptPackets; uint64_t lastPacket[PACKET_LAST]; }; #endif