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] Corpse Overhaul #3938

Merged
merged 24 commits into from
Feb 8, 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
1 change: 1 addition & 0 deletions common/database.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ class Database : public DBcore {
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids);
void PurgeExpiredInstances();
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
void CleanupInstanceCorpses();

/* Adventure related. */

Expand Down
14 changes: 14 additions & 0 deletions common/database/database_update_manifest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5270,6 +5270,20 @@ MODIFY COLUMN `level` tinyint(3) UNSIGNED NOT NULL FIRST,
MODIFY COLUMN `class` tinyint(2) UNSIGNED NOT NULL AFTER `level`;
)",
.content_schema_update = true
},
ManifestEntry{
.version = 9259,
.description = "2024_01_13_corpse_rez_overhaul.sql",
.check = "SHOW COLUMNS FROM `character_corpses` LIKE 'rez_time'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `character_corpses`
ADD COLUMN `rez_time` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `wc_9`,
ADD COLUMN `gm_exp` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `rez_time`,
ADD COLUMN `killed_by` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `gm_exp`,
ADD COLUMN `rezzable` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `killed_by`;
)"
}
// -- template; copy/paste this when you need to create a new entry
// ManifestEntry{
Expand Down
20 changes: 20 additions & 0 deletions common/database_instances.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,3 +570,23 @@ void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)

InstanceListRepository::UpdateOne(*this, i);
}

void Database::CleanupInstanceCorpses() {
auto l = InstanceListRepository::GetWhere(
*this,
"never_expires = 0"
);

if (l.empty()) {
return;
}

std::vector<std::string> instance_ids;
for (const auto& e : l) {
instance_ids.emplace_back(std::to_string(e.id));
}

const auto imploded_instance_ids = Strings::Implode(",", instance_ids);

CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
}
2 changes: 2 additions & 0 deletions common/eqemu_logsys.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ namespace Logs {
DataBuckets,
Zoning,
EqTime,
Corpses,
MaxCategoryID /* Don't Remove this */
};

Expand Down Expand Up @@ -239,6 +240,7 @@ namespace Logs {
"DataBuckets",
"Zoning",
"EqTime",
"Corpses",
};
}

Expand Down
10 changes: 10 additions & 0 deletions common/eqemu_logsys_log_aliases.h
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,16 @@
OutF(LogSys, Logs::Detail, Logs::EqTime, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)

#define LogCorpses(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::Corpses))\
OutF(LogSys, Logs::General, Logs::Corpses, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)

#define LogCorpsesDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Corpses))\
OutF(LogSys, Logs::Detail, Logs::Corpses, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)

#define Log(debug_level, log_category, message, ...) do {\
if (LogSys.IsLogEnabled(debug_level, log_category))\
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
Expand Down
48 changes: 48 additions & 0 deletions common/repositories/base/base_character_corpses_repository.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ class BaseCharacterCorpsesRepository {
uint32_t wc_7;
uint32_t wc_8;
uint32_t wc_9;
uint32_t rez_time;
uint32_t gm_exp;
uint32_t killed_by;
uint8_t rezzable;
};

static std::string PrimaryKey()
Expand Down Expand Up @@ -123,6 +127,10 @@ class BaseCharacterCorpsesRepository {
"wc_7",
"wc_8",
"wc_9",
"rez_time",
"gm_exp",
"killed_by",
"rezzable",
};
}

Expand Down Expand Up @@ -176,6 +184,10 @@ class BaseCharacterCorpsesRepository {
"wc_7",
"wc_8",
"wc_9",
"rez_time",
"gm_exp",
"killed_by",
"rezzable",
};
}

