Implemented 'Inventory Snapshot' feature

This commit is contained in:
Uleat
2015-09-25 23:07:05 -04:00
parent 41d19c4e8a
commit a1089fccd6
15 changed files with 192 additions and 6 deletions
+11
View File
@@ -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;
+7
View File
@@ -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);
+32
View File
@@ -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) {
+2
View File
@@ -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
View File
@@ -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);
+1
View File
@@ -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);