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

[Feature/Enhancement] - No disconnect on death #147

Merged
merged 55 commits into from
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
205df46
Update iologindata.cpp
omeranha Oct 17, 2021
0b2479c
Revert "Update iologindata.cpp"
omeranha Oct 17, 2021
7c64a1b
Fix sonar warning
Costallat Oct 18, 2021
dfb3182
no disconnect on death first!
omeranha Oct 19, 2021
32b45e3
Update src/creatures/players/player.cpp
omeranha Oct 23, 2021
41b77b7
Update src/creatures/players/player.cpp
omeranha Oct 23, 2021
2ac71b3
Update src/creatures/players/player.cpp
omeranha Oct 23, 2021
d0b3c5c
Update src/creatures/players/player.cpp
omeranha Oct 23, 2021
0738c02
Update src/creatures/players/player.cpp
omeranha Oct 23, 2021
435d385
Update src/server/network/protocol/protocolgame.cpp
omeranha Oct 23, 2021
27d72d2
Update src/creatures/players/player.cpp
omeranha Oct 23, 2021
6a415af
Merge branch 'master' into omeranha-no-disconnect-on-death
omeranha Oct 23, 2021
b50f187
Merge branch 'master' into omeranha-no-disconnect-on-death
beats-dh Oct 28, 2021
5043c09
Merge branch 'master' into omeranha-no-disconnect-on-death
dudantas Nov 3, 2021
4339a29
Merge branch 'opentibiabr:master' into master
omeranha Nov 4, 2021
bce6a54
Merge branch 'opentibiabr:master' into master
omeranha Nov 26, 2021
6a1e386
Merge branch 'opentibiabr:master' into master
omeranha Dec 7, 2021
c9df206
Merge branch 'opentibiabr:master' into master
omeranha Dec 11, 2021
c503ceb
Merge branch 'opentibiabr:master' into master
omeranha Dec 16, 2021
f60c4fa
Merge branch 'opentibiabr:master' into master
omeranha Jan 3, 2022
216efd2
Merge branch 'opentibiabr:master' into master
omeranha Jan 8, 2022
be7d207
Merge branch 'opentibiabr:master' into master
omeranha Jan 11, 2022
e7268be
Merge branch 'master' into pr/147
dudantas Jan 27, 2022
9904f1e
Fix sonar bug
dudantas Jan 28, 2022
a2304b5
sonar issues
omeranha Jan 31, 2022
a884ee4
sonar fixes
omeranha Jan 31, 2022
affeb41
Merge branch 'opentibiabr:master' into master
omeranha Feb 4, 2022
68815f1
Merge branch 'opentibiabr:master' into master
omeranha Feb 7, 2022
3c89e1a
Merge branch 'opentibiabr:master' into master
omeranha Feb 9, 2022
11923f7
Merge branch 'master' into omeranha-no-disconnect-on-death
omeranha Feb 11, 2022
6ffbcc3
Merge branch 'opentibiabr:master' into master
omeranha Feb 12, 2022
05280dd
Merge branch 'opentibiabr:master' into master
omeranha Feb 14, 2022
4862c2f
Merge branch 'opentibiabr:master' into master
omeranha Feb 15, 2022
2084124
Merge branch 'opentibiabr:master' into master
omeranha Feb 16, 2022
8881c2a
Merge branch 'master' into omeranha-no-disconnect-on-death
omeranha Feb 16, 2022
1513f90
cleanup, party fix, no spam of logged in and logged out messages in c…
omeranha Feb 17, 2022
2af9d48
Fix sonar
beats-dh Feb 17, 2022
af2a9e1
refactor
omeranha Feb 19, 2022
e1d7652
Merge branch 'master' into pr/147
omeranha Feb 26, 2022
7b522b0
should fix connection lost message after some seconds in "you are dea…
omeranha Feb 26, 2022
6ddd86a
not needed
omeranha Feb 26, 2022
c5900bb
Merge branch 'master' into pr/147
omeranha Feb 28, 2022
79392db
Merge branch 'master' into pr/147
omeranha Mar 1, 2022
0362920
player death messages, test commit :)
omeranha Mar 3, 2022
eb709b1
Merge branch 'master' into pr/147
omeranha Mar 10, 2022
cafb13d
Merge branch 'master' into pr/147
omeranha Mar 11, 2022
584cdc5
Update player_death.lua
omeranha Mar 11, 2022
cc8e931
should fix cancel crash message
omeranha Mar 12, 2022
57e8b91
fix guild crash + nil blesses
omeranha Mar 12, 2022
a13afdd
Merge branch 'master' into pr/147
omeranha Mar 12, 2022
8f0327b
blessings messages in cpp, remove lua code
omeranha Mar 13, 2022
8ff5e1a
sonar and removing nil stamina
omeranha Mar 13, 2022
cc37d6d
refactor², fix chats not working and party invitations cleaning when …
omeranha Mar 14, 2022
fccd02b
whitespace
omeranha Mar 14, 2022
5ef0856
Merge branch 'master' into pr/147
omeranha Mar 21, 2022
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
8 changes: 1 addition & 7 deletions data/scripts/creaturescripts/player_death.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ local deathListEnabled = true
local maxDeathRecords = 5

