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
Changes from 1 commit
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
Next Next commit
feat: support to protocol 13.40
Co-Authored-By: Marcos <[email protected]>
dudantas and marcosvf132 committed Aug 8, 2024
commit 0a95cf92cee71e446016a8b2f891d72ca24ad48c
2 changes: 1 addition & 1 deletion src/core.hpp
Original file line number Diff line number Diff line change
@@ -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
@@ -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());
@@ -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;
}
@@ -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);
@@ -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);
@@ -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);
@@ -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));
@@ -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);
}

12 changes: 6 additions & 6 deletions src/creatures/players/wheel/player_wheel.hpp
Original file line number Diff line number Diff line change
@@ -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;
79 changes: 67 additions & 12 deletions src/server/network/protocol/protocolgame.cpp
Original file line number Diff line number Diff line change
@@ -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;
@@ -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");
@@ -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;
@@ -1662,14 +1675,19 @@ void ProtocolGame::parseSetOutfit(NetworkMessage &msg) {
newOutfit.lookFeet = std::min<uint8_t>(132, msg.getByte());
newOutfit.lookAddons = msg.getByte();
if (outfitType == 0) {
bool isMounted = false;
newOutfit.lookMount = msg.get<uint16_t>();
if (!oldProtocol) {
newOutfit.lookMountHead = std::min<uint8_t>(132, msg.getByte());
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());
if (version >= 1334) {
isMounted = msg.getByte();
}
newOutfit.lookFamiliarsType = msg.get<uint16_t>();
}
g_logger().info("Bool isMounted: {}", isMounted);
uint8_t isMountRandomized = msg.getByte();
g_game().playerChangeOutfit(player->getID(), newOutfit, isMountRandomized);
} else if (outfitType == 1) {
@@ -1789,11 +1807,26 @@ 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 = 0;
if (version >= 1340) {
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_game().playerQuickLoot(player->getID(), pos, itemId, stackpos, nullptr, lootAllCorpses, autoLoot);
}

@@ -2348,6 +2381,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);
@@ -2980,7 +3017,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);
}

@@ -4665,6 +4707,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);
}

@@ -4861,9 +4916,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) {
@@ -4878,14 +4933,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);
}


Unchanged files with check annotations Beta

SpawnMonster &operator=(const SpawnMonster &) = delete;
// moveable
SpawnMonster(SpawnMonster &&rhs) noexcept :

Check warning on line 40 in src/creatures/monsters/spawns/spawn_monster.hpp

GitHub Actions / ubuntu-22.04-linux-debug

when initialized here [-Wreorder]

Check warning on line 40 in src/creatures/monsters/spawns/spawn_monster.hpp

GitHub Actions / ubuntu-22.04-linux-debug

when initialized here [-Wreorder]

Check warning on line 40 in src/creatures/monsters/spawns/spawn_monster.hpp

GitHub Actions / ubuntu-22.04-linux-debug

when initialized here [-Wreorder]
spawnMonsterMap(std::move(rhs.spawnMonsterMap)),
spawnedMonsterMap(std::move(rhs.spawnedMonsterMap)),
checkSpawnMonsterEvent(rhs.checkSpawnMonsterEvent), centerPos(rhs.centerPos), radius(rhs.radius), interval(rhs.interval) { }
private:
// map of the spawned creatures
std::map<uint32_t, std::shared_ptr<Monster>> spawnedMonsterMap;

Check warning on line 81 in src/creatures/monsters/spawns/spawn_monster.hpp

GitHub Actions / ubuntu-22.04-linux-debug

‘std::map<unsigned int, std::shared_ptr<Monster> > SpawnMonster::spawnedMonsterMap’ [-Wreorder]

Check warning on line 81 in src/creatures/monsters/spawns/spawn_monster.hpp

GitHub Actions / ubuntu-22.04-linux-debug

‘std::map<unsigned int, std::shared_ptr<Monster> > SpawnMonster::spawnedMonsterMap’ [-Wreorder]
// map of creatures in the spawn
std::map<uint32_t, spawnBlock_t> spawnMonsterMap;

Check warning on line 84 in src/creatures/monsters/spawns/spawn_monster.hpp

GitHub Actions / ubuntu-22.04-linux-debug

‘SpawnMonster::spawnMonsterMap’ will be initialized after [-Wreorder]

Check warning on line 84 in src/creatures/monsters/spawns/spawn_monster.hpp

GitHub Actions / ubuntu-22.04-linux-debug

‘SpawnMonster::spawnMonsterMap’ will be initialized after [-Wreorder]
Position centerPos;

Check warning on line 86 in src/creatures/monsters/spawns/spawn_monster.hpp

GitHub Actions / ubuntu-22.04-linux-debug

‘Position SpawnMonster::centerPos’ [-Wreorder]
int32_t radius;
uint32_t interval = 30000;
uint32_t checkSpawnMonsterEvent = 0;

Check warning on line 90 in src/creatures/monsters/spawns/spawn_monster.hpp

GitHub Actions / ubuntu-22.04-linux-debug

‘SpawnMonster::checkSpawnMonsterEvent’ will be initialized after [-Wreorder]

Check warning on line 90 in src/creatures/monsters/spawns/spawn_monster.hpp

GitHub Actions / ubuntu-22.04-linux-debug

‘SpawnMonster::checkSpawnMonsterEvent’ will be initialized after [-Wreorder]
static bool findPlayer(const Position &pos);
bool spawnMonster(uint32_t spawnMonsterId, spawnBlock_t &sb, std::shared_ptr<MonsterType> monsterType, bool startup = false);