diff --git a/changelog.txt b/changelog.txt index 9917b0e2d..54c61f19f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -3,8 +3,21 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) == 1/20/2019 == Uleat: Added 'spells' entry to EQDictionary -Akkadius: Implement and extended #goto via #goto - this will work cross zone, cross instance, in zone etc. - It works on top of the original #goto (target) and #goto x y z +Akkadius: + - [Command] Extended #goto via #goto - + - This will work cross zone, cross instance, in zone etc. + - It works on top of the original #goto (target) and #goto x y z + - [Command] Implemented server side #who Example: https://bit.ly/2TZ2hvI + - Searches can be filtered by + - Account Name + - Base Class Name + - Guild Name + - IP + - Player Name + - Race Name + - Zone Short Name + - Features a clickable (Goto) saylink that will bring you directly to a player regardless of + whether or not they are in an instance == 1/15/2019 == Uleat: Activated per-expansion support for active inventory slot addressing diff --git a/common/classes.cpp b/common/classes.cpp index 58aa56602..be683fbd1 100644 --- a/common/classes.cpp +++ b/common/classes.cpp @@ -18,280 +18,382 @@ #include "../common/global_define.h" #include "../common/classes.h" -const char* GetClassIDName(uint8 class_id, uint8 level) +const char *GetClassIDName(uint8 class_id, uint8 level) { switch (class_id) { - case WARRIOR: - if (level >= 70) - return "Vanquisher"; - else if (level >= 65) - return "Overlord"; //Baron-Sprite: LEAVE MY CLASSES ALONE. - else if (level >= 60) - return "Warlord"; - else if (level >= 55) - return "Myrmidon"; - else if (level >= 51) - return "Champion"; - else - return "Warrior"; - case CLERIC: - if (level >= 70) - return "Prelate"; - else if (level >= 65) - return "Archon"; - else if (level >= 60) - return "High Priest"; - else if (level >= 55) - return "Templar"; - else if (level >= 51) - return "Vicar"; - else - return "Cleric"; - case PALADIN: - if (level >= 70) - return "Lord"; - else if (level >= 65) - return "Lord Protector"; - else if (level >= 60) - return "Crusader"; - else if (level >= 55) - return "Knight"; - else if (level >= 51) - return "Cavalier"; - else - return "Paladin"; - case RANGER: - if (level >= 70) - return "Plainswalker"; - else if (level >= 65) - return "Forest Stalker"; - else if (level >= 60) - return "Warder"; - else if (level >= 55) - return "Outrider"; - else if (level >= 51) - return "Pathfinder"; - else - return "Ranger"; - case SHADOWKNIGHT: - if (level >= 70) - return "Scourge Knight"; - else if (level >= 65) - return "Dread Lord"; - else if (level >= 60) - return "Grave Lord"; - else if (level >= 55) - return "Revenant"; - else if (level >= 51) - return "Reaver"; - else - return "Shadowknight"; - case DRUID: - if (level >= 70) - return "Natureguard"; - else if (level >= 65) - return "Storm Warden"; - else if (level >= 60) - return "Hierophant"; - else if (level >= 55) - return "Preserver"; - else if (level >= 51) - return "Wanderer"; - else - return "Druid"; - case MONK: - if (level >= 70) - return "Stone Fist"; - else if (level >= 65) - return "Transcendent"; - else if (level >= 60) - return "Grandmaster"; - else if (level >= 55) - return "Master"; - else if (level >= 51) - return "Disciple"; - else - return "Monk"; - case BARD: - if (level >= 70) - return "Performer"; - else if (level >= 65) - return "Maestro"; - else if (level >= 60) - return "Virtuoso"; - else if (level >= 55) - return "Troubadour"; - else if (level >= 51) - return "Minstrel"; - else - return "Bard"; - case ROGUE: - if (level >= 70) - return "Nemesis"; - else if (level >= 65) - return "Deceiver"; - else if (level >= 60) - return "Assassin"; - else if (level >= 55) - return "Blackguard"; - else if (level >= 51) - return "Rake"; - else - return "Rogue"; - case SHAMAN: - if (level >= 70) - return "Soothsayer"; - else if (level >= 65) - return "Prophet"; - else if (level >= 60) - return "Oracle"; - else if (level >= 55) - return "Luminary"; - else if (level >= 51) - return "Mystic"; - else - return "Shaman"; - case NECROMANCER: - if (level >= 70) - return "Wraith"; - else if (level >= 65) - return "Arch Lich"; - else if (level >= 60) - return "Warlock"; - else if (level >= 55) - return "Defiler"; - else if (level >= 51) - return "Heretic"; - else - return "Necromancer"; - case WIZARD: - if (level >= 70) - return "Grand Arcanist"; - else if (level >= 65) - return "Arcanist"; - else if (level >= 60) - return "Sorcerer"; - else if (level >= 55) - return "Evoker"; - else if (level >= 51) - return "Channeler"; - else - return "Wizard"; - case MAGICIAN: - if (level >= 70) - return "Arch Magus"; - else if (level >= 65) - return "Arch Convoker"; - else if (level >= 60) - return "Arch Mage"; - else if (level >= 55) - return "Conjurer"; - if (level >= 51) - return "Elementalist"; - else - return "Magician"; - case ENCHANTER: - if (level >= 70) - return "Bedazzler"; - else if (level >= 65) - return "Coercer"; - else if (level >= 60) - return "Phantasmist"; - else if (level >= 55) - return "Beguiler"; - else if (level >= 51) - return "Illusionist"; - else - return "Enchanter"; - case BEASTLORD: - if (level >= 70) - return "Wildblood"; - else if (level >= 65) - return "Feral Lord"; - else if (level >= 60) - return "Savage Lord"; - else if (level >= 55) - return "Animist"; - else if (level >= 51) - return "Primalist"; - else - return "Beastlord"; - case BERSERKER: - if (level >= 70) - return "Ravager"; - else if (level >= 65) - return "Fury"; - else if (level >= 60) - return "Rager"; - else if (level >= 55) - return "Vehement"; - else if (level >= 51) - return "Brawler"; - else - return "Berserker"; - case BANKER: - if (level >= 70) - return "Master Banker"; - else if (level >= 65) - return "Elder Banker"; - else if (level >= 60) - return "Oldest Banker"; - else if (level >= 55) - return "Older Banker"; - else if (level >= 51) - return "Old Banker"; - else - return "Banker"; - case WARRIORGM: - return "Warrior Guildmaster"; - case CLERICGM: - return "Cleric Guildmaster"; - case PALADINGM: - return "Paladin Guildmaster"; - case RANGERGM: - return "Ranger Guildmaster"; - case SHADOWKNIGHTGM: - return "Shadowknight Guildmaster"; - case DRUIDGM: - return "Druid Guildmaster"; - case MONKGM: - return "Monk Guildmaster"; - case BARDGM: - return "Bard Guildmaster"; - case ROGUEGM: - return "Rogue Guildmaster"; - case SHAMANGM: - return "Shaman Guildmaster"; - case NECROMANCERGM: - return "Necromancer Guildmaster"; - case WIZARDGM: - return "Wizard Guildmaster"; - case MAGICIANGM: - return "Magician Guildmaster"; - case ENCHANTERGM: - return "Enchanter Guildmaster"; - case BEASTLORDGM: - return "Beastlord Guildmaster"; - case BERSERKERGM: - return "Berserker Guildmaster"; - case MERCHANT: - return "Merchant"; - case ADVENTURERECRUITER: - return "Adventure Recruiter"; - case ADVENTUREMERCHANT: - return "Adventure Merchant"; - case CORPSE_CLASS: - return "Corpse Class"; - case TRIBUTE_MASTER: - return "Tribute Master"; - case GUILD_TRIBUTE_MASTER: - return "Guild Tribute Master"; - default: - return "Unknown"; + case WARRIOR: + if (level >= 70) { + return "Vanquisher"; + } + else if (level >= 65) { + return "Overlord"; //Baron-Sprite: LEAVE MY CLASSES ALONE. + } + else if (level >= 60) { + return "Warlord"; + } + else if (level >= 55) { + return "Myrmidon"; + } + else if (level >= 51) { + return "Champion"; + } + else { + return "Warrior"; + } + case CLERIC: + if (level >= 70) { + return "Prelate"; + } + else if (level >= 65) { + return "Archon"; + } + else if (level >= 60) { + return "High Priest"; + } + else if (level >= 55) { + return "Templar"; + } + else if (level >= 51) { + return "Vicar"; + } + else { + return "Cleric"; + } + case PALADIN: + if (level >= 70) { + return "Lord"; + } + else if (level >= 65) { + return "Lord Protector"; + } + else if (level >= 60) { + return "Crusader"; + } + else if (level >= 55) { + return "Knight"; + } + else if (level >= 51) { + return "Cavalier"; + } + else { + return "Paladin"; + } + case RANGER: + if (level >= 70) { + return "Plainswalker"; + } + else if (level >= 65) { + return "Forest Stalker"; + } + else if (level >= 60) { + return "Warder"; + } + else if (level >= 55) { + return "Outrider"; + } + else if (level >= 51) { + return "Pathfinder"; + } + else { + return "Ranger"; + } + case SHADOWKNIGHT: + if (level >= 70) { + return "Scourge Knight"; + } + else if (level >= 65) { + return "Dread Lord"; + } + else if (level >= 60) { + return "Grave Lord"; + } + else if (level >= 55) { + return "Revenant"; + } + else if (level >= 51) { + return "Reaver"; + } + else { + return "Shadowknight"; + } + case DRUID: + if (level >= 70) { + return "Natureguard"; + } + else if (level >= 65) { + return "Storm Warden"; + } + else if (level >= 60) { + return "Hierophant"; + } + else if (level >= 55) { + return "Preserver"; + } + else if (level >= 51) { + return "Wanderer"; + } + else { + return "Druid"; + } + case MONK: + if (level >= 70) { + return "Stone Fist"; + } + else if (level >= 65) { + return "Transcendent"; + } + else if (level >= 60) { + return "Grandmaster"; + } + else if (level >= 55) { + return "Master"; + } + else if (level >= 51) { + return "Disciple"; + } + else { + return "Monk"; + } + case BARD: + if (level >= 70) { + return "Performer"; + } + else if (level >= 65) { + return "Maestro"; + } + else if (level >= 60) { + return "Virtuoso"; + } + else if (level >= 55) { + return "Troubadour"; + } + else if (level >= 51) { + return "Minstrel"; + } + else { + return "Bard"; + } + case ROGUE: + if (level >= 70) { + return "Nemesis"; + } + else if (level >= 65) { + return "Deceiver"; + } + else if (level >= 60) { + return "Assassin"; + } + else if (level >= 55) { + return "Blackguard"; + } + else if (level >= 51) { + return "Rake"; + } + else { + return "Rogue"; + } + case SHAMAN: + if (level >= 70) { + return "Soothsayer"; + } + else if (level >= 65) { + return "Prophet"; + } + else if (level >= 60) { + return "Oracle"; + } + else if (level >= 55) { + return "Luminary"; + } + else if (level >= 51) { + return "Mystic"; + } + else { + return "Shaman"; + } + case NECROMANCER: + if (level >= 70) { + return "Wraith"; + } + else if (level >= 65) { + return "Arch Lich"; + } + else if (level >= 60) { + return "Warlock"; + } + else if (level >= 55) { + return "Defiler"; + } + else if (level >= 51) { + return "Heretic"; + } + else { + return "Necromancer"; + } + case WIZARD: + if (level >= 70) { + return "Grand Arcanist"; + } + else if (level >= 65) { + return "Arcanist"; + } + else if (level >= 60) { + return "Sorcerer"; + } + else if (level >= 55) { + return "Evoker"; + } + else if (level >= 51) { + return "Channeler"; + } + else { + return "Wizard"; + } + case MAGICIAN: + if (level >= 70) { + return "Arch Magus"; + } + else if (level >= 65) { + return "Arch Convoker"; + } + else if (level >= 60) { + return "Arch Mage"; + } + else if (level >= 55) { + return "Conjurer"; + } + if (level >= 51) { + return "Elementalist"; + } + else { + return "Magician"; + } + case ENCHANTER: + if (level >= 70) { + return "Bedazzler"; + } + else if (level >= 65) { + return "Coercer"; + } + else if (level >= 60) { + return "Phantasmist"; + } + else if (level >= 55) { + return "Beguiler"; + } + else if (level >= 51) { + return "Illusionist"; + } + else { + return "Enchanter"; + } + case BEASTLORD: + if (level >= 70) { + return "Wildblood"; + } + else if (level >= 65) { + return "Feral Lord"; + } + else if (level >= 60) { + return "Savage Lord"; + } + else if (level >= 55) { + return "Animist"; + } + else if (level >= 51) { + return "Primalist"; + } + else { + return "Beastlord"; + } + case BERSERKER: + if (level >= 70) { + return "Ravager"; + } + else if (level >= 65) { + return "Fury"; + } + else if (level >= 60) { + return "Rager"; + } + else if (level >= 55) { + return "Vehement"; + } + else if (level >= 51) { + return "Brawler"; + } + else { + return "Berserker"; + } + case BANKER: + if (level >= 70) { + return "Master Banker"; + } + else if (level >= 65) { + return "Elder Banker"; + } + else if (level >= 60) { + return "Oldest Banker"; + } + else if (level >= 55) { + return "Older Banker"; + } + else if (level >= 51) { + return "Old Banker"; + } + else { + return "Banker"; + } + case WARRIORGM: + return "Warrior Guildmaster"; + case CLERICGM: + return "Cleric Guildmaster"; + case PALADINGM: + return "Paladin Guildmaster"; + case RANGERGM: + return "Ranger Guildmaster"; + case SHADOWKNIGHTGM: + return "Shadowknight Guildmaster"; + case DRUIDGM: + return "Druid Guildmaster"; + case MONKGM: + return "Monk Guildmaster"; + case BARDGM: + return "Bard Guildmaster"; + case ROGUEGM: + return "Rogue Guildmaster"; + case SHAMANGM: + return "Shaman Guildmaster"; + case NECROMANCERGM: + return "Necromancer Guildmaster"; + case WIZARDGM: + return "Wizard Guildmaster"; + case MAGICIANGM: + return "Magician Guildmaster"; + case ENCHANTERGM: + return "Enchanter Guildmaster"; + case BEASTLORDGM: + return "Beastlord Guildmaster"; + case BERSERKERGM: + return "Berserker Guildmaster"; + case MERCHANT: + return "Merchant"; + case ADVENTURERECRUITER: + return "Adventure Recruiter"; + case ADVENTUREMERCHANT: + return "Adventure Merchant"; + case CORPSE_CLASS: + return "Corpse Class"; + case TRIBUTE_MASTER: + return "Tribute Master"; + case GUILD_TRIBUTE_MASTER: + return "Guild Tribute Master"; + default: + return "Unknown"; } } -const char* GetPlayerClassName(uint32 player_class_value, uint8 level) +const char *GetPlayerClassName(uint32 player_class_value, uint8 level) { return GetClassIDName(GetClassIDFromPlayerClassValue(player_class_value), level); } @@ -299,295 +401,295 @@ const char* GetPlayerClassName(uint32 player_class_value, uint8 level) uint32 GetPlayerClassValue(uint8 class_id) { switch (class_id) { - case WARRIOR: - case CLERIC: - case PALADIN: - case RANGER: - case SHADOWKNIGHT: - case DRUID: - case MONK: - case BARD: - case ROGUE: - case SHAMAN: - case NECROMANCER: - case WIZARD: - case MAGICIAN: - case ENCHANTER: - case BEASTLORD: - case BERSERKER: - return class_id; - default: - return PLAYER_CLASS_UNKNOWN; // watch + case WARRIOR: + case CLERIC: + case PALADIN: + case RANGER: + case SHADOWKNIGHT: + case DRUID: + case MONK: + case BARD: + case ROGUE: + case SHAMAN: + case NECROMANCER: + case WIZARD: + case MAGICIAN: + case ENCHANTER: + case BEASTLORD: + case BERSERKER: + return class_id; + default: + return PLAYER_CLASS_UNKNOWN; // watch } } uint32 GetPlayerClassBit(uint8 class_id) { switch (class_id) { - case WARRIOR: - return PLAYER_CLASS_WARRIOR_BIT; - case CLERIC: - return PLAYER_CLASS_CLERIC_BIT; - case PALADIN: - return PLAYER_CLASS_PALADIN_BIT; - case RANGER: - return PLAYER_CLASS_RANGER_BIT; - case SHADOWKNIGHT: - return PLAYER_CLASS_SHADOWKNIGHT_BIT; - case DRUID: - return PLAYER_CLASS_DRUID_BIT; - case MONK: - return PLAYER_CLASS_MONK_BIT; - case BARD: - return PLAYER_CLASS_BARD_BIT; - case ROGUE: - return PLAYER_CLASS_ROGUE_BIT; - case SHAMAN: - return PLAYER_CLASS_SHAMAN_BIT; - case NECROMANCER: - return PLAYER_CLASS_NECROMANCER_BIT; - case WIZARD: - return PLAYER_CLASS_WIZARD_BIT; - case MAGICIAN: - return PLAYER_CLASS_MAGICIAN_BIT; - case ENCHANTER: - return PLAYER_CLASS_ENCHANTER_BIT; - case BEASTLORD: - return PLAYER_CLASS_BEASTLORD_BIT; - case BERSERKER: - return PLAYER_CLASS_BERSERKER_BIT; - default: - return PLAYER_CLASS_UNKNOWN_BIT; + case WARRIOR: + return PLAYER_CLASS_WARRIOR_BIT; + case CLERIC: + return PLAYER_CLASS_CLERIC_BIT; + case PALADIN: + return PLAYER_CLASS_PALADIN_BIT; + case RANGER: + return PLAYER_CLASS_RANGER_BIT; + case SHADOWKNIGHT: + return PLAYER_CLASS_SHADOWKNIGHT_BIT; + case DRUID: + return PLAYER_CLASS_DRUID_BIT; + case MONK: + return PLAYER_CLASS_MONK_BIT; + case BARD: + return PLAYER_CLASS_BARD_BIT; + case ROGUE: + return PLAYER_CLASS_ROGUE_BIT; + case SHAMAN: + return PLAYER_CLASS_SHAMAN_BIT; + case NECROMANCER: + return PLAYER_CLASS_NECROMANCER_BIT; + case WIZARD: + return PLAYER_CLASS_WIZARD_BIT; + case MAGICIAN: + return PLAYER_CLASS_MAGICIAN_BIT; + case ENCHANTER: + return PLAYER_CLASS_ENCHANTER_BIT; + case BEASTLORD: + return PLAYER_CLASS_BEASTLORD_BIT; + case BERSERKER: + return PLAYER_CLASS_BERSERKER_BIT; + default: + return PLAYER_CLASS_UNKNOWN_BIT; } } uint8 GetClassIDFromPlayerClassValue(uint32 player_class_value) { switch (player_class_value) { - case PLAYER_CLASS_WARRIOR: - case PLAYER_CLASS_CLERIC: - case PLAYER_CLASS_PALADIN: - case PLAYER_CLASS_RANGER: - case PLAYER_CLASS_SHADOWKNIGHT: - case PLAYER_CLASS_DRUID: - case PLAYER_CLASS_MONK: - case PLAYER_CLASS_BARD: - case PLAYER_CLASS_ROGUE: - case PLAYER_CLASS_SHAMAN: - case PLAYER_CLASS_NECROMANCER: - case PLAYER_CLASS_WIZARD: - case PLAYER_CLASS_MAGICIAN: - case PLAYER_CLASS_ENCHANTER: - case PLAYER_CLASS_BEASTLORD: - case PLAYER_CLASS_BERSERKER: - return player_class_value; - default: - return PLAYER_CLASS_UNKNOWN; // watch + case PLAYER_CLASS_WARRIOR: + case PLAYER_CLASS_CLERIC: + case PLAYER_CLASS_PALADIN: + case PLAYER_CLASS_RANGER: + case PLAYER_CLASS_SHADOWKNIGHT: + case PLAYER_CLASS_DRUID: + case PLAYER_CLASS_MONK: + case PLAYER_CLASS_BARD: + case PLAYER_CLASS_ROGUE: + case PLAYER_CLASS_SHAMAN: + case PLAYER_CLASS_NECROMANCER: + case PLAYER_CLASS_WIZARD: + case PLAYER_CLASS_MAGICIAN: + case PLAYER_CLASS_ENCHANTER: + case PLAYER_CLASS_BEASTLORD: + case PLAYER_CLASS_BERSERKER: + return player_class_value; + default: + return PLAYER_CLASS_UNKNOWN; // watch } } uint8 GetClassIDFromPlayerClassBit(uint32 player_class_bit) { switch (player_class_bit) { - case PLAYER_CLASS_WARRIOR_BIT: - return WARRIOR; - case PLAYER_CLASS_CLERIC_BIT: - return CLERIC; - case PLAYER_CLASS_PALADIN_BIT: - return PALADIN; - case PLAYER_CLASS_RANGER_BIT: - return RANGER; - case PLAYER_CLASS_SHADOWKNIGHT_BIT: - return SHADOWKNIGHT; - case PLAYER_CLASS_DRUID_BIT: - return DRUID; - case PLAYER_CLASS_MONK_BIT: - return MONK; - case PLAYER_CLASS_BARD_BIT: - return BARD; - case PLAYER_CLASS_ROGUE_BIT: - return ROGUE; - case PLAYER_CLASS_SHAMAN_BIT: - return SHAMAN; - case PLAYER_CLASS_NECROMANCER_BIT: - return NECROMANCER; - case PLAYER_CLASS_WIZARD_BIT: - return WIZARD; - case PLAYER_CLASS_MAGICIAN_BIT: - return MAGICIAN; - case PLAYER_CLASS_ENCHANTER_BIT: - return ENCHANTER; - case PLAYER_CLASS_BEASTLORD_BIT: - return BEASTLORD; - case PLAYER_CLASS_BERSERKER_BIT: - return BERSERKER; - default: - return PLAYER_CLASS_UNKNOWN; // watch + case PLAYER_CLASS_WARRIOR_BIT: + return WARRIOR; + case PLAYER_CLASS_CLERIC_BIT: + return CLERIC; + case PLAYER_CLASS_PALADIN_BIT: + return PALADIN; + case PLAYER_CLASS_RANGER_BIT: + return RANGER; + case PLAYER_CLASS_SHADOWKNIGHT_BIT: + return SHADOWKNIGHT; + case PLAYER_CLASS_DRUID_BIT: + return DRUID; + case PLAYER_CLASS_MONK_BIT: + return MONK; + case PLAYER_CLASS_BARD_BIT: + return BARD; + case PLAYER_CLASS_ROGUE_BIT: + return ROGUE; + case PLAYER_CLASS_SHAMAN_BIT: + return SHAMAN; + case PLAYER_CLASS_NECROMANCER_BIT: + return NECROMANCER; + case PLAYER_CLASS_WIZARD_BIT: + return WIZARD; + case PLAYER_CLASS_MAGICIAN_BIT: + return MAGICIAN; + case PLAYER_CLASS_ENCHANTER_BIT: + return ENCHANTER; + case PLAYER_CLASS_BEASTLORD_BIT: + return BEASTLORD; + case PLAYER_CLASS_BERSERKER_BIT: + return BERSERKER; + default: + return PLAYER_CLASS_UNKNOWN; // watch } } bool IsFighterClass(uint8 class_id) { switch (class_id) { - case WARRIOR: - case PALADIN: - case RANGER: - case SHADOWKNIGHT: - case MONK: - case BARD: - case ROGUE: - case BEASTLORD: - case BERSERKER: - return true; - default: - return false; + case WARRIOR: + case PALADIN: + case RANGER: + case SHADOWKNIGHT: + case MONK: + case BARD: + case ROGUE: + case BEASTLORD: + case BERSERKER: + return true; + default: + return false; } } bool IsSpellFighterClass(uint8 class_id) { switch (class_id) { - case PALADIN: - case RANGER: - case SHADOWKNIGHT: - case BEASTLORD: - return true; - default: - return false; + case PALADIN: + case RANGER: + case SHADOWKNIGHT: + case BEASTLORD: + return true; + default: + return false; } } bool IsNonSpellFighterClass(uint8 class_id) { switch (class_id) { - case WARRIOR: - case MONK: - case BARD: - case ROGUE: - case BERSERKER: - return true; - default: - return false; + case WARRIOR: + case MONK: + case BARD: + case ROGUE: + case BERSERKER: + return true; + default: + return false; } } bool IsCasterClass(uint8 class_id) { switch (class_id) { - case CLERIC: - case DRUID: - case SHAMAN: - case NECROMANCER: - case WIZARD: - case MAGICIAN: - case ENCHANTER: - return true; - default: - return false; + case CLERIC: + case DRUID: + case SHAMAN: + case NECROMANCER: + case WIZARD: + case MAGICIAN: + case ENCHANTER: + return true; + default: + return false; } } bool IsINTCasterClass(uint8 class_id) { switch (class_id) { - case NECROMANCER: - case WIZARD: - case MAGICIAN: - case ENCHANTER: - return true; - default: - return false; + case NECROMANCER: + case WIZARD: + case MAGICIAN: + case ENCHANTER: + return true; + default: + return false; } } bool IsWISCasterClass(uint8 class_id) { switch (class_id) { - case CLERIC: - case DRUID: - case SHAMAN: - return true; - default: - return false; + case CLERIC: + case DRUID: + case SHAMAN: + return true; + default: + return false; } } bool IsPlateClass(uint8 class_id) { switch (class_id) { - case WARRIOR: - case CLERIC: - case PALADIN: - case SHADOWKNIGHT: - case BARD: - return true; - default: - return false; + case WARRIOR: + case CLERIC: + case PALADIN: + case SHADOWKNIGHT: + case BARD: + return true; + default: + return false; } } bool IsChainClass(uint8 class_id) { switch (class_id) { - case RANGER: - case ROGUE: - case SHAMAN: - case BERSERKER: - return true; - default: - return false; + case RANGER: + case ROGUE: + case SHAMAN: + case BERSERKER: + return true; + default: + return false; } } bool IsLeatherClass(uint8 class_id) { switch (class_id) { - case DRUID: - case MONK: - case BEASTLORD: - return true; - default: - return false; + case DRUID: + case MONK: + case BEASTLORD: + return true; + default: + return false; } } bool IsClothClass(uint8 class_id) { switch (class_id) { - case NECROMANCER: - case WIZARD: - case MAGICIAN: - case ENCHANTER: - return true; - default: - return false; + case NECROMANCER: + case WIZARD: + case MAGICIAN: + case ENCHANTER: + return true; + default: + return false; } } uint8 ClassArmorType(uint8 class_id) { switch (class_id) { - case WARRIOR: - case CLERIC: - case PALADIN: - case SHADOWKNIGHT: - case BARD: - return ARMOR_TYPE_PLATE; - case RANGER: - case ROGUE: - case SHAMAN: - case BERSERKER: - return ARMOR_TYPE_CHAIN; - case DRUID: - case MONK: - case BEASTLORD: - return ARMOR_TYPE_LEATHER; - case NECROMANCER: - case WIZARD: - case MAGICIAN: - case ENCHANTER: - return ARMOR_TYPE_CLOTH; - default: - return ARMOR_TYPE_UNKNOWN; + case WARRIOR: + case CLERIC: + case PALADIN: + case SHADOWKNIGHT: + case BARD: + return ARMOR_TYPE_PLATE; + case RANGER: + case ROGUE: + case SHAMAN: + case BERSERKER: + return ARMOR_TYPE_CHAIN; + case DRUID: + case MONK: + case BEASTLORD: + return ARMOR_TYPE_LEATHER; + case NECROMANCER: + case WIZARD: + case MAGICIAN: + case ENCHANTER: + return ARMOR_TYPE_CLOTH; + default: + return ARMOR_TYPE_UNKNOWN; } } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 797075108..7485d7451 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -809,6 +809,16 @@ void Client::CompleteConnect() std::string event_desc = StringFormat("Connect :: Logged into zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID()); QServ->PlayerLogEvent(Player_Log_Connect_State, this->CharacterID(), event_desc); } + + /** + * Update last login since this doesn't get updated until a late save later so we can update online status + */ + database.QueryDatabase( + StringFormat( + "UPDATE `character_data` SET `last_login` = UNIX_TIMESTAMP() WHERE id = %u", + this->CharacterID() + ) + ); } if (zone) { diff --git a/zone/command.cpp b/zone/command.cpp index d6e28ddf3..5224d4c83 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -413,6 +413,7 @@ int command_init(void) command_add("viewpetition", "[petition number] - View a petition", 20, command_viewpetition) || command_add("wc", "[wear slot] [material] - Sends an OP_WearChange for your target", 200, command_wc) || command_add("weather", "[0/1/2/3] (Off/Rain/Snow/Manual) - Change the weather", 80, command_weather) || + command_add("who", "[search]", 20, command_who) || command_add("worldshutdown", "- Shut down world and all zones", 200, command_worldshutdown) || command_add("wp", "[add/delete] [grid_num] [pause] [wp_num] [-h] - Add/delete a waypoint to/from a wandering grid", 170, command_wp) || command_add("wpadd", "[pause] [-h] - Add your current location as a waypoint to your NPC target's AI path", 170, command_wpadd) || @@ -2262,10 +2263,12 @@ void command_sendzonespawns(Client *c, const Seperator *sep) void command_zsave(Client *c, const Seperator *sep) { - if(zone->SaveZoneCFG()) + if (zone->SaveZoneCFG()) { c->Message(13, "Zone header saved successfully."); - else + } + else { c->Message(13, "ERROR: Zone header data was NOT saved."); + } } void command_dbspawn2(Client *c, const Seperator *sep) @@ -11837,6 +11840,126 @@ void command_scale(Client *c, const Seperator *sep) } } +void command_who(Client *c, const Seperator *sep) +{ + std::string query = + "SELECT\n" + " character_data.account_id,\n" + " character_data.name,\n" + " character_data.zone_id,\n" + " COALESCE((select zone.short_name from zone where zoneidnumber = character_data.zone_id LIMIT 1), \"Not Found\") as zone_name,\n" + " character_data.zone_instance,\n" + " COALESCE((select guilds.name from guilds where id = ((select guild_id from guild_members where char_id = character_data.id))), \"\") as guild_name,\n" + " character_data.level,\n" + " character_data.race,\n" + " character_data.class,\n" + " COALESCE((select account.status from account where account.id = character_data.account_id LIMIT 1), 0) as account_status,\n" + " COALESCE((select account.name from account where account.id = character_data.account_id LIMIT 1), \"\") as account_name,\n" + " COALESCE((select account_ip.ip from account_ip where account_ip.accid = character_data.account_id ORDER BY account_ip.lastused DESC LIMIT 1), \"\") as account_ip\n" + "FROM\n" + " character_data\n" + "WHERE\n" + " last_login > (UNIX_TIMESTAMP() - 600)\n" + "ORDER BY character_data.name;"; + + auto results = database.QueryDatabase(query); + if (!results.Success()) + return; + + if (results.RowCount() == 0) { + c->Message(15, "No results found"); + return; + } + + std::string search_string; + + if (sep->arg[1]) { + search_string = str_tolower(sep->arg[1]); + } + + int found_count = 0; + + c->Message(5, "Players in EverQuest"); + c->Message(5, "--------------------"); + + for (auto row = results.begin(); row != results.end(); ++row) { + auto account_id = static_cast(atoi(row[0])); + std::string player_name = row[1]; + auto zone_id = static_cast(atoi(row[2])); + std::string zone_short_name = row[3]; + auto zone_instance = static_cast(atoi(row[4])); + std::string guild_name = row[5]; + auto player_level = static_cast(atoi(row[6])); + auto player_race = static_cast(atoi(row[7])); + auto player_class = static_cast(atoi(row[8])); + auto account_status = static_cast(atoi(row[9])); + std::string account_name = row[10]; + std::string account_ip = row[11]; + + std::string base_class_name = GetClassIDName(static_cast(player_class), 1); + std::string displayed_race_name = GetRaceIDName(static_cast(player_race)); + + if (search_string.length() > 0) { + bool found_search_term = + ( + str_tolower(player_name).find(search_string) != std::string::npos || + str_tolower(zone_short_name).find(search_string) != std::string::npos || + str_tolower(displayed_race_name).find(search_string) != std::string::npos || + str_tolower(base_class_name).find(search_string) != std::string::npos || + str_tolower(guild_name).find(search_string) != std::string::npos || + str_tolower(account_name).find(search_string) != std::string::npos || + str_tolower(account_ip).find(search_string) != std::string::npos + ); + + if (!found_search_term) { + continue; + } + } + + std::string displayed_guild_name; + if (guild_name.length() > 0) { + displayed_guild_name = EQEmu::SayLinkEngine::GenerateQuestSaylink( + StringFormat( + "#who \"%s\"", + guild_name.c_str()), + false, + StringFormat("<%s>", guild_name.c_str()) + ); + } + + std::string goto_saylink = EQEmu::SayLinkEngine::GenerateQuestSaylink( + StringFormat("#goto %s", player_name.c_str()), false, "Goto" + ); + + std::string display_class_name = GetClassIDName(static_cast(player_class), static_cast(player_level)); + + c->Message( + 5, "%s[%u %s] %s (%s) %s ZONE: %s (%u) (%s) (%s) (%s)", + (account_status > 0 ? "* GM * " : ""), + player_level, + EQEmu::SayLinkEngine::GenerateQuestSaylink(StringFormat("#who %s", base_class_name.c_str()), false, display_class_name).c_str(), + player_name.c_str(), + EQEmu::SayLinkEngine::GenerateQuestSaylink(StringFormat("#who %s", displayed_race_name.c_str()), false, displayed_race_name).c_str(), + displayed_guild_name.c_str(), + EQEmu::SayLinkEngine::GenerateQuestSaylink(StringFormat("#who %s", zone_short_name.c_str()), false, zone_short_name).c_str(), + zone_instance, + goto_saylink.c_str(), + EQEmu::SayLinkEngine::GenerateQuestSaylink(StringFormat("#who %s", account_name.c_str()), false, account_name).c_str(), + EQEmu::SayLinkEngine::GenerateQuestSaylink(StringFormat("#who %s", account_ip.c_str()), false, account_ip).c_str() + ); + + found_count++; + } + + std::string message = ( + found_count > 0 ? + StringFormat("There is %i player(s) in EverQuest", found_count).c_str() : + "There are no players in EverQuest that match those who filters." + ); + + c->Message(5, message.c_str()); +} + // All new code added to command.cpp should be BEFORE this comment line. Do no append code to this file below the BOTS code block. #ifdef BOTS #include "bot_command.h" diff --git a/zone/command.h b/zone/command.h index 0a4eec014..ae029cc9d 100644 --- a/zone/command.h +++ b/zone/command.h @@ -325,6 +325,7 @@ void command_viewnpctype(Client *c, const Seperator *sep); void command_viewpetition(Client *c, const Seperator *sep); void command_wc(Client *c, const Seperator *sep); void command_weather(Client *c, const Seperator *sep); +void command_who(Client *c, const Seperator *sep); void command_worldshutdown(Client *c, const Seperator *sep); void command_wp(Client *c, const Seperator *sep); void command_wpadd(Client *c, const Seperator *sep);