mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 03:08:26 +00:00
Implemented 'Inventory Snapshot' feature
This commit is contained in:
@@ -642,6 +642,17 @@ bool Client::Save(uint8 iCommitNow) {
|
||||
|
||||
m_pp.hunger_level = EQEmu::Clamp(m_pp.hunger_level, 0, 50000);
|
||||
m_pp.thirst_level = EQEmu::Clamp(m_pp.thirst_level, 0, 50000);
|
||||
|
||||
// perform snapshot before SaveCharacterData() so that m_epp will contain the updated time
|
||||
if (RuleB(Character, ActiveInvSnapshots) && time(nullptr) >= GetNextInvSnapshotTime()) {
|
||||
if (database.SaveCharacterInventorySnapshot(CharacterID())) {
|
||||
SetNextInvSnapshot(RuleI(Character, InvSnapshotMinIntervalM));
|
||||
}
|
||||
else {
|
||||
SetNextInvSnapshot(RuleI(Character, InvSnapshotMinRetryM));
|
||||
}
|
||||
}
|
||||
|
||||
database.SaveCharacterData(this->CharacterID(), this->AccountID(), &m_pp, &m_epp); /* Save Character Data */
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1250,6 +1250,13 @@ public:
|
||||
|
||||
bool InterrogateInventory(Client* requester, bool log, bool silent, bool allowtrip, bool& error, bool autolog = true);
|
||||
|
||||
void SetNextInvSnapshot(uint32 interval_in_min) {
|
||||
m_epp.last_invsnapshot_time = time(nullptr);
|
||||
m_epp.next_invsnapshot_time = m_epp.last_invsnapshot_time + (interval_in_min * 60);
|
||||
}
|
||||
uint32 GetLastInvSnapshotTime() { return m_epp.last_invsnapshot_time; }
|
||||
uint32 GetNextInvSnapshotTime() { return m_epp.next_invsnapshot_time; }
|
||||
|
||||
//Command #Tune functions
|
||||
virtual int32 Tune_GetMeleeMitDmg(Mob* GM, Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||
int32 GetMeleeDamage(Mob* other, bool GetMinDamage = false);
|
||||
|
||||
@@ -183,6 +183,7 @@ int command_init(void) {
|
||||
command_add("castspell", "[spellid] - Cast a spell", 50, command_castspell) ||
|
||||
command_add("chat", "[channel num] [message] - Send a channel message to all zones", 200, command_chat) ||
|
||||
command_add("checklos", "- Check for line of sight to your target", 50, command_checklos) ||
|
||||
command_add("clearinvsnapshots", "[use rule] - Clear inventory snapshot history (true - elapsed entries, false - all entries)", 200, command_clearinvsnapshots) ||
|
||||
command_add("close_shop", nullptr, 100, command_merchantcloseshop) ||
|
||||
command_add("connectworld", nullptr,0, command_connectworldserver) ||
|
||||
command_add("connectworldserver", "- Make zone attempt to connect to worldserver", 200, command_connectworldserver) ||
|
||||
@@ -260,6 +261,7 @@ int command_init(void) {
|
||||
command_add("instance", "- Modify Instances", 200, command_instance) ||
|
||||
command_add("interrogateinv", "- use [help] argument for available options", 0, command_interrogateinv) ||
|
||||
command_add("interrupt", "[message id] [color] - Interrupt your casting. Arguments are optional.", 50, command_interrupt) ||
|
||||
command_add("invsnapshot", "- Takes an inventory snapshot of your current target", 80, command_invsnapshot) ||
|
||||
command_add("invul", nullptr,0, command_invul) ||
|
||||
command_add("invulnerable", "[on/off] - Turn player target's or your invulnerable flag on or off", 80, command_invul) ||
|
||||
command_add("ipban", "[IP address] - Ban IP by character name", 200, command_ipban) ||
|
||||
@@ -2836,6 +2838,36 @@ void command_interrogateinv(Client *c, const Seperator *sep)
|
||||
c->Message(13, "An unknown error occurred while processing Client::InterrogateInventory()");
|
||||
}
|
||||
|
||||
void command_invsnapshot(Client *c, const Seperator *sep)
|
||||
{
|
||||
auto t = c->GetTarget();
|
||||
if (!t || !t->IsClient()) {
|
||||
c->Message(0, "Target must be a client");
|
||||
return;
|
||||
}
|
||||
|
||||
if (database.SaveCharacterInventorySnapshot(((Client*)t)->CharacterID())) {
|
||||
c->SetNextInvSnapshot(RuleI(Character, InvSnapshotMinIntervalM));
|
||||
c->Message(0, "Successful inventory snapshot taken of %s", t->GetName());
|
||||
}
|
||||
else {
|
||||
c->SetNextInvSnapshot(RuleI(Character, InvSnapshotMinRetryM));
|
||||
c->Message(0, "Failed to take inventory snapshot of %s", t->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
void command_clearinvsnapshots(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (strcmp(sep->arg[1], "false") == 0) {
|
||||
database.ClearInvSnapshots(false);
|
||||
c->Message(0, "Inventory snapshots cleared using current time");
|
||||
}
|
||||
else {
|
||||
database.ClearInvSnapshots();
|
||||
c->Message(0, "Inventory snapshots cleared using RuleI(Character, InvSnapshotHistoryD) (%i days)", RuleI(Character, InvSnapshotHistoryD));
|
||||
}
|
||||
}
|
||||
|
||||
void command_findnpctype(Client *c, const Seperator *sep)
|
||||
{
|
||||
if(sep->arg[1][0] == 0) {
|
||||
|
||||
@@ -154,6 +154,8 @@ void command_appearance(Client *c, const Seperator *sep);
|
||||
void command_nukeitem(Client *c, const Seperator *sep);
|
||||
void command_peekinv(Client *c, const Seperator *sep);
|
||||
void command_interrogateinv(Client *c, const Seperator *sep);
|
||||
void command_invsnapshot(Client *c, const Seperator *sep);
|
||||
void command_clearinvsnapshots(Client *c, const Seperator *sep);
|
||||
void command_findnpctype(Client *c, const Seperator *sep);
|
||||
void command_findzone(Client *c, const Seperator *sep);
|
||||
void command_viewnpctype(Client *c, const Seperator *sep);
|
||||
|
||||
+61
-5
@@ -887,7 +887,8 @@ bool ZoneDatabase::LoadCharacterData(uint32 character_id, PlayerProfile_Struct*
|
||||
"RestTimer, "
|
||||
"`e_aa_effects`, "
|
||||
"`e_percent_to_aa`, "
|
||||
"`e_expended_aa_spent` "
|
||||
"`e_expended_aa_spent`, "
|
||||
"`e_last_invsnapshot` "
|
||||
"FROM "
|
||||
"character_data "
|
||||
"WHERE `id` = %i ", character_id);
|
||||
@@ -983,7 +984,9 @@ bool ZoneDatabase::LoadCharacterData(uint32 character_id, PlayerProfile_Struct*
|
||||
pp->RestTimer = atoi(row[r]); r++; // "RestTimer, "
|
||||
m_epp->aa_effects = atoi(row[r]); r++; // "`e_aa_effects`, "
|
||||
m_epp->perAA = atoi(row[r]); r++; // "`e_percent_to_aa`, "
|
||||
m_epp->expended_aa = atoi(row[r]); r++; // "`e_expended_aa_spent` "
|
||||
m_epp->expended_aa = atoi(row[r]); r++; // "`e_expended_aa_spent`, "
|
||||
m_epp->last_invsnapshot_time = atoi(row[r]); r++; // "`e_last_invsnapshot` "
|
||||
m_epp->next_invsnapshot_time = m_epp->last_invsnapshot_time + (RuleI(Character, InvSnapshotMinIntervalM) * 60);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1377,6 +1380,56 @@ bool ZoneDatabase::SaveCharacterLeadershipAA(uint32 character_id, PlayerProfile_
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZoneDatabase::SaveCharacterInventorySnapshot(uint32 character_id){
|
||||
uint32 time_index = time(nullptr);
|
||||
std::string query = StringFormat(
|
||||
"INSERT INTO inventory_snapshots ("
|
||||
" time_index,"
|
||||
" charid,"
|
||||
" slotid,"
|
||||
" itemid,"
|
||||
" charges,"
|
||||
" color,"
|
||||
" augslot1,"
|
||||
" augslot2,"
|
||||
" augslot3,"
|
||||
" augslot4,"
|
||||
" augslot5,"
|
||||
" augslot6,"
|
||||
" instnodrop,"
|
||||
" custom_data,"
|
||||
" ornamenticon,"
|
||||
" ornamentidfile,"
|
||||
" ornament_hero_model"
|
||||
")"
|
||||
" SELECT"
|
||||
" %u,"
|
||||
" charid,"
|
||||
" slotid,"
|
||||
" itemid,"
|
||||
" charges,"
|
||||
" color,"
|
||||
" augslot1,"
|
||||
" augslot2,"
|
||||
" augslot3,"
|
||||
" augslot4,"
|
||||
" augslot5,"
|
||||
" augslot6,"
|
||||
" instnodrop,"
|
||||
" custom_data,"
|
||||
" ornamenticon,"
|
||||
" ornamentidfile,"
|
||||
" ornament_hero_model"
|
||||
" FROM inventory"
|
||||
" WHERE charid = %u",
|
||||
time_index,
|
||||
character_id
|
||||
);
|
||||
auto results = database.QueryDatabase(query);
|
||||
Log.Out(Logs::General, Logs::None, "ZoneDatabase::SaveCharacterInventorySnapshot %i (%s)", character_id, (results.Success() ? "pass" : "fail"));
|
||||
return results.Success();
|
||||
}
|
||||
|
||||
bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp){
|
||||
clock_t t = std::clock(); /* Function timer start */
|
||||
std::string query = StringFormat(
|
||||
@@ -1473,7 +1526,8 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla
|
||||
" RestTimer, "
|
||||
" e_aa_effects, "
|
||||
" e_percent_to_aa, "
|
||||
" e_expended_aa_spent "
|
||||
" e_expended_aa_spent, "
|
||||
" e_last_invsnapshot "
|
||||
") "
|
||||
"VALUES ("
|
||||
"%u," // id " id, "
|
||||
@@ -1568,7 +1622,8 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla
|
||||
"%u," // RestTimer pp->RestTimer, " RestTimer) "
|
||||
"%u," // e_aa_effects
|
||||
"%u," // e_percent_to_aa
|
||||
"%u" // e_expended_aa_spent
|
||||
"%u," // e_expended_aa_spent
|
||||
"%u" // e_last_invsnapshot
|
||||
")",
|
||||
character_id, // " id, "
|
||||
account_id, // " account_id, "
|
||||
@@ -1662,7 +1717,8 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla
|
||||
pp->RestTimer, // " RestTimer) "
|
||||
m_epp->aa_effects,
|
||||
m_epp->perAA,
|
||||
m_epp->expended_aa
|
||||
m_epp->expended_aa,
|
||||
m_epp->last_invsnapshot_time
|
||||
);
|
||||
auto results = database.QueryDatabase(query);
|
||||
Log.Out(Logs::General, Logs::None, "ZoneDatabase::SaveCharacterData %i, done... Took %f seconds", character_id, ((float)(std::clock() - t)) / CLOCKS_PER_SEC);
|
||||
|
||||
@@ -290,6 +290,7 @@ public:
|
||||
bool SaveCharacterBandolier(uint32 character_id, uint8 bandolier_id, uint8 bandolier_slot, uint32 item_id, uint32 icon, const char* bandolier_name);
|
||||
bool SaveCharacterPotionBelt(uint32 character_id, uint8 potion_id, uint32 item_id, uint32 icon);
|
||||
bool SaveCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
bool SaveCharacterInventorySnapshot(uint32 character_id);
|
||||
|
||||
/* Character Data Deletes */
|
||||
bool DeleteCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
|
||||
|
||||
Reference in New Issue
Block a user