function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified)
local playerId = player:getId()
if nextUseStaminaTime[playerId] then
nextUseStaminaTime[playerId] = nil
end

player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead.")
if not deathListEnabled then
return
end
Expand Down Expand Up @@ -74,7 +68,7 @@ function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustifi
if targetGuild ~= 0 then
local killerGuild = killer:getGuild()
killerGuild = killerGuild and killerGuild:getId() or 0
if killerGuild ~= 0 and targetGuild ~= killerGuild and isInWar(playerId, killer:getId()) then
if killerGuild ~= 0 and targetGuild ~= killerGuild and isInWar(player:getId(), killer:getId()) then
local warId = false
resultId = db.storeQuery("SELECT `id` FROM `guild_wars` WHERE `status` = 1 AND ((`guild1` = " .. killerGuild .. " AND `guild2` = " .. targetGuild .. ") OR (`guild1` = " .. targetGuild .. " AND `guild2` = " .. killerGuild .. "))")
if resultId ~= false then
Expand Down
8 changes: 4 additions & 4 deletions src/creatures/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,12 +679,12 @@ void Creature::onDeath()
bool droppedCorpse = dropCorpse(lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
death(lastHitCreature);

if (master) {
setMaster(nullptr);
if (droppedCorpse && !getPlayer()) {
g_game.removeCreature(this, false);
}

if (droppedCorpse) {
g_game.removeCreature(this, false);
if (master) {
removeMaster();
}
}

Expand Down
175 changes: 162 additions & 13 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,9 @@ void Player::onCreatureAppear(Creature* creature, bool isLogin)
bed->wakeUp(this);
}

SPDLOG_INFO("{} has logged in", name);
if (isLogin) {
SPDLOG_INFO("{} has logged in", name);
}

if (guild) {
guild->addMember(this);
Expand Down Expand Up @@ -1598,6 +1600,9 @@ void Player::onRemoveCreature(Creature* creature, bool isLogout)
if (creature == this) {
if (isLogout) {
loginPosition = getPosition();
SPDLOG_INFO("{} has logged out", getName());
g_chat->removeUserFromAllChannels(*this);
clearPartyInvitations();
}

lastLogout = time(nullptr);
Expand All @@ -1612,17 +1617,11 @@ void Player::onRemoveCreature(Creature* creature, bool isLogout)

closeShopWindow();

clearPartyInvitations();

if (party) {
if (party && isLogout) {
party->leaveParty(this);
}

g_chat->removeUserFromAllChannels(*this);

SPDLOG_INFO("{} has logged out", getName());

if (guild) {
if (guild && isLogout) {
guild->removeMember(this);
}

Expand Down Expand Up @@ -2492,7 +2491,7 @@ void Player::death(Creature* lastHitCreature)
if (charmRuneBless != 0) {
MonsterType* mType = g_monsters.getMonsterType(lastHitCreature->getName());
if (mType && mType->info.raceid == charmRuneBless) {
deathLossPercent = (deathLossPercent * 90) / 100;
deathLossPercent = (deathLossPercent * 90) / 100;
}
}
}
Expand All @@ -2514,6 +2513,14 @@ void Player::death(Creature* lastHitCreature)
magLevelPercent = 0;
}

//Level loss
uint64_t expLoss = static_cast<uint64_t>(experience * deathLossPercent);
g_events->eventPlayerOnLoseExperience(this, expLoss);

sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead.");
std::ostringstream lostExp;
lostExp << "You lost " << expLoss << " experience.";

//Skill loss
for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { //for each skill
uint64_t sumSkillTries = 0;
Expand Down Expand Up @@ -2542,9 +2549,7 @@ void Player::death(Creature* lastHitCreature)
skills[i].percent = Player::getPercentLevel(skills[i].tries, vocation->getReqSkillTries(i, skills[i].level));
}

//Level loss
uint64_t expLoss = static_cast<uint64_t>(experience * deathLossPercent);
g_events->eventPlayerOnLoseExperience(this, expLoss);
sendTextMessage(MESSAGE_EVENT_ADVANCE, lostExp.str());

if (expLoss != 0) {
uint32_t oldLevel = level;
Expand Down Expand Up @@ -2575,6 +2580,24 @@ void Player::death(Creature* lastHitCreature)
}
}

std::ostringstream deathType;
deathType << "You died during ";
if (pvpDeath) {
deathType << "PvP.";
} else {
deathType << "PvE.";
}
sendTextMessage(MESSAGE_EVENT_ADVANCE, deathType.str());

std::string bless = getBlessingsName();
std::ostringstream blesses;
if (bless.length() == 0) {
blesses << "You weren't protected with any blessings.";
} else {
blesses << "You were blessed with " << bless;
}
sendTextMessage(MESSAGE_EVENT_ADVANCE, blesses.str());

//Make player lose bless
uint8_t maxBlessing = 8;
if (pvpDeath && hasBlessing(1)) {
Expand All @@ -2585,6 +2608,14 @@ void Player::death(Creature* lastHitCreature)
}
}

std::ostringstream lostBlesses;
if (bless.length() == 0) {
lostBlesses << "You lost all your blesses.";
} else {
lostBlesses << "You are still blessed with " << bless;
}
sendTextMessage(MESSAGE_EVENT_ADVANCE, lostBlesses.str());

sendStats();
sendSkills();
sendReLoginWindow(unfairFightReduction);
Expand Down Expand Up @@ -2635,6 +2666,91 @@ void Player::death(Creature* lastHitCreature)
onIdleStatus();
sendStats();
}
despawn();
}

