Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support to protocol 13.40 #2802

Merged
merged 4 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static constexpr auto AUTHENTICATOR_PERIOD = 30U;
// SERVER_MAJOR_VERSION is the actual full version of the server, including minor and patch numbers.
// This is intended for internal use to identify the exact state of the server (release) software.
static constexpr auto SERVER_RELEASE_VERSION = "3.1.2";
static constexpr auto CLIENT_VERSION = 1332;
static constexpr auto CLIENT_VERSION = 1340;

#define CLIENT_VERSION_UPPER (CLIENT_VERSION / 100)
#define CLIENT_VERSION_LOWER (CLIENT_VERSION % 100)
28 changes: 12 additions & 16 deletions src/creatures/players/wheel/player_wheel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ void PlayerWheel::revealGem(WheelGemQuality_t quality) {
sendOpenWheelWindow(m_player.getID());
}

PlayerWheelGem PlayerWheel::getGem(uint8_t index) const {
PlayerWheelGem PlayerWheel::getGem(uint16_t index) const {
auto gems = getRevealedGems();
if (gems.size() <= index) {
g_logger().error("[{}] Player {} trying to get gem with index {} but has only {} gems", __FUNCTION__, m_player.getName(), index, gems.size());
Expand All @@ -907,9 +907,9 @@ PlayerWheelGem PlayerWheel::getGem(const std::string &uuid) const {
return gem;
}

uint8_t PlayerWheel::getGemIndex(const std::string &uuid) const {
uint16_t PlayerWheel::getGemIndex(const std::string &uuid) const {
auto gems = getRevealedGems();
for (uint8_t i = 0; i < gems.size(); ++i) {
for (uint16_t i = 0; i < gems.size(); ++i) {
if (gems[i].uuid == uuid) {
return i;
}
Expand All @@ -918,7 +918,7 @@ uint8_t PlayerWheel::getGemIndex(const std::string &uuid) const {
return 0xFF;
}

void PlayerWheel::destroyGem(uint8_t index) {
void PlayerWheel::destroyGem(uint16_t index) {
auto gem = getGem(index);
if (gem.locked) {
g_logger().error("[{}] Player {} trying to destroy locked gem with index {}", __FUNCTION__, m_player.getName(), index);
Expand All @@ -928,7 +928,7 @@ void PlayerWheel::destroyGem(uint8_t index) {
sendOpenWheelWindow(m_player.getID());
}

void PlayerWheel::switchGemDomain(uint8_t index) {
void PlayerWheel::switchGemDomain(uint16_t index) {
auto gem = getGem(index);
if (gem.locked) {
g_logger().error("[{}] Player {} trying to destroy locked gem with index {}", __FUNCTION__, m_player.getName(), index);
Expand All @@ -946,14 +946,14 @@ void PlayerWheel::switchGemDomain(uint8_t index) {
sendOpenWheelWindow(m_player.getID());
}

void PlayerWheel::toggleGemLock(uint8_t index) {
void PlayerWheel::toggleGemLock(uint16_t index) {
auto gem = getGem(index);
gem.locked = !gem.locked;
gem.save(gemsKV());
sendOpenWheelWindow(m_player.getID());
}

void PlayerWheel::setActiveGem(WheelGemAffinity_t affinity, uint8_t index) {
void PlayerWheel::setActiveGem(WheelGemAffinity_t affinity, uint16_t index) {
auto gem = getGem(index);
if (gem.uuid.empty()) {
g_logger().error("[{}] Failed to load gem with index {}", __FUNCTION__, index);
Expand All @@ -979,19 +979,15 @@ void PlayerWheel::addGems(NetworkMessage &msg) const {
for (const auto &gem : activeGems) {
auto index = getGemIndex(gem.uuid);
g_logger().debug("[{}] Adding active gem: {} with index {}", __FUNCTION__, gem.toString(), index);
msg.addByte(getGemIndex(gem.uuid));
msg.add<uint16_t>(getGemIndex(gem.uuid));
}

auto revealedGems = getRevealedGems();
if (revealedGems.size() > 225) {
g_logger().error("[{}] Player {} has more than 225 gems unlocked", __FUNCTION__, m_player.getName());
revealedGems.resize(225);
}
msg.addByte(revealedGems.size());
int index = 0;
msg.add<uint16_t>(revealedGems.size());
uint16_t index = 0;
for (const auto &gem : revealedGems) {
g_logger().debug("[{}] Adding revealed gem: {}", __FUNCTION__, gem.toString());
msg.addByte(index++);
msg.add<uint16_t>(index++);
msg.addByte(gem.locked);
msg.addByte(static_cast<uint8_t>(gem.affinity));
msg.addByte(static_cast<uint8_t>(gem.quality));
Expand Down Expand Up @@ -1161,7 +1157,7 @@ void PlayerWheel::saveSlotPointsOnPressSaveButton(NetworkMessage &msg) {
removeActiveGem(affinity);
continue;
}
uint8_t gemIndex = msg.getByte();
uint16_t gemIndex = msg.get<uint16_t>();
setActiveGem(affinity, gemIndex);
}

Expand Down
12 changes: 6 additions & 6 deletions src/creatures/players/wheel/player_wheel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,14 +386,14 @@ class PlayerWheel {
* @return The calculated mitigation value.
*/
float calculateMitigation() const;
PlayerWheelGem getGem(uint8_t index) const;
PlayerWheelGem getGem(uint16_t index) const;
PlayerWheelGem getGem(const std::string &uuid) const;
uint8_t getGemIndex(const std::string &uuid) const;
uint16_t getGemIndex(const std::string &uuid) const;
void revealGem(WheelGemQuality_t quality);
void destroyGem(uint8_t index);
void switchGemDomain(uint8_t index);
void toggleGemLock(uint8_t index);
void setActiveGem(WheelGemAffinity_t affinity, uint8_t index);
void destroyGem(uint16_t index);
void switchGemDomain(uint16_t index);
void toggleGemLock(uint16_t index);
void setActiveGem(WheelGemAffinity_t affinity, uint16_t index);
void removeActiveGem(WheelGemAffinity_t affinity);
void addRevelationBonus(WheelGemAffinity_t affinity, uint16_t points) {
m_bonusRevelationPoints[static_cast<size_t>(affinity)] += points;
Expand Down
74 changes: 62 additions & 12 deletions src/server/network/protocol/protocolgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,7 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage &msg) {

OperatingSystem_t operatingSystem = static_cast<OperatingSystem_t>(msg.get<uint16_t>());
version = msg.get<uint16_t>(); // Protocol version
g_logger().trace("Protocol version: {}", version);

// Old protocol support
oldProtocol = g_configManager().getBoolean(OLD_PROTOCOL, __FUNCTION__) && version <= 1100;
Expand All @@ -721,10 +722,21 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage &msg) {
clientVersion = static_cast<int32_t>(msg.get<uint32_t>());

if (!oldProtocol) {
msg.getString(); // Client version (String)
auto clientVersionString = msg.getString(); // Client version (String)
g_logger().trace("Client version: {}", clientVersionString);
if (version >= 1334) {
auto assetHashIdentifier = msg.getString(); // Assets hash identifier
g_logger().trace("Client asset hash identifier: {}", assetHashIdentifier);
}
}

if (version < 1334) {
auto datRevision = msg.get<uint16_t>(); // Dat revision
g_logger().trace("Dat revision: {}", datRevision);
}

msg.skipBytes(3); // U16 dat revision, U8 game preview state
auto gamePreviewState = msg.getByte(); // U8 game preview state
g_logger().trace("Game preview state: {}", gamePreviewState);

if (!Protocol::RSA_decrypt(msg)) {
g_logger().warn("[ProtocolGame::onRecvFirstMessage] - RSA Decrypt Failed");
Expand All @@ -736,7 +748,8 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage &msg) {
enableXTEAEncryption();
setXTEAKey(key.data());

msg.skipBytes(1); // gamemaster flag
auto isGameMaster = static_cast<bool>(msg.getByte()); // gamemaster flag
g_logger().trace("Is Game Master: {}", isGameMaster);

std::string authType = g_configManager().getString(AUTH_TYPE, __FUNCTION__);
std::ostringstream ss;
Expand Down Expand Up @@ -1668,8 +1681,11 @@ void ProtocolGame::parseSetOutfit(NetworkMessage &msg) {
newOutfit.lookMountBody = std::min<uint8_t>(132, msg.getByte());
newOutfit.lookMountLegs = std::min<uint8_t>(132, msg.getByte());
newOutfit.lookMountFeet = std::min<uint8_t>(132, msg.getByte());
bool isMounted = msg.getByte();
newOutfit.lookFamiliarsType = msg.get<uint16_t>();
g_logger().debug("Bool isMounted: {}", isMounted);
}

uint8_t isMountRandomized = msg.getByte();
g_game().playerChangeOutfit(player->getID(), newOutfit, isMountRandomized);
} else if (outfitType == 1) {
Expand Down Expand Up @@ -1789,11 +1805,23 @@ void ProtocolGame::parseQuickLoot(NetworkMessage &msg) {
return;
}

Position pos = msg.getPosition();
uint16_t itemId = msg.get<uint16_t>();
uint8_t stackpos = msg.getByte();
bool lootAllCorpses = msg.getByte();
bool autoLoot = msg.getByte();
uint8_t variant = msg.getByte();
const Position pos = msg.getPosition();
uint16_t itemId = 0;
uint8_t stackpos = 0;
bool lootAllCorpses = true;
bool autoLoot = true;

if (variant == 2) {
// Loot player nearby (13.40)
} else {
itemId = msg.get<uint16_t>();
stackpos = msg.getByte();
lootAllCorpses = variant == 1;
autoLoot = false;
}
g_logger().debug("[{}] variant {}, pos {}, itemId {}, stackPos {}", __FUNCTION__, variant, pos.toString(), itemId, stackpos);

g_game().playerQuickLoot(player->getID(), pos, itemId, stackpos, nullptr, lootAllCorpses, autoLoot);
}

Expand Down Expand Up @@ -2348,6 +2376,10 @@ void ProtocolGame::parseBestiarysendMonsterData(NetworkMessage &msg) {
newmsg.addString(Class, "ProtocolGame::parseBestiarysendMonsterData - Class");

newmsg.addByte(currentLevel);

newmsg.add<uint16_t>(0); // Animus Mastery Bonus
newmsg.add<uint16_t>(0); // Animus Mastery Points

newmsg.add<uint32_t>(killCounter);

newmsg.add<uint16_t>(mtype->info.bestiaryFirstUnlock);
Expand Down Expand Up @@ -2980,7 +3012,12 @@ void ProtocolGame::parseBestiarysendCreatures(NetworkMessage &msg) {
} else {
newmsg.addByte(0);
}

newmsg.add<uint16_t>(0); // Creature Animous Bonus
}

newmsg.add<uint16_t>(0); // Animus Mastery Points

writeToOutputBuffer(newmsg);
}

Expand Down Expand Up @@ -4665,6 +4702,19 @@ void ProtocolGame::sendContainer(uint8_t cid, std::shared_ptr<Container> contain
msg.addByte(0x00);
}

// New container menu options
if (container->isMovable()) { // Pickupable/Moveable (?)
msg.addByte(1);
} else {
msg.addByte(0);
}

if (container->getHoldingPlayer()) { // Player holding the item (?)
msg.addByte(1);
} else {
msg.addByte(0);
}

writeToOutputBuffer(msg);
}

Expand Down Expand Up @@ -4861,9 +4911,9 @@ void ProtocolGame::sendSaleItemList(const std::vector<ShopBlock> &shopVector, co
msg.add<uint64_t>(player->getMoney() + player->getBankBalance());
}

uint8_t itemsToSend = 0;
uint16_t itemsToSend = 0;
auto msgPosition = msg.getBufferPosition();
msg.skipBytes(1);
msg.skipBytes(2);

for (const ShopBlock &shopBlock : shopVector) {
if (shopBlock.itemSellPrice == 0) {
Expand All @@ -4878,14 +4928,14 @@ void ProtocolGame::sendSaleItemList(const std::vector<ShopBlock> &shopVector, co
} else {
msg.add<uint16_t>(std::min<uint16_t>(it->second, std::numeric_limits<uint16_t>::max()));
}
if (++itemsToSend >= 0xFF) {
if (++itemsToSend >= 0xFFFF) {
break;
}
}
}

msg.setBufferPosition(msgPosition);
msg.addByte(itemsToSend);
msg.add<uint16_t>(itemsToSend);
writeToOutputBuffer(msg);
}

Expand Down
Loading