Expand Down Expand Up @@ -263,6 +275,10 @@ class BaseCharacterCorpsesRepository {
e.wc_7 = 0;
e.wc_8 = 0;
e.wc_9 = 0;
e.rez_time = 0;
e.gm_exp = 0;
e.killed_by = 0;
e.rezzable = 0;

return e;
}
Expand Down Expand Up @@ -346,6 +362,10 @@ class BaseCharacterCorpsesRepository {
e.wc_7 = row[44] ? static_cast<uint32_t>(strtoul(row[44], nullptr, 10)) : 0;
e.wc_8 = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 0;
e.wc_9 = row[46] ? static_cast<uint32_t>(strtoul(row[46], nullptr, 10)) : 0;
e.rez_time = row[47] ? static_cast<uint32_t>(strtoul(row[47], nullptr, 10)) : 0;
e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0;
e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0;
e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;

return e;
}
Expand Down Expand Up @@ -425,6 +445,10 @@ class BaseCharacterCorpsesRepository {
v.push_back(columns[44] + " = " + std::to_string(e.wc_7));
v.push_back(columns[45] + " = " + std::to_string(e.wc_8));
v.push_back(columns[46] + " = " + std::to_string(e.wc_9));
v.push_back(columns[47] + " = " + std::to_string(e.rez_time));
v.push_back(columns[48] + " = " + std::to_string(e.gm_exp));
v.push_back(columns[49] + " = " + std::to_string(e.killed_by));
v.push_back(columns[50] + " = " + std::to_string(e.rezzable));

auto results = db.QueryDatabase(
fmt::format(
Expand Down Expand Up @@ -493,6 +517,10 @@ class BaseCharacterCorpsesRepository {
v.push_back(std::to_string(e.wc_7));
v.push_back(std::to_string(e.wc_8));
v.push_back(std::to_string(e.wc_9));
v.push_back(std::to_string(e.rez_time));
v.push_back(std::to_string(e.gm_exp));
v.push_back(std::to_string(e.killed_by));
v.push_back(std::to_string(e.rezzable));

auto results = db.QueryDatabase(
fmt::format(
Expand Down Expand Up @@ -569,6 +597,10 @@ class BaseCharacterCorpsesRepository {
v.push_back(std::to_string(e.wc_7));
v.push_back(std::to_string(e.wc_8));
v.push_back(std::to_string(e.wc_9));
v.push_back(std::to_string(e.rez_time));
v.push_back(std::to_string(e.gm_exp));
v.push_back(std::to_string(e.killed_by));
v.push_back(std::to_string(e.rezzable));

insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
Expand Down Expand Up @@ -649,6 +681,10 @@ class BaseCharacterCorpsesRepository {
e.wc_7 = row[44] ? static_cast<uint32_t>(strtoul(row[44], nullptr, 10)) : 0;
e.wc_8 = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 0;
e.wc_9 = row[46] ? static_cast<uint32_t>(strtoul(row[46], nullptr, 10)) : 0;
e.rez_time = row[47] ? static_cast<uint32_t>(strtoul(row[47], nullptr, 10)) : 0;
e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0;
e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0;
e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;

all_entries.push_back(e);
}
Expand Down Expand Up @@ -720,6 +756,10 @@ class BaseCharacterCorpsesRepository {
e.wc_7 = row[44] ? static_cast<uint32_t>(strtoul(row[44], nullptr, 10)) : 0;
e.wc_8 = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 0;
e.wc_9 = row[46] ? static_cast<uint32_t>(strtoul(row[46], nullptr, 10)) : 0;
e.rez_time = row[47] ? static_cast<uint32_t>(strtoul(row[47], nullptr, 10)) : 0;
e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0;
e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0;
e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;

all_entries.push_back(e);
}
Expand Down Expand Up @@ -841,6 +881,10 @@ class BaseCharacterCorpsesRepository {
v.push_back(std::to_string(e.wc_7));
v.push_back(std::to_string(e.wc_8));
v.push_back(std::to_string(e.wc_9));
v.push_back(std::to_string(e.rez_time));
v.push_back(std::to_string(e.gm_exp));
v.push_back(std::to_string(e.killed_by));
v.push_back(std::to_string(e.rezzable));

auto results = db.QueryDatabase(
fmt::format(
Expand Down Expand Up @@ -910,6 +954,10 @@ class BaseCharacterCorpsesRepository {
v.push_back(std::to_string(e.wc_7));
v.push_back(std::to_string(e.wc_8));
v.push_back(std::to_string(e.wc_9));
v.push_back(std::to_string(e.rez_time));
v.push_back(std::to_string(e.gm_exp));
v.push_back(std::to_string(e.killed_by));
v.push_back(std::to_string(e.rezzable));

insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
Expand Down
2 changes: 1 addition & 1 deletion common/repositories/character_corpses_repository.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class CharacterCorpsesRepository: public BaseCharacterCorpsesRepository {
fmt::format(
"UPDATE `{}` SET `is_buried` = 1 WHERE `is_buried` = 0 AND (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) > {} AND time_of_death != 0",
TableName(),
RuleI(Character, CorpseDecayTimeMS) / 1000
RuleI(Character, CorpseDecayTime) / 1000
)
);

Expand Down
13 changes: 8 additions & 5 deletions common/ruletypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@ RULE_INT(Character, DeathExpLossMultiplier, 3, "Adjust how much experience is lo
RULE_BOOL(Character, DeathKeepLevel, false, "Players can not drop below 0% experience from death.")
RULE_BOOL(Character, UseDeathExpLossMult, false, "Setting to control whether DeathExpLossMultiplier or the code default is used: (Level x Level / 18.0) x 12000")
RULE_BOOL(Character, UseOldRaceRezEffects, false, "Older clients had ID 757 for races with high starting STR, but it doesn't seem used anymore")
RULE_INT(Character, CorpseDecayTimeMS, 10800000, "Time after which the corpse decays (milliseconds)")
RULE_INT(Character, CorpseResTimeMS, 10800000, "Time after which the corpse can no longer be resurrected (milliseconds)")
RULE_INT(Character, CorpseDecayTime, 604800000, "Time after which the corpse decays (milliseconds) DEFAULT: 604800000 (7 Days)")
RULE_INT( Character, EmptyCorpseDecayTime, 10800000, "Time after which an empty corpse decays (milliseconds) DEFAULT: 10800000 (3 Hours)")
RULE_INT(Character, CorpseResTime, 10800000, "Time after which the corpse can no longer be resurrected (milliseconds) DEFAULT: 10800000 (3 Hours)")
RULE_INT( Character, DuelCorpseResTime, 600000, "Time before cant res corpse after a duel (milliseconds) DEFAULT: 600000 (10 Minutes)")
RULE_INT( Character, CorpseOwnerOnlineTime, 30000, "How often corpse will check if its owner is online DEFAULT: 30000 (30 Seconds)")
RULE_BOOL(Character, LeaveCorpses, true, "Setting whether you leave a corpse behind")
RULE_BOOL(Character, LeaveNakedCorpses, false, "Setting whether you leave a corpse without items")
RULE_INT(Character, MaxDraggedCorpses, 2, "Maximum number of corpses you can drag at once")
Expand Down Expand Up @@ -580,10 +583,10 @@ RULE_REAL(Combat, BashACBonusDivisor, 25.0, "this divides the AC value contribut
RULE_CATEGORY_END()

RULE_CATEGORY(NPC)
RULE_INT(NPC, MinorNPCCorpseDecayTimeMS, 450000, "NPC corpse decay time, if NPC below level 55 (milliseconds)")
RULE_INT(NPC, MajorNPCCorpseDecayTimeMS, 1500000, "NPC corpse decay time, if NPC equal or greater than level 55 (milliseconds)")
RULE_INT(NPC, MinorNPCCorpseDecayTime, 450000, "NPC corpse decay time, if NPC below level 55 (milliseconds)")
RULE_INT(NPC, MajorNPCCorpseDecayTime, 1500000, "NPC corpse decay time, if NPC equal or greater than level 55 (milliseconds)")
RULE_INT(NPC, CorpseUnlockTimer, 150000, "Time after which corpses are unlocked for everyone to loot (milliseconds)")
RULE_INT(NPC, EmptyNPCCorpseDecayTimeMS, 0, "NPC corpse decay time, if no items are left on the corpse (milliseconds)")
RULE_INT(NPC, EmptyNPCCorpseDecayTime, 0, "NPC corpse decay time, if no items are left on the corpse (milliseconds)")
RULE_BOOL(NPC, UseItemBonusesForNonPets, true, "Switch whether item bonuses should be used for NPCs who are not pets")
RULE_BOOL(NPC, UseBaneDamage, false, "If NPCs can't inherently hit the target we don't add bane/magic dmg which isn't exactly the same as PCs")
RULE_INT(NPC, SayPauseTimeInSec, 5, "Time span in which an NPC pauses his movement after a Say event without aggro (seconds)")
Expand Down
9 changes: 9 additions & 0 deletions common/servertalk.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
#define ServerOP_UpdateSpawn 0x003f
#define ServerOP_SpawnStatusChange 0x0040
#define ServerOP_DropClient 0x0041 // DropClient
#define ServerOP_IsOwnerOnline 0x0042
#define ServerOP_DepopAllPlayersCorpses 0x0060
#define ServerOP_QGlobalUpdate 0x0061
#define ServerOP_QGlobalDelete 0x0062
Expand Down Expand Up @@ -1653,6 +1654,14 @@ struct ServerRequestTellQueue_Struct {
char name[64];
};

struct ServerIsOwnerOnline_Struct {
char name[64];
uint32 corpse_id;
uint16 zone_id;
uint8 online;
uint32 account_id;
};

struct UCSServerStatus_Struct {
uint8 available; // non-zero=true, 0=false
union {
Expand Down
2 changes: 1 addition & 1 deletion common/shareddb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1495,7 +1495,7 @@ int SharedDatabase::DeleteStalePlayerCorpses() {
*this,
fmt::format(
"(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) > {} AND time_of_death != 0",
RuleI(Character, CorpseDecayTimeMS) / 1000
RuleI(Character, CorpseDecayTime) / 1000
)
)
);
Expand Down
1 change: 1 addition & 0 deletions common/spdat.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@
#define SPELL_ANCIENT_CRY_OF_CHAOS 5032
#define SPELL_BLOODTHIRST 8476
#define SPELL_AMPLIFICATION 2603
#define SPELL_DIVINE_REZ 2738

// discipline IDs.
#define DISC_UNHOLY_AURA 4520
Expand Down
2 changes: 1 addition & 1 deletion common/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/

#define CURRENT_BINARY_DATABASE_VERSION 9258
#define CURRENT_BINARY_DATABASE_VERSION 9259

#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9042

Expand Down
4 changes: 4 additions & 0 deletions world/world_boot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,12 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
->LoadTaskData()
->LoadSharedTaskState();

LogInfo("Purging expired shared tasks");
shared_task_manager.PurgeExpiredSharedTasks();

LogInfo("Cleaning up instance corpses");
database.CleanupInstanceCorpses();

return true;
}

Expand Down
25 changes: 25 additions & 0 deletions world/zoneserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,31 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
RuleManager::Instance()->LoadRules(&database, "default", true);
break;
}
case ServerOP_IsOwnerOnline: {
if (pack->size != sizeof(ServerIsOwnerOnline_Struct)) {
break;
}

auto o = (ServerIsOwnerOnline_Struct*) pack->pBuffer;
auto cle = client_list.FindCLEByAccountID(o->account_id);

o->online = cle ? 1 : 0;

if (o->online) {
LogCorpsesDetail(
"ServerOP_IsOwnerOnline account_id [{}] corpse name [{}] found to be online, sending online update to zone_id [{}]",
o->account_id,
o->name,
o->zone_id
);
}

auto zs = zoneserver_list.FindByZoneID(o->zone_id);
if (zs) {
zs->SendPacket(pack);
}
break;
}
case ServerOP_ReloadContentFlags: {
zoneserver_list.SendPacket(pack);
content_service.SetExpansionContext()->ReloadContentFlags();
Expand Down
Loading