bool Player::spawn()
{
setDead(false);

const Position& pos = getLoginPosition();

if (!g_game.map.placeCreature(pos, this, false, true)) {
return false;
}

SpectatorHashSet spectators;
g_game.map.getSpectators(spectators, position, false, true);
for (Creature* spectator : spectators) {
omeranha marked this conversation as resolved.
Show resolved Hide resolved
if (!spectator) {
continue;
}

if (Player* tmpPlayer = spectator->getPlayer()) {
tmpPlayer->sendCreatureAppear(this, pos, true);
}

spectator->onCreatureAppear(this, false);
}

getParent()->postAddNotification(this, nullptr, 0);
g_game.addCreatureCheck(this);

addList();
return true;
}

void Player::despawn()
{
if (isDead()) {
return;
}

listWalkDir.clear();
stopEventWalk();
onWalkAborted();

// remove check
Game::removeCreatureCheck(this);

// remove from map
Tile* tile = getTile();
omeranha marked this conversation as resolved.
Show resolved Hide resolved
if (!tile) {
return;
}

std::vector<int32_t> oldStackPosVector;

SpectatorHashSet spectators;
g_game.map.getSpectators(spectators, tile->getPosition(), true);
size_t i = 0;
for (Creature* spectator : spectators) {
omeranha marked this conversation as resolved.
Show resolved Hide resolved
if (!spectator) {
continue;
}

if (const Player* player = spectator->getPlayer()) {
oldStackPosVector.push_back(player->canSeeCreature(this) ? tile->getStackposOfCreature(player, this) : -1);
}
if (Player* player = spectator->getPlayer()) {
player->sendRemoveTileThing(tile->getPosition(), oldStackPosVector[i++]);
}

spectator->onRemoveCreature(this, false);
}

tile->removeCreature(this);

getParent()->postRemoveNotification(this, nullptr, 0);

g_game.removePlayer(this);

// show player as pending
for (const auto& [key, player] : g_game.getPlayers()) {
player->notifyStatusChange(this, VIPSTATUS_PENDING, false);
}

setDead(true);
}

bool Player::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified)
Expand Down Expand Up @@ -5658,6 +5774,39 @@ void Player::openPlayerContainers()
}
}

std::string Player::getBlessingsName() const
{
uint8_t count = 0;
std::for_each(blessings.begin(), blessings.end(), [&count](uint8_t amount) {
if (amount != 0) {
count++;
}
});

std::ostringstream os;
for (uint8_t i = 1; i <= 8; i++) {
if (hasBlessing(i)) {
if (auto blessName = BlessingNames.find(static_cast<Blessings_t>(i));
blessName != BlessingNames.end()) {
os << (*blessName).second;
} else {
continue;
}

--count;
if (count > 1) {
os << ", ";
} else if (count == 1) {
os << " and ";
} else {
os << ".";
}
}
}

return os.str();
}

