/** * EQEmulator: Everquest Server Emulator * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY except by those people which sell it, which * are required to give you total support for your newly bought product; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include "../common/net/websocket_server.h" #include "../common/eqemu_logsys.h" #include "zonedb.h" #include "../common/zone_store.h" #include "client.h" #include "entity.h" #include "corpse.h" #include "api_service.h" #include "npc.h" #include "object.h" #include "zone.h" #include "doors.h" #include extern Zone *zone; /** * @param connection * @param username * @param password * @return */ EQ::Net::WebsocketLoginStatus CheckLogin( EQ::Net::WebsocketServerConnection *connection, const std::string &username, const std::string &password ) { EQ::Net::WebsocketLoginStatus ret; ret.logged_in = false; std::string prefix = "eqemu"; ret.account_id = database.CheckLogin(username.c_str(), password.c_str(), prefix.c_str()); if (ret.account_id == 0) { return ret; } char account_name[64]; database.GetAccountName(static_cast(ret.account_id), account_name); ret.account_name = account_name; ret.logged_in = true; ret.status = database.CheckStatus(ret.account_id); return ret; } /** * @param connection * @param params * @return */ Json::Value ApiGetPacketStatistics(EQ::Net::WebsocketServerConnection *connection, Json::Value params) { if (zone->GetZoneID() == 0) { throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call"); } Json::Value response; auto &list = entity_list.GetClientList(); for (auto &iter : list) { auto client = iter.second; auto connection = client->Connection(); auto opts = connection->GetManager()->GetOptions(); auto eqs_stats = connection->GetStats(); auto &stats = eqs_stats.DaybreakStats; auto now = EQ::Net::Clock::now(); auto sec_since_stats_reset = std::chrono::duration_cast>( now - stats.created ).count(); Json::Value row; row["client_id"] = client->GetID(); row["client_name"] = client->GetCleanName(); row["seconds_since_reset"] = sec_since_stats_reset; row["sent_bytes"] = stats.sent_bytes; row["receive_bytes"] = stats.recv_bytes; row["min_ping"] = stats.min_ping; row["max_ping"] = stats.max_ping; row["last_ping"] = stats.last_ping; row["average_ping"] = stats.avg_ping; row["realtime_receive_packets"] = stats.recv_packets; row["realtime_sent_packets"] = stats.sent_packets; row["sync_recv_packets"] = stats.sync_recv_packets; row["sync_sent_packets"] = stats.sync_sent_packets; row["sync_remote_recv_packets"] = stats.sync_remote_recv_packets; row["sync_remote_sent_packets"] = stats.sync_remote_sent_packets; row["packet_loss_in"] = (100.0 * (1.0 - static_cast(stats.sync_recv_packets) / static_cast(stats.sync_remote_sent_packets))); row["packet_loss_out"] = (100.0 * (1.0 - static_cast(stats.sync_remote_recv_packets) / static_cast(stats.sync_sent_packets))); row["resent_packets"] = stats.resent_packets; row["resent_fragments"] = stats.resent_fragments; row["resent_non_fragments"] = stats.resent_full; row["dropped_datarate_packets"] = stats.dropped_datarate_packets; Json::Value sent_packet_types; for (auto i = 0; i < _maxEmuOpcode; ++i) { auto count = eqs_stats.SentCount[i]; if (count > 0) { sent_packet_types[OpcodeNames[i]] = count; } } Json::Value receive_packet_types; for (auto i = 0; i < _maxEmuOpcode; ++i) { auto count = eqs_stats.RecvCount[i]; if (count > 0) { receive_packet_types[OpcodeNames[i]] = count; } } row["sent_packet_types"] = sent_packet_types; row["receive_packet_types"] = receive_packet_types; response.append(row); } return response; } Json::Value ApiGetOpcodeList(EQ::Net::WebsocketServerConnection *connection, Json::Value params) { if (zone->GetZoneID() == 0) { throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call"); } Json::Value response; for (auto i = 0; i < _maxEmuOpcode; ++i) { Json::Value row = OpcodeNames[i]; response.append(row); } return response; } Json::Value ApiGetNpcListDetail(EQ::Net::WebsocketServerConnection *connection, Json::Value params) { if (zone->GetZoneID() == 0) { throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call"); } Json::Value response; auto &list = entity_list.GetNPCList(); for (auto &iter : list) { auto npc = iter.second; Json::Value row; /** * Main */ row["id"] = npc->GetID(); row["clean_name"] = npc->GetCleanName(); row["x"] = npc->GetX(); row["y"] = npc->GetY(); row["z"] = npc->GetZ(); row["heading"] = npc->GetHeading(); /** * Rest */ row["accuracy_rating"] = npc->GetAccuracyRating(); row["ai_has_spells"] = npc->AI_HasSpells(); row["ai_has_spells_effects"] = npc->AI_HasSpellsEffects(); row["ammo_id_file"] = npc->GetAmmoIDfile(); row["attack_delay"] = npc->GetAttackDelay(); row["attack_speed"] = npc->GetAttackSpeed(); row["avoidance_rating"] = npc->GetAvoidanceRating(); row["base_damage"] = npc->GetBaseDamage(); row["combat_event"] = npc->GetCombatEvent(); row["copper"] = npc->GetCopper(); row["count_loot"] = npc->CountLoot(); row["drops_global_loot"] = npc->DropsGlobalLoot(); row["gold"] = npc->GetGold(); row["grid"] = npc->GetGrid(); row["has_private_corpse"] = npc->HasPrivateCorpse(); row["is_animal"] = npc->IsAnimal(); row["is_guarding"] = npc->IsGuarding(); row["is_ldon_locked"] = npc->IsLDoNLocked(); row["is_ldon_trap_detected"] = npc->IsLDoNTrapDetected(); row["is_ldon_trapped"] = npc->IsLDoNTrapped(); row["is_merchant_open"] = npc->IsMerchantOpen(); row["is_not_targetable_with_hotkey"] = npc->IsNotTargetableWithHotkey(); row["is_proximity_set"] = npc->IsProximitySet(); row["is_taunting"] = npc->IsTaunting(); row["ldon_locked_skill"] = npc->GetLDoNLockedSkill(); row["ldon_trap_spell_id"] = npc->GetLDoNTrapSpellID(); row["ldon_trap_type"] = npc->GetLDoNTrapType(); row["loottable_id"] = npc->GetLoottableID(); row["max_dmg"] = npc->GetMaxDMG(); row["max_wp"] = npc->GetMaxWp(); row["min_damage"] = npc->GetMinDamage(); row["min_dmg"] = npc->GetMinDMG(); row["npc_spells_effects_id"] = npc->GetNPCSpellsEffectsID(); row["npc_spells_id"] = npc->GetNPCSpellsID(); row["npchp_regen"] = npc->GetNPCHPRegen(); row["num_merc_types"] = npc->GetNumMercTypes(); row["num_mercs"] = npc->GetNumMercs(); row["number_of_attacks"] = npc->GetNumberOfAttacks(); row["pet_spell_id"] = npc->GetPetSpellID(); row["platinum"] = npc->GetPlatinum(); row["prim_skill"] = npc->GetPrimSkill(); if (npc->IsProximitySet()) { row["proximity_max_x"] = npc->GetProximityMaxX(); row["proximity_max_y"] = npc->GetProximityMaxY(); row["proximity_max_z"] = npc->GetProximityMaxZ(); row["proximity_min_x"] = npc->GetProximityMinX(); row["proximity_min_y"] = npc->GetProximityMinY(); row["proximity_min_z"] = npc->GetProximityMinZ(); } row["ranged_skill"] = npc->GetRangedSkill(); row["raw_ac"] = npc->GetRawAC(); row["sec_skill"] = npc->GetSecSkill(); row["silver"] = npc->GetSilver(); row["slow_mitigation"] = npc->GetSlowMitigation(); row["spawn_group_id"] = npc->GetSpawnGroupId(); row["swarm_owner"] = npc->GetSwarmOwner(); row["swarm_target"] = npc->GetSwarmTarget(); row["waypoint_max"] = npc->GetWaypointMax(); row["will_aggro_npcs"] = npc->WillAggroNPCs(); response.append(row); } return response; } Json::Value ApiGetDoorListDetail(EQ::Net::WebsocketServerConnection *connection, Json::Value params) { if (zone->GetZoneID() == 0) { throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call"); } Json::Value response; auto &door_list = entity_list.GetDoorsList(); for (auto itr : door_list) { Doors *door = itr.second; Json::Value row; row["door_name"] = door->GetDoorName(); row["client_version_mask"] = door->GetClientVersionMask(); row["disable_timer"] = door->GetDisableTimer(); row["door_db_id"] = door->GetDoorDBID(); row["door_id"] = door->GetDoorID(); row["door_param"] = door->GetDoorParam(); row["entity_id"] = door->GetEntityID(); row["guild_id"] = door->GetGuildID(); row["incline"] = door->GetIncline(); row["invert_state"] = door->GetInvertState(); row["is_door"] = door->IsDoor(); row["is_door_open"] = door->IsDoorOpen(); row["is_ldon_door"] = door->IsLDoNDoor(); row["key_item"] = door->GetKeyItem(); row["lockpick"] = door->GetLockpick(); row["no_keyring"] = door->GetNoKeyring(); row["open_type"] = door->GetOpenType(); row["size"] = door->GetSize(); row["trigger_door_id"] = door->GetTriggerDoorID(); row["trigger_type"] = door->GetTriggerType(); row["x"] = door->GetX(); row["y"] = door->GetY(); row["z"] = door->GetZ(); response.append(row); } return response; } Json::Value ApiGetCorpseListDetail(EQ::Net::WebsocketServerConnection *connection, Json::Value params) { if (zone->GetZoneID() == 0) { throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call"); } Json::Value response; auto &corpse_list = entity_list.GetCorpseList(); for (auto itr : corpse_list) { auto corpse = itr.second; Json::Value row; row["char_id"] = corpse->GetCharID(); row["copper"] = corpse->GetCopper(); row["corpse_dbid"] = corpse->GetCorpseDBID(); row["count_items"] = corpse->CountItems(); row["decay_time"] = corpse->GetDecayTime(); row["gold"] = corpse->GetGold(); row["is_become_npc_corpse"] = corpse->IsBecomeNPCCorpse(); row["is_being_looted"] = corpse->IsBeingLooted(); row["is_corpse"] = corpse->IsCorpse(); row["is_locked"] = corpse->IsLocked(); row["is_npc_corpse"] = corpse->IsNPCCorpse(); row["is_player_corpse"] = corpse->IsPlayerCorpse(); row["is_rezzed"] = corpse->IsRezzed(); row["owner_name"] = corpse->GetOwnerName(); row["platinum"] = corpse->GetPlatinum(); row["player_kill_item"] = corpse->GetPlayerKillItem(); row["rez_exp"] = corpse->GetRezExp(); row["rez_time"] = corpse->GetRezTime(); row["silver"] = corpse->GetSilver(); response.append(row); } return response; } Json::Value ApiGetObjectListDetail(EQ::Net::WebsocketServerConnection *connection, Json::Value params) { if (zone->GetZoneID() == 0) { throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call"); } Json::Value response; auto &list = entity_list.GetObjectList(); for (auto &iter : list) { auto object = iter.second; Json::Value row; row["display_name"] = object->GetDisplayName(); row["dbid"] = object->GetDBID(); row["heading_data"] = object->GetHeadingData(); row["icon"] = object->GetIcon(); row["is_ground_spawn"] = object->IsGroundSpawn(); row["item_id"] = object->GetItemID(); row["model_name"] = object->GetModelName(); row["size"] = object->GetSize(); row["solid_type"] = object->GetSolidType(); row["tilt_x"] = object->GetTiltX(); row["tilt_y"] = object->GetTiltY(); row["type"] = object->GetType(); row["x"] = object->GetX(); row["y"] = object->GetY(); row["z"] = object->GetZ(); response.append(row); } return response; } Json::Value ApiGetMobListDetail(EQ::Net::WebsocketServerConnection *connection, Json::Value params) { if (zone->GetZoneID() == 0) { throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call"); } Json::Value response; auto &list = entity_list.GetMobList(); for (auto &iter : list) { auto mob = iter.second; Json::Value row; /** * Main */ row["id"] = mob->GetID(); row["clean_name"] = mob->GetCleanName(); row["x"] = mob->GetX(); row["y"] = mob->GetY(); row["z"] = mob->GetZ(); row["heading"] = mob->GetHeading(); /** * Rest */ row["ac"] = mob->GetAC(); row["ac_softcap"] = mob->GetACSoftcap(); row["ac_sum"] = mob->ACSum(); row["active_light_type"] = mob->GetActiveLightType(); row["aggro_range"] = mob->GetAggroRange(); row["allow_beneficial"] = mob->GetAllowBeneficial(); row["animation"] = mob->GetAnimation(); row["assist_range"] = mob->GetAssistRange(); row["aura_slots"] = mob->GetAuraSlots(); row["base_fear_speed"] = mob->GetBaseFearSpeed(); row["base_runspeed"] = mob->GetBaseRunspeed(); row["base_size"] = mob->GetBaseSize(); row["base_walkspeed"] = mob->GetBaseWalkspeed(); row["beard"] = mob->GetBeard(); row["beard_color"] = mob->GetBeardColor(); row["best_melee_skill"] = mob->GetBestMeleeSkill(); row["calc_fear_resist_chance"] = mob->CalcFearResistChance(); row["calc_resist_chance_bonus"] = mob->CalcResistChanceBonus(); row["can_block_spell"] = mob->CanBlockSpell(); row["can_facestab"] = mob->CanFacestab(); row["casted_spell_inv_slot"] = mob->GetCastedSpellInvSlot(); row["casting_spell_id"] = mob->CastingSpellID(); row["charmed"] = mob->Charmed(); row["check_last_los_state"] = mob->CheckLastLosState(); row["class"] = mob->GetClass(); row["class_level_factor"] = mob->GetClassLevelFactor(); row["class_race_ac_bonus"] = mob->GetClassRaceACBonus(); row["compute_defense"] = mob->compute_defense(); row["count_dispellable_buffs"] = mob->CountDispellableBuffs(); row["cripp_blow_chance"] = mob->GetCrippBlowChance(); row["cur_wp"] = mob->GetCurWp(); row["cwp"] = mob->GetCWP(); row["cwpp"] = mob->GetCWPP(); row["divine_aura"] = mob->DivineAura(); row["dont_buff_me_before"] = mob->DontBuffMeBefore(); row["dont_cure_me_before"] = mob->DontCureMeBefore(); row["dont_dot_me_before"] = mob->DontDotMeBefore(); row["dont_heal_me_before"] = mob->DontHealMeBefore(); row["dont_root_me_before"] = mob->DontRootMeBefore(); row["dont_snare_me_before"] = mob->DontSnareMeBefore(); row["drakkin_details"] = mob->GetDrakkinDetails(); row["drakkin_heritage"] = mob->GetDrakkinHeritage(); row["drakkin_tattoo"] = mob->GetDrakkinTattoo(); row["emote_id"] = mob->GetEmoteID(); row["equipment_light_type"] = mob->GetEquipmentLightType(); row["eye_color1"] = mob->GetEyeColor1(); row["eye_color2"] = mob->GetEyeColor2(); row["fear_speed"] = mob->GetFearSpeed(); row["flurry_chance"] = mob->GetFlurryChance(); row["follow_can_run"] = mob->GetFollowCanRun(); row["follow_distance"] = mob->GetFollowDistance(); row["follow_id"] = mob->GetFollowID(); row["gender"] = mob->GetGender(); row["hair_color"] = mob->GetHairColor(); row["hair_style"] = mob->GetHairStyle(); row["has_active_song"] = mob->HasActiveSong(); row["has_assist_aggro"] = mob->HasAssistAggro(); row["has_died"] = mob->HasDied(); row["has_disc_buff"] = mob->HasDiscBuff(); row["has_endur_upkeep"] = mob->HasEndurUpkeep(); row["has_free_aura_slots"] = mob->HasFreeAuraSlots(); row["has_free_trap_slots"] = mob->HasFreeTrapSlots(); row["has_mgb"] = mob->HasMGB(); row["has_numhits"] = mob->HasNumhits(); row["has_pet"] = mob->HasPet(); row["has_pet_affinity"] = mob->HasPetAffinity(); row["has_primary_aggro"] = mob->HasPrimaryAggro(); row["has_project_illusion"] = mob->HasProjectIllusion(); row["has_projectile_attack"] = mob->HasProjectileAttack(); row["has_shield_equiped"] = mob->HasShieldEquiped(); row["has_special_abilities"] = mob->HasSpecialAbilities(); row["has_tar_reflection"] = mob->HasTargetReflection(); row["has_temp_pets_active"] = mob->HasTempPetsActive(); row["has_two_hand_blunt_equiped"] = mob->HasTwoHandBluntEquiped(); row["has_two_hander_equipped"] = mob->HasTwoHanderEquipped(); row["hate_summon"] = mob->HateSummon(); row["helm_texture"] = mob->GetHelmTexture(); row["hp"] = mob->GetHP(); row["improved_taunt"] = mob->ImprovedTaunt(); row["innate_light_type"] = mob->GetInnateLightType(); row["is_ai_controlled"] = mob->IsAIControlled(); row["is_amnesiad"] = mob->IsAmnesiad(); row["is_animation"] = mob->IsAnimation(); row["is_blind"] = mob->IsBlind(); row["is_casting"] = mob->IsCasting(); row["is_charmed"] = mob->IsCharmed(); row["is_destructible_object"] = mob->IsDestructibleObject(); row["is_engaged"] = mob->IsEngaged(); row["is_enraged"] = mob->IsEnraged(); row["is_familiar"] = mob->IsFamiliar(); row["is_feared"] = mob->IsFeared(); row["is_findable"] = mob->IsFindable(); row["is_focused"] = mob->IsFocused(); row["is_g_held"] = mob->IsGHeld(); row["is_grouped"] = mob->IsGrouped(); row["is_held"] = mob->IsHeld(); row["is_looting"] = mob->IsLooting(); row["is_melee_disabled"] = mob->IsMeleeDisabled(); row["is_mezzed"] = mob->IsMezzed(); row["is_moved"] = mob->IsMoved(); row["is_moving"] = mob->IsMoving(); row["is_no_cast"] = mob->IsNoCast(); row["is_off_hand_atk"] = mob->IsOffHandAtk(); row["is_pet_owner_client"] = mob->IsPetOwnerClient(); row["is_pet_regroup"] = mob->IsPetRegroup(); row["is_pet_stop"] = mob->IsPetStop(); row["is_pseudo_rooted"] = mob->IsPseudoRooted(); row["is_raid_grouped"] = mob->IsRaidGrouped(); row["is_rare_spawn"] = mob->IsRareSpawn(); row["is_roamer"] = mob->IsRoamer(); row["is_rooted"] = mob->IsRooted(); row["is_running"] = mob->IsRunning(); row["is_silenced"] = mob->IsSilenced(); row["is_stunned"] = mob->IsStunned(); row["is_tar_lock_pet"] = mob->IsTargetLockPet(); row["is_tarable"] = mob->IsTargetable(); row["is_tared"] = mob->IsTargeted(); row["is_temp_pet"] = mob->IsTempPet(); row["is_trackable"] = mob->IsTrackable(); row["item_hp_bonuses"] = mob->GetItemHPBonuses(); row["last_name"] = mob->GetLastName(); row["level"] = mob->GetLevel(); row["luclin_face"] = mob->GetLuclinFace(); row["mana"] = mob->GetMana(); row["mana_percent"] = mob->GetManaPercent(); row["mana_ratio"] = mob->GetManaRatio(); row["max_hp"] = mob->GetMaxHP(); row["max_mana"] = mob->GetMaxMana(); row["melee_mitigation"] = mob->GetMeleeMitigation(); row["mitigation_ac"] = mob->GetMitigationAC(); row["movespeed"] = mob->GetMovespeed(); row["name"] = mob->GetName(); row["next_hp_event"] = mob->GetNextHPEvent(); row["next_inc_hp_event"] = mob->GetNextIncHPEvent(); row["npc_assist_cap"] = mob->NPCAssistCap(); row["npc_type_id"] = mob->GetNPCTypeID(); row["orig_level"] = mob->GetOrigLevel(); row["orig_name"] = mob->GetOrigName(); row["owner_id"] = mob->GetOwnerID(); row["pet_id"] = mob->GetPetID(); row["pet_power"] = mob->GetPetPower(); row["pet_tar_lock_id"] = mob->GetPetTargetLockID(); row["qglobal"] = mob->GetQglobal(); row["race"] = mob->GetRace(); row["run_anim_speed"] = mob->GetRunAnimSpeed(); row["sanctuary"] = mob->Sanctuary(); row["see_hide"] = mob->SeeHide(); row["see_improved_hide"] = mob->SeeImprovedHide(); row["see_invisible"] = mob->SeeInvisible(); row["see_invisible_undead"] = mob->SeeInvisibleUndead(); row["size"] = mob->GetSize(); row["slow_mitigation"] = mob->GetSlowMitigation(); row["snared_amount"] = mob->GetSnaredAmount(); row["spawned"] = mob->Spawned(); row["spell_hp_bonuses"] = mob->GetSpellHPBonuses(); row["spell_light_type"] = mob->GetSpellLightType(); row["spell_power_distance_mod"] = mob->GetSpellPowerDistanceMod(); row["spell_x"] = mob->GetSpellX(); row["spell_y"] = mob->GetSpellY(); row["spell_z"] = mob->GetSpellZ(); row["tar_ring_x"] = mob->GetTargetRingX(); row["tar_ring_y"] = mob->GetTargetRingY(); row["tar_ring_z"] = mob->GetTargetRingZ(); row["temp_pet_count"] = mob->GetTempPetCount(); row["texture"] = mob->GetTexture(); row["trap_slots"] = mob->GetTrapSlots(); row["try_death_save"] = mob->TryDeathSave(); row["try_divine_save"] = mob->TryDivineSave(); row["try_spell_on_death"] = mob->TrySpellOnDeath(); row["update_active_light"] = mob->UpdateActiveLight(); row["wander_type"] = mob->GetWanderType(); response.append(row); } return response; } Json::Value ApiGetClientListDetail(EQ::Net::WebsocketServerConnection *connection, Json::Value params) { if (zone->GetZoneID() == 0) { throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call"); } Json::Value response; auto &list = entity_list.GetClientList(); for (auto &iter : list) { auto client = iter.second; Json::Value row; /** * Main */ row["id"] = client->GetID(); row["clean_name"] = client->GetCleanName(); row["x"] = client->GetX(); row["y"] = client->GetY(); row["z"] = client->GetZ(); row["heading"] = client->GetHeading(); /** * Rest */ row["aa_percent"] = client->GetAAPercent(); row["aa_points"] = client->GetAAPoints(); row["aaxp"] = client->GetAAXP(); row["account_age"] = client->GetAccountAge(); row["account_creation"] = client->GetAccountCreation(); row["account_id"] = client->AccountID(); row["account_name"] = client->AccountName(); row["act_agi"] = client->GetActAGI(); row["act_cha"] = client->GetActCHA(); row["act_dex"] = client->GetActDEX(); row["act_int"] = client->GetActINT(); row["act_sta"] = client->GetActSTA(); row["act_str"] = client->GetActSTR(); row["act_wis"] = client->GetActWIS(); row["active_task_count"] = client->GetActiveTaskCount(); row["admin"] = client->Admin(); row["aggro_count"] = client->GetAggroCount(); row["aggro_meter_available"] = client->AggroMeterAvailable(); row["all_money"] = client->GetAllMoney(); row["anon"] = client->GetAnon(); row["atk_rating"] = client->GetATKRating(); row["auto_attack_enabled"] = client->AutoAttackEnabled(); row["auto_fire_enabled"] = client->AutoFireEnabled(); row["auto_split_enabled"] = client->AutoSplitEnabled(); row["base_agi"] = client->GetBaseAGI(); row["base_beard"] = client->GetBaseBeard(); row["base_beard_color"] = client->GetBaseBeardColor(); row["base_cha"] = client->GetBaseCHA(); row["base_class"] = client->GetBaseClass(); row["base_corrup"] = client->GetBaseCorrup(); row["base_details"] = client->GetBaseDetails(); row["base_dex"] = client->GetBaseDEX(); row["base_eye_color"] = client->GetBaseEyeColor(); row["base_face"] = client->GetBaseFace(); row["base_gender"] = client->GetBaseGender(); row["base_hair_color"] = client->GetBaseHairColor(); row["base_hair_style"] = client->GetBaseHairStyle(); row["base_heritage"] = client->GetBaseHeritage(); row["base_hp"] = client->GetBaseHP(); row["base_int"] = client->GetBaseINT(); row["base_ph_r"] = client->GetBasePhR(); row["base_race"] = client->GetBaseRace(); row["base_sta"] = client->GetBaseSTA(); row["base_str"] = client->GetBaseSTR(); row["base_tattoo"] = client->GetBaseTattoo(); row["base_wis"] = client->GetBaseWIS(); row["become_npc_level"] = client->GetBecomeNPCLevel(); row["boat_id"] = client->GetBoatID(); row["buyer_welcome_message"] = client->GetBuyerWelcomeMessage(); row["calc_atk"] = client->CalcATK(); row["calc_base_mana"] = client->CalcBaseMana(); row["calc_current_weight"] = client->CalcCurrentWeight(); row["calc_endurance_regen_cap"] = client->CalcEnduranceRegenCap(); row["calc_hp_regen_cap"] = client->CalcHPRegenCap(); row["calc_mana_regen_cap"] = client->CalcManaRegenCap(); row["calc_max_mana"] = client->CalcMaxMana(); row["can_fast_regen"] = client->CanFastRegen(); row["can_fish"] = client->CanFish(); row["can_med_on_horse"] = client->CanMedOnHorse(); row["carried_money"] = client->GetCarriedMoney(); row["char_max_level_from_bucket"] = client->GetCharMaxLevelFromBucket(); row["char_max_level_from_q_global"] = client->GetCharMaxLevelFromQGlobal(); row["character_id"] = client->CharacterID(); row["check_can_unsuspend_merc"] = client->CheckCanUnsuspendMerc(); row["check_double_attack"] = client->CheckDoubleAttack(); row["check_double_ranged_attack"] = client->CheckDoubleRangedAttack(); row["check_dual_wield"] = client->CheckDualWield(); row["check_trade_non_droppable"] = client->CheckTradeNonDroppable(); row["check_triple_attack"] = client->CheckTripleAttack(); row["client_max_level"] = client->GetClientMaxLevel(); row["client_version_bit"] = client->ClientVersionBit(); row["connected"] = client->Connected(); row["copper"] = client->GetCopper(); row["corpse_count"] = client->GetCorpseCount(); row["duel_tar"] = client->GetDuelTarget(); row["ebon_crystals"] = client->GetEbonCrystals(); row["endurance"] = client->GetEndurance(); row["endurance_percent"] = client->GetEndurancePercent(); row["exp"] = client->GetEXP(); row["face"] = client->GetFace(); row["feigned"] = client->GetFeigned(); row["gm"] = client->GetGM(); row["gm_speed"] = client->GetGMSpeed(); row["gold"] = client->GetGold(); row["group_exp"] = client->GetGroupEXP(); row["group_leadership_aa_health_enhancement"] = client->GroupLeadershipAAHealthEnhancement(); row["group_leadership_aa_health_regeneration"] = client->GroupLeadershipAAHealthRegeneration(); row["group_leadership_aa_mana_enhancement"] = client->GroupLeadershipAAManaEnhancement(); row["group_leadership_aa_offense_enhancement"] = client->GroupLeadershipAAOffenseEnhancement(); row["group_points"] = client->GetGroupPoints(); row["guild_id"] = client->GuildID(); row["guild_rank"] = client->GuildRank(); row["has_adventure_data"] = client->HasAdventureData(); row["hide_me"] = client->GetHideMe(); row["horse_id"] = client->GetHorseId(); row["hunger"] = client->GetHunger(); row["hungry"] = client->Hungry(); row["in_zone"] = client->InZone(); row["instance_id"] = client->GetInstanceID(); row["interrogate_inv_state"] = client->GetInterrogateInvState(); row["ip"] = client->GetIP(); row["is_become_npc"] = client->IsBecomeNPC(); row["is_buyer"] = client->IsBuyer(); row["is_dead"] = client->IsDead(); row["is_dragging_corpse"] = client->IsDraggingCorpse(); row["is_dueling"] = client->IsDueling(); row["is_guild_banker"] = client->IsGuildBanker(); row["is_hovering_for_respawn"] = client->IsHoveringForRespawn(); row["is_in_a_guild"] = client->IsInAGuild(); row["is_ld"] = client->IsLD(); row["is_leadership_exp_on"] = client->IsLeadershipEXPOn(); row["is_lfp"] = client->IsLFP(); row["is_medding"] = client->IsMedding(); row["is_on_adventure"] = client->IsOnAdventure(); row["is_rezz_pending"] = client->IsRezzPending(); row["is_sitting"] = client->IsSitting(); row["is_starved"] = client->IsStarved(); row["is_tracking"] = client->IsTracking(); row["is_trader"] = client->IsTrader(); row["is_unconscious"] = client->IsUnconscious(); row["ldon_losses"] = client->GetLDoNLosses(); row["ldon_wins"] = client->GetLDoNWins(); row["last_inv_snapshot_time"] = client->GetLastInvSnapshotTime(); row["last_name"] = client->GetLastName(); row["level2"] = client->GetLevel2(); row["level_regen"] = client->LevelRegen(); row["ls_account_id"] = client->LSAccountID(); row["max_endurance"] = client->GetMaxEndurance(); row["max_x_tars"] = client->GetMaxXTargets(); row["merc_id"] = client->GetMercID(); row["merc_only_or_no_group"] = client->MercOnlyOrNoGroup(); row["merc_slot"] = client->GetMercSlot(); row["next_inv_snapshot_time"] = client->GetNextInvSnapshotTime(); row["num_mercs"] = client->GetNumMercs(); row["pending_adventure_create"] = client->GetPendingAdventureCreate(); row["pending_adventure_door_click"] = client->GetPendingAdventureDoorClick(); row["pending_adventure_leave"] = client->GetPendingAdventureLeave(); row["pending_adventure_request"] = client->GetPendingAdventureRequest(); row["pending_guild_invitation"] = client->GetPendingGuildInvitation(); row["platinum"] = client->GetPlatinum(); row["port"] = client->GetPort(); row["primary_skill_value"] = client->GetPrimarySkillValue(); row["proximity_x"] = client->ProximityX(); row["proximity_y"] = client->ProximityY(); row["proximity_z"] = client->ProximityZ(); row["pvp_points"] = client->GetPVPPoints(); row["radiant_crystals"] = client->GetRadiantCrystals(); row["raid_exp"] = client->GetRaidEXP(); row["raid_points"] = client->GetRaidPoints(); row["raw_item_ac"] = client->GetRawItemAC(); row["required_aa_experience"] = client->GetRequiredAAExperience(); row["revoked"] = client->GetRevoked(); row["run_mode"] = client->GetRunMode(); row["save_currency"] = client->SaveCurrency(); row["save_task_state"] = client->SaveTaskState(); row["silver"] = client->GetSilver(); row["skill_points"] = client->GetSkillPoints(); row["spent_aa"] = client->GetSpentAA(); row["tgb"] = client->TGB(); row["thirst"] = client->GetThirst(); row["thirsty"] = client->Thirsty(); row["total_atk"] = client->GetTotalATK(); row["total_seconds_played"] = client->GetTotalSecondsPlayed(); row["weight"] = client->GetWeight(); row["wid"] = client->GetWID(); row["x_tarting_available"] = client->XTargettingAvailable(); response.append(row); } return response; } Json::Value ApiGetZoneAttributes(EQ::Net::WebsocketServerConnection *connection, Json::Value params) { if (zone->GetZoneID() == 0) { throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call"); } Json::Value response; Json::Value row; row["aggro_limit_reached"] = zone->AggroLimitReached(); row["allow_mercs"] = zone->AllowMercs(); row["buff_timers_suspended"] = zone->BuffTimersSuspended(); row["can_bind"] = zone->CanBind(); row["can_cast_outdoor"] = zone->CanCastOutdoor(); row["can_do_combat"] = zone->CanDoCombat(); row["can_levitate"] = zone->CanLevitate(); row["count_auth"] = zone->CountAuth(); row["count_spawn2"] = zone->CountSpawn2(); row["file_name"] = zone->GetFileName(); row["graveyard_id"] = zone->graveyard_id(); row["graveyard_zoneid"] = zone->graveyard_zoneid(); row["has_graveyard"] = zone->HasGraveyard(); row["has_map"] = zone->HasMap(); row["has_water_map"] = zone->HasWaterMap(); row["has_weather"] = zone->HasWeather(); row["instance_id"] = zone->GetInstanceID(); row["instance_version"] = zone->GetInstanceVersion(); row["instant_grids"] = zone->InstantGrids(); row["is_city"] = zone->IsCity(); row["is_hotzone"] = zone->IsHotzone(); row["is_instance_persistent"] = zone->IsInstancePersistent(); row["is_pvp_zone"] = zone->IsPVPZone(); row["is_static_zone"] = zone->IsStaticZone(); row["is_ucs_server_available"] = zone->IsUCSServerAvailable(); row["long_name"] = zone->GetLongName(); row["max_clients"] = zone->GetMaxClients(); row["mobs_aggro_count"] = zone->MobsAggroCount(); row["save_zone_cfg"] = zone->SaveZoneCFG(); row["short_name"] = zone->GetShortName(); row["total_blocked_spells"] = zone->GetZoneTotalBlockedSpells(); row["zone_id"] = zone->GetZoneID(); row["zone_type"] = zone->GetZoneType(); response.append(row); return response; } Json::Value ApiGetLogsysCategories(EQ::Net::WebsocketServerConnection *connection, Json::Value params) { if (!zone || (zone && zone->GetZoneID() == 0)) { throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call"); } Json::Value response; for (int i = 1; i < Logs::LogCategory::MaxCategoryID; i++) { Json::Value row; row["log_category_id"] = i; row["log_category_description"] = Logs::LogCategoryName[i]; row["log_to_console"] = LogSys.log_settings[i].log_to_console; row["log_to_file"] = LogSys.log_settings[i].log_to_file; row["log_to_gmsay"] = LogSys.log_settings[i].log_to_gmsay; response.append(row); } return response; } Json::Value ApiSetLoggingLevel(EQ::Net::WebsocketServerConnection *connection, Json::Value params) { if (zone->GetZoneID() == 0) { throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call"); } Json::Value response; auto logging_category = params[0].asInt(); auto logging_level = params[1].asInt(); response["status"] = "Category doesn't exist"; LogInfo("Logging category is [{}] and level is [{}]", logging_category, logging_level ); if (logging_category < Logs::LogCategory::MaxCategoryID && logging_category > Logs::LogCategory::None ) { LogSys.log_settings[logging_category].log_to_console = logging_level; response["status"] = "Category log level updated"; } if (logging_level > 0) { LogSys.log_settings[logging_category].is_category_enabled = 1; } else { LogSys.log_settings[logging_category].is_category_enabled = 0; } return response; } void RegisterApiLogEvent(std::unique_ptr &server) { LogSys.SetConsoleHandler( [&](uint16 log_category, const std::string &msg) { Json::Value data; data["log_category"] = log_category; data["msg"] = msg; server->DispatchEvent(EQ::Net::SubscriptionEventLog, data, 50); } ); } void RegisterApiService(std::unique_ptr &server) { server->SetLoginHandler(CheckLogin); server->SetMethodHandler("get_packet_statistics", &ApiGetPacketStatistics, 50); server->SetMethodHandler("get_opcode_list", &ApiGetOpcodeList, 50); server->SetMethodHandler("get_npc_list_detail", &ApiGetNpcListDetail, 50); server->SetMethodHandler("get_door_list_detail", &ApiGetDoorListDetail, 50); server->SetMethodHandler("get_corpse_list_detail", &ApiGetCorpseListDetail, 50); server->SetMethodHandler("get_object_list_detail", &ApiGetObjectListDetail, 50); server->SetMethodHandler("get_mob_list_detail", &ApiGetMobListDetail, 50); server->SetMethodHandler("get_client_list_detail", &ApiGetClientListDetail, 50); server->SetMethodHandler("get_zone_attributes", &ApiGetZoneAttributes, 50); server->SetMethodHandler("get_logsys_categories", &ApiGetLogsysCategories, 50); server->SetMethodHandler("set_logging_level", &ApiSetLoggingLevel, 50); RegisterApiLogEvent(server); }