void ProtocolGame::parseOutfitWindow(InputMessage& msg) { Outfit outfit = internalGetOutfit(msg); typedef std::tuple<int, std::string, int> OutfitInfo; std::vector<OutfitInfo> outfitList; uint8 outfitCount = msg.getU8(); for(int i = 0; i < outfitCount; i++) { uint16 outfitId = msg.getU16(); std::string outfitName = msg.getString(); uint8 outfitAddons = msg.getU8(); outfitList.push_back(OutfitInfo(outfitId, outfitName, outfitAddons)); } CreaturePtr creature = CreaturePtr(new Creature); creature->setXPattern(2); creature->setOutfit(outfit); g_lua.callGlobalField("Game", "onOpenOutfitWindow", creature, outfitList); }
void ProtocolGame::parseClosePrivateChannel(InputMessage& msg) { msg.getU16(); // channel id }
void ProtocolGame::parseCreatePrivateChannel(InputMessage& msg) { msg.getU16(); // channel id msg.getString(); // channel name }
void ProtocolGame::parsePlayerIcons(InputMessage& msg) { int icons = msg.getU16(); m_localPlayer->setIcons((Otc::PlayerIcons)icons); }
void ProtocolGame::parsePlayerStats(InputMessage& msg) { double health = msg.getU16(); double maxHealth = msg.getU16(); double freeCapacity = msg.getU32() / 100.0; double experience = msg.getU32(); double level = msg.getU16(); double levelPercent = msg.getU8(); double mana = msg.getU16(); double maxMana = msg.getU16(); double magicLevel = msg.getU8(); double magicLevelPercent = msg.getU8(); double soul = msg.getU8(); double stamina = msg.getU16(); //TODO: move to game if(m_localPlayer->getStatistic(Otc::Health) != health || m_localPlayer->getStatistic(Otc::MaxHealth) != maxHealth) { m_localPlayer->setStatistic(Otc::Health, health); m_localPlayer->setStatistic(Otc::MaxHealth, maxHealth); g_lua.callGlobalField("Game", "onHealthChange", health, maxHealth); } if(m_localPlayer->getStatistic(Otc::FreeCapacity) != freeCapacity) { m_localPlayer->setStatistic(Otc::FreeCapacity, freeCapacity); g_lua.callGlobalField("Game", "onFreeCapacityChange", freeCapacity); } if(m_localPlayer->getStatistic(Otc::Experience) != experience) { m_localPlayer->setStatistic(Otc::Experience, experience); g_lua.callGlobalField("Game", "onExperienceChange", experience); } if(m_localPlayer->getStatistic(Otc::Level) != level || m_localPlayer->getStatistic(Otc::LevelPercent) != levelPercent) { m_localPlayer->setStatistic(Otc::Level, level); m_localPlayer->setStatistic(Otc::LevelPercent, levelPercent); g_lua.callGlobalField("Game", "onLevelChange", level, levelPercent); } if(m_localPlayer->getStatistic(Otc::Mana) != mana || m_localPlayer->getStatistic(Otc::MaxMana) != maxMana) { m_localPlayer->setStatistic(Otc::Mana, mana); m_localPlayer->setStatistic(Otc::MaxMana, maxMana); g_lua.callGlobalField("Game", "onManaChange", mana, maxMana); } if(m_localPlayer->getStatistic(Otc::MagicLevel) != magicLevel || m_localPlayer->getStatistic(Otc::MagicLevelPercent) != magicLevelPercent) { m_localPlayer->setStatistic(Otc::MagicLevel, magicLevel); m_localPlayer->setStatistic(Otc::MagicLevelPercent, magicLevelPercent); g_lua.callGlobalField("Game", "onMagicLevelChange", magicLevel, magicLevelPercent); } if(m_localPlayer->getStatistic(Otc::Soul) != soul) { m_localPlayer->setStatistic(Otc::Soul, soul); g_lua.callGlobalField("Game", "onSoulChange", soul); } if(m_localPlayer->getStatistic(Otc::Stamina) != stamina) { m_localPlayer->setStatistic(Otc::Stamina, stamina); g_lua.callGlobalField("Game", "onStaminaChange", stamina); } }
void ProtocolGame::parseMessage(InputMessage& msg) { try { while(!msg.eof()) { int opt = msg.getU8(); switch(opt) { case Proto::GameServerInitGame: parsePlayerLogin(msg); break; case Proto::GameServerGMActions: parseGMActions(msg); break; case Proto::GameServerLoginError: parseLoginError(msg); break; case Proto::GameServerLoginAdvice: parseFYIMessage(msg); break; case Proto::GameServerLoginWait: parseWaitList(msg); break; case Proto::GameServerPing: parsePing(msg); break; //case Proto::GameServerChallange: case Proto::GameServerDead: parseDeath(msg); break; case Proto::GameServerFullMap: parseMapDescription(msg); break; case Proto::GameServerMapTopRow: parseMoveNorth(msg); break; case Proto::GameServerMapRightRow: parseMoveEast(msg); break; case Proto::GameServerMapBottomRow: parseMoveSouth(msg); break; case Proto::GameServerMapLeftRow: parseMoveWest(msg); break; case Proto::GameServerTileData: parseUpdateTile(msg); break; case Proto::GameServerCreateOnMap: parseTileAddThing(msg); break; case Proto::GameServerChangeOnMap: parseTileTransformThing(msg); break; case Proto::GameServerDeleteOnMap: parseTileRemoveThing(msg); break; case Proto::GameServerMoveCreature: parseCreatureMove(msg); break; case Proto::GameServerOpenContainer: parseOpenContainer(msg); break; case Proto::GameServerCloseContainer: parseCloseContainer(msg); break; case Proto::GameServerCreateContainer: parseContainerAddItem(msg); break; case Proto::GameServerChangeInContainer: parseContainerUpdateItem(msg); break; case Proto::GameServerDeleteInContainer: parseContainerRemoveItem(msg); break; case Proto::GameServerSetInventory: parseAddInventoryItem(msg); break; case Proto::GameServerDeleteInventory: parseRemoveInventoryItem(msg); break; case Proto::GameServerNpcOffer: parseOpenShopWindow(msg); break; case Proto::GameServerPlayerGoods: parsePlayerCash(msg); break; case Proto::GameServerCloseNpcTrade: parseCloseShopWindow(msg); break; case Proto::GameServerOwnOffer: parseSafeTradeRequest(msg); break; case Proto::GameServerCounterOffer: parseSafeTradeRequest(msg); break; case Proto::GameServerCloseTrade: parseSafeTradeClose(msg); break; case Proto::GameServerAmbient: parseWorldLight(msg); break; case Proto::GameServerGraphicalEffect: parseMagicEffect(msg); break; case Proto::GameServerTextEffect: parseAnimatedText(msg); break; case Proto::GameServerMissleEffect: parseDistanceMissile(msg); break; case Proto::GameServerMarkCreature: parseCreatureSquare(msg); break; //case Proto::GameServerTrappers case Proto::GameServerCreatureHealth: parseCreatureHealth(msg); break; case Proto::GameServerCreatureLight: parseCreatureLight(msg); break; case Proto::GameServerCreatureOutfit: parseCreatureOutfit(msg); break; case Proto::GameServerCreatureSpeed: parseCreatureSpeed(msg); break; case Proto::GameServerCreatureSkull: parseCreatureSkulls(msg); break; case Proto::GameServerCreatureParty: parseCreatureShields(msg); break; // case Proto::GameServerCreatureUnpass case Proto::GameServerEditText: parseItemTextWindow(msg); break; case Proto::GameServerEditList: parseHouseTextWindow(msg); break; case Proto::GameServerPlayerData: parsePlayerStats(msg); break; case Proto::GameServerPlayerSkills: parsePlayerSkills(msg); break; case Proto::GameServerPlayerState: parsePlayerIcons(msg); break; case Proto::GameServerClearTarget: parsePlayerCancelAttack(msg); break; //case Proto::GameServerSpellDelay: //case Proto::GameServerSpellGroupDelay: case Proto::GameServerTalk: parseCreatureSpeak(msg); break; case Proto::GameServerChannels: parseChannelList(msg); break; case Proto::GameServerOpenChannel: parseOpenChannel(msg); break; case Proto::GameServerPrivateChannel: parseOpenPrivatePlayerChat(msg); break; case Proto::GameServerRuleViolationChannel: msg.getU16(); break; case Proto::GameServerRuleViolationRemove: msg.getString(); break; case Proto::GameServerRuleViolationCancel: msg.getString(); break; case Proto::GameServerRuleViolationLock: break; case Proto::GameServerOpenOwnChannel: parseCreatePrivateChannel(msg); break; case Proto::GameServerCloseChannel: parseClosePrivateChannel(msg); break; case Proto::GameServerMessage: parseTextMessage(msg); break; case Proto::GameServerSnapBack: parseCancelWalk(msg); break; //case Proto::GameServerWait: case Proto::GameServerTopFloor: parseFloorChangeUp(msg); break; case Proto::GameServerBottomFloor: parseFloorChangeDown(msg); break; case Proto::GameServerOutfit: parseOutfitWindow(msg); break; case Proto::GameServerBuddyData: parseVipState(msg); break; case Proto::GameServerBuddyLogin: parseVipLogin(msg); break; case Proto::GameServerBuddyLogout: parseVipLogout(msg); break; case Proto::GameServerTutorialHint: parseShowTutorial(msg); break; case Proto::GameServerAutomapFlag: parseAddMarker(msg); break; case Proto::GameServerQuestLog: parseQuestList(msg); break; case Proto::GameServerQuestLine: parseQuestPartList(msg); break; //case Proto::GameServerChannelEvent: //case Proto::GameServerObjectInfo: //case Proto::GameServerPlayerInventory: default: Fw::throwException("unknown opt byte ", (int)opt); break; } } } catch(Exception& e) { logTraceError(e.what()); } }
ThingPtr ProtocolGame::internalGetThing(InputMessage& msg) { ThingPtr thing; int thingId = msg.getU16(); assert(thingId != 0); if(thingId == 0x0061 || thingId == 0x0062) { // add new creature CreaturePtr creature; if(thingId == 0x0062) { //creature is known uint id = msg.getU32(); CreaturePtr knownCreature = g_map.getCreatureById(id); if(knownCreature) creature = knownCreature; else logTraceError("server says creature is known, but its not on creatures list"); } else if(thingId == 0x0061) { //creature is not known uint removeId = msg.getU32(); uint id = msg.getU32(); std::string name = msg.getString(); if(name.length() > 0) // every creature name must start with a capital letter name[0] = toupper(name[0]); g_map.removeCreatureById(removeId); if(id == m_localPlayer->getId()) creature = m_localPlayer; else if(id >= Proto::PlayerStartId && id < Proto::PlayerEndId) creature = PlayerPtr(new Player); else if(id >= Proto::MonsterStartId && id < Proto::MonsterEndId) creature = MonsterPtr(new Monster); else if(id >= Proto::NpcStartId && id < Proto::NpcEndId) creature = NpcPtr(new Npc); else logTraceError("creature id is invalid"); creature->setId(id); creature->setName(name); } uint8 healthPercent = msg.getU8(); Otc::Direction direction = (Otc::Direction)msg.getU8(); Outfit outfit = internalGetOutfit(msg); Light light; light.intensity = msg.getU8(); light.color = msg.getU8(); int speed = msg.getU16(); int skull = msg.getU8(); int shield = msg.getU8(); int emblem = -1; if(thingId == 0x0061) // emblem is sent only in packet type 0x61 emblem = msg.getU8(); bool passable = (msg.getU8() == 0); if(creature) { creature->setHealthPercent(healthPercent); creature->setDirection(direction); creature->setOutfit(outfit); creature->setLight(light); creature->setSpeed(speed); creature->setSkull(skull); creature->setShield(shield); if(emblem != -1) creature->setEmblem(emblem); creature->setPassable(passable); creature->setDirection(direction); if(creature == m_localPlayer) { m_localPlayer->setKnown(true); } } thing = creature; } else if(thingId == 0x0063) { // creature turn parseCreatureTurn(msg); } else // item thing = internalGetItem(msg, thingId); return thing; }