[Quest API] Add Last Login and First Login Flags to EVENT_CONNECT

This commit is contained in:
Kinglykrab
2025-04-17 12:33:50 -04:00
committed by Chris Miles
parent 4a9779635d
commit ed89585c91
11 changed files with 171 additions and 77 deletions
+6 -6
View File
@@ -1095,13 +1095,13 @@ void Database::SetLFP(uint32 character_id, bool is_lfp)
CharacterDataRepository::UpdateOne(*this, e); CharacterDataRepository::UpdateOne(*this, e);
} }
void Database::SetLoginFlags(uint32 character_id, bool is_lfp, bool is_lfg, uint8 first_logon) void Database::SetLoginFlags(uint32 character_id, bool is_lfp, bool is_lfg, uint8 ingame)
{ {
auto e = CharacterDataRepository::FindOne(*this, character_id); auto e = CharacterDataRepository::FindOne(*this, character_id);
e.firstlogon = first_logon; e.ingame = ingame;
e.lfg = is_lfg ? 1 : 0; e.lfg = is_lfg ? 1 : 0;
e.lfp = is_lfp ? 1 : 0; e.lfp = is_lfp ? 1 : 0;
CharacterDataRepository::UpdateOne(*this, e); CharacterDataRepository::UpdateOne(*this, e);
} }
@@ -1115,11 +1115,11 @@ void Database::SetLFG(uint32 character_id, bool is_lfg)
CharacterDataRepository::UpdateOne(*this, e); CharacterDataRepository::UpdateOne(*this, e);
} }
void Database::SetFirstLogon(uint32 character_id, uint8 first_logon) void Database::SetIngame(uint32 character_id, uint8 ingame)
{ {
auto e = CharacterDataRepository::FindOne(*this, character_id); auto e = CharacterDataRepository::FindOne(*this, character_id);
e.firstlogon = first_logon; e.ingame = ingame;
CharacterDataRepository::UpdateOne(*this, e); CharacterDataRepository::UpdateOne(*this, e);
} }
+1 -1
View File
@@ -263,7 +263,7 @@ public:
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year); bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
void ClearMerchantTemp(); void ClearMerchantTemp();
void ClearPTimers(uint32 character_id); void ClearPTimers(uint32 character_id);
void SetFirstLogon(uint32 character_id, uint8 first_logon); void SetIngame(uint32 character_id, uint8 ingame);
void SetLFG(uint32 character_id, bool is_lfg); void SetLFG(uint32 character_id, bool is_lfg);
void SetLFP(uint32 character_id, bool is_lfp); void SetLFP(uint32 character_id, bool is_lfp);
void SetLoginFlags(uint32 character_id, bool is_lfp, bool is_lfg, uint8 first_logon); void SetLoginFlags(uint32 character_id, bool is_lfp, bool is_lfg, uint8 first_logon);
+13 -1
View File
@@ -7098,7 +7098,19 @@ ALTER TABLE `npc_types`
ADD COLUMN `npc_tint_id` SMALLINT UNSIGNED NULL DEFAULT '0' AFTER `multiquest_enabled`; ADD COLUMN `npc_tint_id` SMALLINT UNSIGNED NULL DEFAULT '0' AFTER `multiquest_enabled`;
)", )",
.content_schema_update = true .content_schema_update = true
} },
ManifestEntry{
.description = "2025_04_16_character_data_first_login.sql",
.check = "SHOW COLUMNS FROM `character_data` LIKE 'first_login'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `character_data`
CHANGE COLUMN `firstlogon` `ingame` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`,
ADD COLUMN `first_login` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`;
)",
.content_schema_update = false
},
// -- template; copy/paste this when you need to create a new entry // -- template; copy/paste this when you need to create a new entry
// ManifestEntry{ // ManifestEntry{
// .version = 9228, // .version = 9228,
@@ -115,12 +115,14 @@ public:
uint8_t lfg; uint8_t lfg;
std::string mailkey; std::string mailkey;
uint8_t xtargets; uint8_t xtargets;
int8_t firstlogon; uint8_t ingame;
uint32_t first_login;
uint32_t e_aa_effects; uint32_t e_aa_effects;
uint32_t e_percent_to_aa; uint32_t e_percent_to_aa;
uint32_t e_expended_aa_spent; uint32_t e_expended_aa_spent;
uint32_t aa_points_spent_old; uint32_t aa_points_spent_old;
uint32_t aa_points_old; uint32_t aa_points_old;
int32_t expansions;
uint32_t e_last_invsnapshot; uint32_t e_last_invsnapshot;
time_t deleted_at; time_t deleted_at;
uint8_t illusion_block; uint8_t illusion_block;
@@ -230,12 +232,14 @@ public:
"lfg", "lfg",
"mailkey", "mailkey",
"xtargets", "xtargets",
"firstlogon", "ingame",
"first_login",
"e_aa_effects", "e_aa_effects",
"e_percent_to_aa", "e_percent_to_aa",
"e_expended_aa_spent", "e_expended_aa_spent",
"aa_points_spent_old", "aa_points_spent_old",
"aa_points_old", "aa_points_old",
"expansions",
"e_last_invsnapshot", "e_last_invsnapshot",
"deleted_at", "deleted_at",
"illusion_block", "illusion_block",
@@ -341,12 +345,14 @@ public:
"lfg", "lfg",
"mailkey", "mailkey",
"xtargets", "xtargets",
"firstlogon", "ingame",
"first_login",
"e_aa_effects", "e_aa_effects",
"e_percent_to_aa", "e_percent_to_aa",
"e_expended_aa_spent", "e_expended_aa_spent",
"aa_points_spent_old", "aa_points_spent_old",
"aa_points_old", "aa_points_old",
"expansions",
"e_last_invsnapshot", "e_last_invsnapshot",
"UNIX_TIMESTAMP(deleted_at)", "UNIX_TIMESTAMP(deleted_at)",
"illusion_block", "illusion_block",
@@ -486,12 +492,14 @@ public:
e.lfg = 0; e.lfg = 0;
e.mailkey = ""; e.mailkey = "";
e.xtargets = 5; e.xtargets = 5;
e.firstlogon = 0; e.ingame = 0;
e.first_login = 0;
e.e_aa_effects = 0; e.e_aa_effects = 0;
e.e_percent_to_aa = 0; e.e_percent_to_aa = 0;
e.e_expended_aa_spent = 0; e.e_expended_aa_spent = 0;
e.aa_points_spent_old = 0; e.aa_points_spent_old = 0;
e.aa_points_old = 0; e.aa_points_old = 0;
e.expansions = -1;
e.e_last_invsnapshot = 0; e.e_last_invsnapshot = 0;
e.deleted_at = 0; e.deleted_at = 0;
e.illusion_block = 0; e.illusion_block = 0;
@@ -627,15 +635,17 @@ public:
e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0; e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0;
e.mailkey = row[94] ? row[94] : ""; e.mailkey = row[94] ? row[94] : "";
e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5; e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5;
e.firstlogon = row[96] ? static_cast<int8_t>(atoi(row[96])) : 0; e.ingame = row[96] ? static_cast<uint8_t>(strtoul(row[96], nullptr, 10)) : 0;
e.e_aa_effects = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0; e.first_login = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0;
e.e_percent_to_aa = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0; e.e_aa_effects = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0;
e.e_expended_aa_spent = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0; e.e_percent_to_aa = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0;
e.aa_points_spent_old = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0; e.e_expended_aa_spent = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0;
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0; e.aa_points_spent_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0; e.aa_points_old = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10); e.expansions = row[103] ? static_cast<int32_t>(atoi(row[103])) : -1;
e.illusion_block = row[104] ? static_cast<uint8_t>(strtoul(row[104], nullptr, 10)) : 0; e.e_last_invsnapshot = row[104] ? static_cast<uint32_t>(strtoul(row[104], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[105] ? row[105] : "-1", nullptr, 10);
e.illusion_block = row[106] ? static_cast<uint8_t>(strtoul(row[106], nullptr, 10)) : 0;
return e; return e;
} }
@@ -764,15 +774,17 @@ public:
v.push_back(columns[93] + " = " + std::to_string(e.lfg)); v.push_back(columns[93] + " = " + std::to_string(e.lfg));
v.push_back(columns[94] + " = '" + Strings::Escape(e.mailkey) + "'"); v.push_back(columns[94] + " = '" + Strings::Escape(e.mailkey) + "'");
v.push_back(columns[95] + " = " + std::to_string(e.xtargets)); v.push_back(columns[95] + " = " + std::to_string(e.xtargets));
v.push_back(columns[96] + " = " + std::to_string(e.firstlogon)); v.push_back(columns[96] + " = " + std::to_string(e.ingame));
v.push_back(columns[97] + " = " + std::to_string(e.e_aa_effects)); v.push_back(columns[97] + " = " + std::to_string(e.first_login));
v.push_back(columns[98] + " = " + std::to_string(e.e_percent_to_aa)); v.push_back(columns[98] + " = " + std::to_string(e.e_aa_effects));
v.push_back(columns[99] + " = " + std::to_string(e.e_expended_aa_spent)); v.push_back(columns[99] + " = " + std::to_string(e.e_percent_to_aa));
v.push_back(columns[100] + " = " + std::to_string(e.aa_points_spent_old)); v.push_back(columns[100] + " = " + std::to_string(e.e_expended_aa_spent));
v.push_back(columns[101] + " = " + std::to_string(e.aa_points_old)); v.push_back(columns[101] + " = " + std::to_string(e.aa_points_spent_old));
v.push_back(columns[102] + " = " + std::to_string(e.e_last_invsnapshot)); v.push_back(columns[102] + " = " + std::to_string(e.aa_points_old));
v.push_back(columns[103] + " = FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")"); v.push_back(columns[103] + " = " + std::to_string(e.expansions));
v.push_back(columns[104] + " = " + std::to_string(e.illusion_block)); v.push_back(columns[104] + " = " + std::to_string(e.e_last_invsnapshot));
v.push_back(columns[105] + " = FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(columns[106] + " = " + std::to_string(e.illusion_block));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@@ -890,12 +902,14 @@ public:
v.push_back(std::to_string(e.lfg)); v.push_back(std::to_string(e.lfg));
v.push_back("'" + Strings::Escape(e.mailkey) + "'"); v.push_back("'" + Strings::Escape(e.mailkey) + "'");
v.push_back(std::to_string(e.xtargets)); v.push_back(std::to_string(e.xtargets));
v.push_back(std::to_string(e.firstlogon)); v.push_back(std::to_string(e.ingame));
v.push_back(std::to_string(e.first_login));
v.push_back(std::to_string(e.e_aa_effects)); v.push_back(std::to_string(e.e_aa_effects));
v.push_back(std::to_string(e.e_percent_to_aa)); v.push_back(std::to_string(e.e_percent_to_aa));
v.push_back(std::to_string(e.e_expended_aa_spent)); v.push_back(std::to_string(e.e_expended_aa_spent));
v.push_back(std::to_string(e.aa_points_spent_old)); v.push_back(std::to_string(e.aa_points_spent_old));
v.push_back(std::to_string(e.aa_points_old)); v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.expansions));
v.push_back(std::to_string(e.e_last_invsnapshot)); v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")"); v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.illusion_block)); v.push_back(std::to_string(e.illusion_block));
@@ -1024,12 +1038,14 @@ public:
v.push_back(std::to_string(e.lfg)); v.push_back(std::to_string(e.lfg));
v.push_back("'" + Strings::Escape(e.mailkey) + "'"); v.push_back("'" + Strings::Escape(e.mailkey) + "'");
v.push_back(std::to_string(e.xtargets)); v.push_back(std::to_string(e.xtargets));
v.push_back(std::to_string(e.firstlogon)); v.push_back(std::to_string(e.ingame));
v.push_back(std::to_string(e.first_login));
v.push_back(std::to_string(e.e_aa_effects)); v.push_back(std::to_string(e.e_aa_effects));
v.push_back(std::to_string(e.e_percent_to_aa)); v.push_back(std::to_string(e.e_percent_to_aa));
v.push_back(std::to_string(e.e_expended_aa_spent)); v.push_back(std::to_string(e.e_expended_aa_spent));
v.push_back(std::to_string(e.aa_points_spent_old)); v.push_back(std::to_string(e.aa_points_spent_old));
v.push_back(std::to_string(e.aa_points_old)); v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.expansions));
v.push_back(std::to_string(e.e_last_invsnapshot)); v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")"); v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.illusion_block)); v.push_back(std::to_string(e.illusion_block));
@@ -1162,15 +1178,17 @@ public:
e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0; e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0;
e.mailkey = row[94] ? row[94] : ""; e.mailkey = row[94] ? row[94] : "";
e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5; e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5;
e.firstlogon = row[96] ? static_cast<int8_t>(atoi(row[96])) : 0; e.ingame = row[96] ? static_cast<uint8_t>(strtoul(row[96], nullptr, 10)) : 0;
e.e_aa_effects = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0; e.first_login = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0;
e.e_percent_to_aa = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0; e.e_aa_effects = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0;
e.e_expended_aa_spent = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0; e.e_percent_to_aa = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0;
e.aa_points_spent_old = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0; e.e_expended_aa_spent = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0;
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0; e.aa_points_spent_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0; e.aa_points_old = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10); e.expansions = row[103] ? static_cast<int32_t>(atoi(row[103])) : -1;
e.illusion_block = row[104] ? static_cast<uint8_t>(strtoul(row[104], nullptr, 10)) : 0; e.e_last_invsnapshot = row[104] ? static_cast<uint32_t>(strtoul(row[104], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[105] ? row[105] : "-1", nullptr, 10);
e.illusion_block = row[106] ? static_cast<uint8_t>(strtoul(row[106], nullptr, 10)) : 0;
all_entries.push_back(e); all_entries.push_back(e);
} }
@@ -1291,15 +1309,17 @@ public:
e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0; e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0;
e.mailkey = row[94] ? row[94] : ""; e.mailkey = row[94] ? row[94] : "";
e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5; e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5;
e.firstlogon = row[96] ? static_cast<int8_t>(atoi(row[96])) : 0; e.ingame = row[96] ? static_cast<uint8_t>(strtoul(row[96], nullptr, 10)) : 0;
e.e_aa_effects = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0; e.first_login = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0;
e.e_percent_to_aa = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0; e.e_aa_effects = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0;
e.e_expended_aa_spent = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0; e.e_percent_to_aa = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0;
e.aa_points_spent_old = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0; e.e_expended_aa_spent = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0;
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0; e.aa_points_spent_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0; e.aa_points_old = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10); e.expansions = row[103] ? static_cast<int32_t>(atoi(row[103])) : -1;
e.illusion_block = row[104] ? static_cast<uint8_t>(strtoul(row[104], nullptr, 10)) : 0; e.e_last_invsnapshot = row[104] ? static_cast<uint32_t>(strtoul(row[104], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[105] ? row[105] : "-1", nullptr, 10);
e.illusion_block = row[106] ? static_cast<uint8_t>(strtoul(row[106], nullptr, 10)) : 0;
all_entries.push_back(e); all_entries.push_back(e);
} }
@@ -1470,12 +1490,14 @@ public:
v.push_back(std::to_string(e.lfg)); v.push_back(std::to_string(e.lfg));
v.push_back("'" + Strings::Escape(e.mailkey) + "'"); v.push_back("'" + Strings::Escape(e.mailkey) + "'");
v.push_back(std::to_string(e.xtargets)); v.push_back(std::to_string(e.xtargets));
v.push_back(std::to_string(e.firstlogon)); v.push_back(std::to_string(e.ingame));
v.push_back(std::to_string(e.first_login));
v.push_back(std::to_string(e.e_aa_effects)); v.push_back(std::to_string(e.e_aa_effects));
v.push_back(std::to_string(e.e_percent_to_aa)); v.push_back(std::to_string(e.e_percent_to_aa));
v.push_back(std::to_string(e.e_expended_aa_spent)); v.push_back(std::to_string(e.e_expended_aa_spent));
v.push_back(std::to_string(e.aa_points_spent_old)); v.push_back(std::to_string(e.aa_points_spent_old));
v.push_back(std::to_string(e.aa_points_old)); v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.expansions));
v.push_back(std::to_string(e.e_last_invsnapshot)); v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")"); v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.illusion_block)); v.push_back(std::to_string(e.illusion_block));
@@ -1597,12 +1619,14 @@ public:
v.push_back(std::to_string(e.lfg)); v.push_back(std::to_string(e.lfg));
v.push_back("'" + Strings::Escape(e.mailkey) + "'"); v.push_back("'" + Strings::Escape(e.mailkey) + "'");
v.push_back(std::to_string(e.xtargets)); v.push_back(std::to_string(e.xtargets));
v.push_back(std::to_string(e.firstlogon)); v.push_back(std::to_string(e.ingame));
v.push_back(std::to_string(e.first_login));
v.push_back(std::to_string(e.e_aa_effects)); v.push_back(std::to_string(e.e_aa_effects));
v.push_back(std::to_string(e.e_percent_to_aa)); v.push_back(std::to_string(e.e_percent_to_aa));
v.push_back(std::to_string(e.e_expended_aa_spent)); v.push_back(std::to_string(e.e_expended_aa_spent));
v.push_back(std::to_string(e.aa_points_spent_old)); v.push_back(std::to_string(e.aa_points_spent_old));
v.push_back(std::to_string(e.aa_points_old)); v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.expansions));
v.push_back(std::to_string(e.e_last_invsnapshot)); v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")"); v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.illusion_block)); v.push_back(std::to_string(e.illusion_block));
+2 -1
View File
@@ -2080,7 +2080,8 @@ private:
uint16 trader_id; uint16 trader_id;
uint16 customer_id; uint16 customer_id;
uint32 account_creation; uint32 account_creation;
uint8 firstlogon; bool first_login;
bool ingame;
uint32 mercid; // current merc uint32 mercid; // current merc
uint8 mercSlot; // selected merc slot uint8 mercSlot; // selected merc slot
time_t m_trader_transaction_date; time_t m_trader_transaction_date;
+46 -23
View File
@@ -807,29 +807,41 @@ void Client::CompleteConnect()
m_last_position_before_bulk_update = GetPosition(); m_last_position_before_bulk_update = GetPosition();
/* This sub event is for if a player logs in for the first time since entering world. */ /* This sub event is for if a player logs in for the first time since entering world. */
if (firstlogon == 1) { if (ingame) {
TraderRepository::DeleteWhere(database, fmt::format("`char_id` = '{}'", CharacterID())); auto e = CharacterDataRepository::FindOne(
BuyerRepository::DeleteBuyer(database, CharacterID()); database,
LogTradingDetail(
"Removed trader abd buyer entries for Character ID {} on first logon to ensure table consistency.",
CharacterID() CharacterID()
); );
bool is_first_login = e.first_login == 0;
RecordPlayerEventLog(PlayerEvent::WENT_ONLINE, PlayerEvent::EmptyEvent{}); RecordPlayerEventLog(PlayerEvent::WENT_ONLINE, PlayerEvent::EmptyEvent{});
if (parse->PlayerHasQuestSub(EVENT_CONNECT)) { if (parse->PlayerHasQuestSub(EVENT_CONNECT)) {
parse->EventPlayer(EVENT_CONNECT, this, "", 0); const std::string& export_string = fmt::format(
"{} {}",
GetPP().lastlogin,
is_first_login ? 1 : 0
);
parse->EventPlayer(EVENT_CONNECT, this, export_string, 0);
} }
/** if (is_first_login) {
* Update last login since this doesn't get updated until a late save later so we can update online status e.first_login = time(nullptr);
*/ TraderRepository::DeleteWhere(database, fmt::format("`char_id` = '{}'", CharacterID()));
database.QueryDatabase( BuyerRepository::DeleteBuyer(database, CharacterID());
StringFormat( LogTradingDetail(
"UPDATE `character_data` SET `last_login` = UNIX_TIMESTAMP() WHERE id = %u", "Removed trader abd buyer entries for Character ID {} on first logon to ensure table consistency.",
CharacterID() CharacterID()
) );
); }
e.last_login = time(nullptr);
const int updated = CharacterDataRepository::UpdateOne(database, e);
if (!updated) {
LogError("Failed to update login time for character_id [{}]", CharacterID());
}
if (IsPetNameChangeAllowed() && !RuleB(Pets, AlwaysAllowPetRename)) { if (IsPetNameChangeAllowed() && !RuleB(Pets, AlwaysAllowPetRename)) {
InvokeChangePetName(false); InvokeChangePetName(false);
@@ -878,7 +890,7 @@ void Client::CompleteConnect()
entity_list.SendFindableNPCList(this); entity_list.SendFindableNPCList(this);
if (IsInAGuild()) { if (IsInAGuild()) {
if (firstlogon == 1) { if (ingame) {
guild_mgr.UpdateDbMemberOnline(CharacterID(), true); guild_mgr.UpdateDbMemberOnline(CharacterID(), true);
SendGuildMembersList(); SendGuildMembersList();
} }
@@ -1314,14 +1326,14 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
/* Load Character Data */ /* Load Character Data */
query = fmt::format( query = fmt::format(
"SELECT `lfp`, `lfg`, `xtargets`, `firstlogon`, `guild_id`, `rank`, `exp_enabled`, `tribute_enable`, `extra_haste`, `illusion_block` FROM `character_data` LEFT JOIN `guild_members` ON `id` = `char_id` WHERE `id` = {}", "SELECT `lfp`, `lfg`, `xtargets`, `first_login`, `guild_id`, `rank`, `exp_enabled`, `tribute_enable`, `extra_haste`, `illusion_block`, `ingame` FROM `character_data` LEFT JOIN `guild_members` ON `id` = `char_id` WHERE `id` = {}",
cid cid
); );
auto results = database.QueryDatabase(query); auto results = database.QueryDatabase(query);
for (auto row : results) { for (auto row : results) {
if (row[4] && Strings::ToInt(row[4]) > 0) { if (row[4] && Strings::ToInt(row[4]) > 0) {
guild_id = Strings::ToInt(row[4]); guild_id = Strings::ToInt(row[4]);
guildrank = row[5] ? Strings::ToInt(row[5]) : GUILD_RANK_NONE; guildrank = row[5] ? Strings::ToInt(row[5]) : GUILD_RANK_NONE;
guild_tribute_opt_in = row[7] ? Strings::ToBool(row[7]) : 0; guild_tribute_opt_in = row[7] ? Strings::ToBool(row[7]) : 0;
} }
@@ -1329,10 +1341,21 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
SetExtraHaste(Strings::ToInt(row[8]), false); SetExtraHaste(Strings::ToInt(row[8]), false);
SetIllusionBlock(Strings::ToBool(row[9])); SetIllusionBlock(Strings::ToBool(row[9]));
if (LFP) { LFP = Strings::ToInt(row[0]); } if (LFP) {
if (LFG) { LFG = Strings::ToInt(row[1]); } LFP = Strings::ToInt(row[0]);
if (row[3]) }
firstlogon = Strings::ToInt(row[3]);
if (LFG) {
LFG = Strings::ToInt(row[1]);
}
if (row[3]) {
first_login = Strings::ToUnsignedInt(row[3]);
}
if (row[10]) {
ingame = Strings::ToBool(row[10]);
}
} }
if (RuleB(Character, SharedBankPlat)) if (RuleB(Character, SharedBankPlat))
@@ -1720,7 +1743,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
// Taunt persists when zoning on newer clients, overwrite default. // Taunt persists when zoning on newer clients, overwrite default.
if (m_ClientVersionBit & EQ::versions::maskUFAndLater) { if (m_ClientVersionBit & EQ::versions::maskUFAndLater) {
if (!firstlogon) { if (!ingame) {
pet->SetTaunting(m_petinfo.taunting); pet->SetTaunting(m_petinfo.taunting);
} }
} }
+1 -1
View File
@@ -727,7 +727,7 @@ void Client::OnDisconnect(bool hard_disconnect) {
o->trade->Reset(); o->trade->Reset();
} }
database.SetFirstLogon(CharacterID(), 0); //We change firstlogon status regardless of if a player logs out to zone or not, because we only want to trigger it on their first login from world. database.SetIngame(CharacterID(), 0); //We change ingame status regardless of if a player logs out to zone or not, because we only want to trigger it on their first login from world.
/* Remove from all proximities */ /* Remove from all proximities */
ClearAllProximities(); ClearAllProximities();
+7
View File
@@ -2543,6 +2543,13 @@ void PerlembParser::ExportEventVariables(
break; break;
} }
case EVENT_CONNECT: {
Seperator sep(data);
ExportVar(package_name.c_str(), "last_login", sep.arg[0]);
ExportVar(package_name.c_str(), "is_first_login", sep.arg[1]);
break;
}
default: { default: {
break; break;
} }
+1
View File
@@ -353,6 +353,7 @@ LuaParser::LuaParser() {
PlayerArgumentDispatch[EVENT_AA_LOSS] = handle_player_aa_loss; PlayerArgumentDispatch[EVENT_AA_LOSS] = handle_player_aa_loss;
PlayerArgumentDispatch[EVENT_SPELL_BLOCKED] = handle_player_spell_blocked; PlayerArgumentDispatch[EVENT_SPELL_BLOCKED] = handle_player_spell_blocked;
PlayerArgumentDispatch[EVENT_READ_ITEM] = handle_player_read_item; PlayerArgumentDispatch[EVENT_READ_ITEM] = handle_player_read_item;
PlayerArgumentDispatch[EVENT_CONNECT] = handle_player_connect;
ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click; ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click;
ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click; ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click;
+17
View File
@@ -1809,6 +1809,23 @@ void handle_player_read_item(
} }
} }
void handle_player_connect(
QuestInterface *parse,
lua_State* L,
Client* client,
std::string data,
uint32 extra_data,
std::vector<std::any> *extra_pointers
)
{
Seperator sep(data.c_str());
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[0]));
lua_setfield(L, -2, "last_login");
lua_pushboolean(L, Strings::ToBool(sep.arg[1]));
lua_setfield(L, -2, "is_first_login");
}
// Item // Item
void handle_item_click( void handle_item_click(
QuestInterface *parse, QuestInterface *parse,
+9
View File
@@ -865,6 +865,15 @@ void handle_player_read_item(
std::vector<std::any> *extra_pointers std::vector<std::any> *extra_pointers
); );
void handle_player_connect(
QuestInterface *parse,
lua_State* L,
Client* client,
std::string data,
uint32 extra_data,
std::vector<std::any> *extra_pointers
);
// Item // Item
void handle_item_click( void handle_item_click(
QuestInterface *parse, QuestInterface *parse,