diff --git a/common/ruletypes.h b/common/ruletypes.h index c5a4bb562..79e28c143 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -165,6 +165,7 @@ RULE_INT ( World, ExemptAccountLimitStatus, -1 ) //Min status required to be exe RULE_BOOL ( World, GMAccountIPList, false) // Check ip list against GM Accounts, AntiHack GM Accounts. RULE_INT ( World, MinGMAntiHackStatus, 1 ) //Minimum GM status to check against AntiHack list RULE_INT ( World, SoFStartZoneID, -1 ) //Sets the Starting Zone for SoF Clients separate from Titanium Clients (-1 is disabled) +RULE_INT ( World, TitaniumStartZoneID, -1) //Sets the Starting Zone for Titanium Clients (-1 is disabled). Replaces the old method. RULE_INT ( World, ExpansionSettings, 16383) // Sets the expansion settings for the server, This is sent on login to world and affects client expansion settings. Defaults to all expansions enabled up to TSS. RULE_INT ( World, PVPSettings, 0) // Sets the PVP settings for the server, 1 = Rallos Zek RuleSet, 2 = Tallon/Vallon Zek Ruleset, 4 = Sullon Zek Ruleset, 6 = Discord Ruleset, anything above 6 is the Discord Ruleset without the no-drop restrictions removed. TODO: Edit IsAttackAllowed in Zone to accomodate for these rules. RULE_BOOL (World, IsGMPetitionWindowEnabled, false) diff --git a/world/client.cpp b/world/client.cpp index 01130302d..1ceca8284 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -1439,33 +1439,27 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc) pp.pvp = database.GetServerType() == 1 ? 1 : 0; /* If it is an SoF Client and the SoF Start Zone rule is set, send new chars there */ - if (ClientVersionBit & BIT_SoFAndLater && RuleI(World, SoFStartZoneID) > 0) { + if (ClientVersionBit & BIT_SoFAndLater) { clog(WORLD__CLIENT,"Found 'SoFStartZoneID' rule setting: %i", RuleI(World, SoFStartZoneID)); - pp.zone_id = RuleI(World, SoFStartZoneID); - if (pp.zone_id) - database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z); - else - clog(WORLD__CLIENT_ERR,"Error getting zone id for Zone ID %i", RuleI(World, SoFStartZoneID)); - } else { - /* if there's a startzone variable put them in there */ - if (database.GetVariable("startzone", startzone, 50)) { - clog(WORLD__CLIENT,"Found 'startzone' variable setting: %s", startzone); - pp.zone_id = database.GetZoneID(startzone); - if (pp.zone_id) - database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z); - else - clog(WORLD__CLIENT_ERR,"Error getting zone id for '%s'", startzone); - } else { /* otherwise use normal starting zone logic */ - bool ValidStartZone = false; - if (ClientVersionBit & BIT_TitaniumAndEarlier) - ValidStartZone = database.GetStartZone(&pp, cc); - else - ValidStartZone = database.GetStartZoneSoF(&pp, cc); - - if (!ValidStartZone) - return false; + if (RuleI(World, SoFStartZoneID) > 0) { + pp.zone_id = RuleI(World, SoFStartZoneID); + cc->start_zone = pp.zone_id; } } + else { + clog(WORLD__CLIENT, "Found 'TitaniumStartZoneID' rule setting: %i", RuleI(World, TitaniumStartZoneID)); + if (RuleI(World, TitaniumStartZoneID) > 0) { /* if there's a startzone variable put them in there */ + + pp.zone_id = RuleI(World, TitaniumStartZoneID); + cc->start_zone = pp.zone_id; + } + } + /* use normal starting zone logic to either get defaults, or if startzone was set, load that from the db table.*/ + bool ValidStartZone = database.GetStartZone(&pp, cc, ClientVersionBit & BIT_TitaniumAndEarlier); + + if (!ValidStartZone){ + return false; + } /* just in case */ if (!pp.zone_id) { diff --git a/world/worlddb.cpp b/world/worlddb.cpp index 91406b527..73a7a284b 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -282,117 +282,38 @@ int WorldDatabase::MoveCharacterToBind(int CharID, uint8 bindnum) { return zone_id; } -bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc) + + +bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc,bool isTitanium) { + // SoF doesn't send the player_choice field in character creation, it now sends the real zoneID instead. + // + // For SoF, search for an entry in start_zones with a matching zone_id, class, race and deity. + // + // For now, if no row matching row is found, send them to Crescent Reach, as that is probably the most likely + // reason for no match being found. + // if(!in_pp || !in_cc) return false; in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0; in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = in_pp->binds[0].instance_id = 0; - std::string query = StringFormat("SELECT x, y, z, heading, zone_id, bind_id " - "FROM start_zones WHERE player_choice = % i " - "AND player_class = %i AND player_deity = %i " - "AND player_race = %i", - in_cc->start_zone, in_cc->class_, in_cc->deity, - in_cc->race); + //this is wrong. if start_zone is set we should use that id + std::string query = StringFormat("SELECT x, y, z, heading, start_zone, bind_id FROM start_zones WHERE zone_id = %i " + "AND player_class = %i AND player_deity = %i AND player_race = %i", + in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race); auto results = QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEmuLog::Error, "Start zone query failed: %s : %s\n", query.c_str(), results.ErrorMessage().c_str()); + LogFile->write(EQEmuLog::Status, "SoF Start zone query failed: %s : %s\n", query.c_str(), results.ErrorMessage().c_str()); return false; } - LogFile->write(EQEmuLog::Status, "Start zone query: %s\n", query.c_str()); + LogFile->write(EQEmuLog::Status, "SoF Start zone query: %s\n", query.c_str()); if (results.RowCount() == 0) { printf("No start_zones entry in database, using defaults\n"); - switch(in_cc->start_zone) - { - case 0: - { - in_pp->zone_id = 24; // erudnext - in_pp->binds[0].zoneId = 38; // tox - break; - } - case 1: - { - in_pp->zone_id = 2; // qeynos2 - in_pp->binds[0].zoneId = 2; // qeynos2 - break; - } - case 2: - { - in_pp->zone_id = 29; // halas - in_pp->binds[0].zoneId = 30; // everfrost - break; - } - case 3: - { - in_pp->zone_id = 19; // rivervale - in_pp->binds[0].zoneId = 20; // kithicor - break; - } - case 4: - { - in_pp->zone_id = 9; // freportw - in_pp->binds[0].zoneId = 9; // freportw - break; - } - case 5: - { - in_pp->zone_id = 40; // neriaka - in_pp->binds[0].zoneId = 25; // nektulos - break; - } - case 6: - { - in_pp->zone_id = 52; // gukta - in_pp->binds[0].zoneId = 46; // innothule - break; - } - case 7: - { - in_pp->zone_id = 49; // oggok - in_pp->binds[0].zoneId = 47; // feerrott - break; - } - case 8: - { - in_pp->zone_id = 60; // kaladima - in_pp->binds[0].zoneId = 68; // butcher - break; - } - case 9: - { - in_pp->zone_id = 54; // gfaydark - in_pp->binds[0].zoneId = 54; // gfaydark - break; - } - case 10: - { - in_pp->zone_id = 61; // felwithea - in_pp->binds[0].zoneId = 54; // gfaydark - break; - } - case 11: - { - in_pp->zone_id = 55; // akanon - in_pp->binds[0].zoneId = 56; // steamfont - break; - } - case 12: - { - in_pp->zone_id = 82; // cabwest - in_pp->binds[0].zoneId = 78; // fieldofbone - break; - } - case 13: - { - in_pp->zone_id = 155; // sharvahl - in_pp->binds[0].zoneId = 155; // sharvahl - break; - } - } + isTitanium ? SetTitaniumDefaultStartZone(in_pp, in_cc) : SetSoFDefaultStartZone(in_pp, in_cc); } else { LogFile->write(EQEmuLog::Status, "Found starting location in start_zones"); @@ -413,65 +334,106 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* return true; } - -bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc) -{ - // SoF doesn't send the player_choice field in character creation, it now sends the real zoneID instead. - // - // For SoF, search for an entry in start_zones with a matching zone_id, class, race and deity. - // - // For now, if no row matching row is found, send them to Crescent Reach, as that is probably the most likely - // reason for no match being found. - // - if(!in_pp || !in_cc) - return false; - - in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0; - in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = in_pp->binds[0].instance_id = 0; - - std::string query = StringFormat("SELECT x, y, z, heading, bind_id FROM start_zones WHERE zone_id = %i " - "AND player_class = %i AND player_deity = %i AND player_race = %i", - in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race); - auto results = QueryDatabase(query); - if(!results.Success()) { - LogFile->write(EQEmuLog::Status, "SoF Start zone query failed: %s : %s\n", query.c_str(), results.ErrorMessage().c_str()); - return false; - } - - LogFile->write(EQEmuLog::Status, "SoF Start zone query: %s\n", query.c_str()); - - if (results.RowCount() == 0) { - printf("No start_zones entry in database, using defaults\n"); - - if(in_cc->start_zone == RuleI(World, TutorialZoneID)) - in_pp->zone_id = in_cc->start_zone; - else { - in_pp->x = in_pp->binds[0].x = -51; - in_pp->y = in_pp->binds[0].y = -20; - in_pp->z = in_pp->binds[0].z = 0.79; - in_pp->zone_id = in_pp->binds[0].zoneId = 394; // Crescent Reach. - } - } - else { - LogFile->write(EQEmuLog::Status, "Found starting location in start_zones"); - auto row = results.begin(); - in_pp->x = atof(row[0]); - in_pp->y = atof(row[1]); - in_pp->z = atof(row[2]); - in_pp->heading = atof(row[3]); +void WorldDatabase::SetSoFDefaultStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc){ + if (in_cc->start_zone == RuleI(World, TutorialZoneID)) in_pp->zone_id = in_cc->start_zone; - in_pp->binds[0].zoneId = atoi(row[4]); + else { + in_pp->x = in_pp->binds[0].x = -51; + in_pp->y = in_pp->binds[0].y = -20; + in_pp->z = in_pp->binds[0].z = 0.79; + in_pp->zone_id = in_pp->binds[0].zoneId = 394; // Crescent Reach. + } +} +void WorldDatabase::SetTitaniumDefaultStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc) +{ + switch (in_cc->start_zone) + { + case 0: + { + in_pp->zone_id = 24; // erudnext + in_pp->binds[0].zoneId = 38; // tox + break; + } + case 1: + { + in_pp->zone_id = 2; // qeynos2 + in_pp->binds[0].zoneId = 2; // qeynos2 + break; + } + case 2: + { + in_pp->zone_id = 29; // halas + in_pp->binds[0].zoneId = 30; // everfrost + break; + } + case 3: + { + in_pp->zone_id = 19; // rivervale + in_pp->binds[0].zoneId = 20; // kithicor + break; + } + case 4: + { + in_pp->zone_id = 9; // freportw + in_pp->binds[0].zoneId = 9; // freportw + break; + } + case 5: + { + in_pp->zone_id = 40; // neriaka + in_pp->binds[0].zoneId = 25; // nektulos + break; + } + case 6: + { + in_pp->zone_id = 52; // gukta + in_pp->binds[0].zoneId = 46; // innothule + break; + } + case 7: + { + in_pp->zone_id = 49; // oggok + in_pp->binds[0].zoneId = 47; // feerrott + break; + } + case 8: + { + in_pp->zone_id = 60; // kaladima + in_pp->binds[0].zoneId = 68; // butcher + break; + } + case 9: + { + in_pp->zone_id = 54; // gfaydark + in_pp->binds[0].zoneId = 54; // gfaydark + break; + } + case 10: + { + in_pp->zone_id = 61; // felwithea + in_pp->binds[0].zoneId = 54; // gfaydark + break; + } + case 11: + { + in_pp->zone_id = 55; // akanon + in_pp->binds[0].zoneId = 56; // steamfont + break; + } + case 12: + { + in_pp->zone_id = 82; // cabwest + in_pp->binds[0].zoneId = 78; // fieldofbone + break; + } + case 13: + { + in_pp->zone_id = 155; // sharvahl + in_pp->binds[0].zoneId = 155; // sharvahl + break; + } } - - if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0) - database.GetSafePoints(in_pp->zone_id, 0, &in_pp->x, &in_pp->y, &in_pp->z); - - if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0) - database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z); - - return true; } - void WorldDatabase::GetLauncherList(std::vector &rl) { rl.clear(); diff --git a/world/worlddb.h b/world/worlddb.h index ecb39ef61..166248e72 100644 --- a/world/worlddb.h +++ b/world/worlddb.h @@ -28,9 +28,7 @@ struct CharacterSelect_Struct; class WorldDatabase : public SharedDatabase { public: - bool GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc); - bool GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc); - + bool GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc, bool isTitanium); void GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct*, uint32 ClientVersion); int MoveCharacterToBind(int CharID, uint8 bindnum = 0); @@ -40,8 +38,9 @@ public: bool LoadCharacterCreateAllocations(); bool LoadCharacterCreateCombos(); -protected: - +private: + void SetTitaniumDefaultStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc); + void SetSoFDefaultStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc); }; extern WorldDatabase database;