/*******************************************************************************
* Interfaces
******************************************************************************/
Expand Down
11 changes: 11 additions & 0 deletions src/creatures/players/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ class Player final : public Creature, public Cylinder
uint8_t getBlessingCount(uint8_t index) const {
return blessings[index - 1];
}
std::string getBlessingsName() const;

bool isOffline() const {
return (getID() == 0);
Expand Down Expand Up @@ -1911,6 +1912,8 @@ class Player final : public Creature, public Cylinder
void setNextPotionActionTask(SchedulerTask* task);

void death(Creature* lastHitCreature) override;
bool spawn();
void despawn();
bool dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature,
bool lastHitUnjustified, bool mostDamageUnjustified) override;
Item* getCorpse(Creature* lastHitCreature, Creature* mostDamageCreature) override;
Expand Down Expand Up @@ -2155,6 +2158,7 @@ class Player final : public Creature, public Cylinder
bool marketMenu = false; // Menu option 'show in market'
bool exerciseTraining = false;
bool moved = false;
bool dead = false;

static uint32_t playerAutoID;

Expand Down Expand Up @@ -2193,6 +2197,13 @@ class Player final : public Creature, public Cylinder
uint16_t getLookCorpse() const override;
void getPathSearchParams(const Creature* creature, FindPathParams& fpp) const override;

void setDead(bool isDead) {
dead = isDead;
}
bool isDead() const {
return dead;
}

friend class Game;
friend class Npc;
friend class PlayerFunctions;
Expand Down
40 changes: 32 additions & 8 deletions src/server/network/protocol/protocolgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ void ProtocolGame::connect(uint32_t playerId, OperatingSystem_t operatingSystem)

player->client = getThis();
player->openPlayerContainers();
sendAddCreature(player, player->getPosition(), 0, false);
sendAddCreature(player, player->getPosition(), 0, true);
player->lastIP = player->getIP();
player->lastLoginSaved = std::max<time_t>(time(nullptr), player->lastLoginSaved + 1);
acceptPackets = true;
Expand Down Expand Up @@ -427,7 +427,7 @@ void ProtocolGame::logout(bool displayEffect, bool forced)

sendSessionEndInformation(forced ? SESSION_END_FORCECLOSE : SESSION_END_LOGOUT);

g_game.removeCreature(player);
g_game.removeCreature(player, true);
}

void ProtocolGame::onRecvFirstMessage(NetworkMessage &msg)
Expand Down Expand Up @@ -602,16 +602,40 @@ void ProtocolGame::parsePacket(NetworkMessage& msg)

uint8_t recvbyte = msg.getByte();

// A dead player can not perform actions
if (!player || player->isRemoved() || player->getHealth() <= 0) {
if (!player || player->isRemoved()) {
if (recvbyte == 0x0F) {
// we need to make the player pointer != null in this part, game.cpp release is the first step
// login(player->getName(), player->getAccount(), player->operatingSystem);
disconnect();
}

return;
}

//a dead player can not performs actions
if (player->isDead() || player->getHealth() <= 0) {
if (recvbyte == 0x14) {
disconnect();
return;
}

if (recvbyte == 0x0F) {
if (!player) {
return;
}

if (!player->spawn()) {
disconnect();
g_game.removeCreature(player);
return;
}

sendAddCreature(player, player->getPosition(), 0, false);
return;
}

if (recvbyte != 0x14) {
if (recvbyte != 0x1D && recvbyte != 0x1E) {
// keep the connection alive
g_scheduler.addEvent(createSchedulerTask(500, std::bind(&ProtocolGame::sendPing, getThis())));
g_scheduler.addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::sendPingBack, getThis())));
return;
}
}
Expand All @@ -621,7 +645,7 @@ void ProtocolGame::parsePacket(NetworkMessage& msg)
g_dispatcher.addTask(createTask(std::bind(&Modules::executeOnRecvbyte, g_modules, player->getID(), msg, recvbyte)));
}

g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::parsePacketFromDispatcher, getThis(), msg, recvbyte)));
g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::parsePacketFromDispatcher, getThis(), msg, recvbyte)));
}

void ProtocolGame::parsePacketFromDispatcher(NetworkMessage msg, uint8_t recvbyte)
Expand Down
Loading