* @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License V3 * @package SWDB */ require_once(PATH::ENTITY . "Entity.php"); require_once(PATH::ENTITY . "Unit.php"); require_once(PATH::ENTITY . "Building.php"); require_once(PATH::ENTITY . "Decoration.php"); require_once(PATH::ENTITY . "Item.php"); require_once(PATH::ENTITY . "Record.php"); require_once(PATH::ENTITY . "Server.php"); /** * A Player. * * Represents a game account. * * @category Entity */ class Player extends Entity{ /** * @var int User ID. */ private $user; /** * @var int In-game player ID. */ private $id; /** * @var int Account server ID. */ private $server; /** * @var string Account country code. */ private $country; /** * @var string Account language code. */ private $language; /** * @var int Player level. */ private $level; /** * @var string Player name. */ private $name; /** * @var int Total experience. */ private $experience; /** * @var Unit Player's representative unit. */ private $rep; /** * @var int Player's representative unit ID. */ private $rep_id; /** * @var DateTime Time the player joined the game. */ private $joined = 0; /** * @var int Player's top rank in the Arena. * @see ARENA_RANK_ID */ private $top_rank_arena = 0; /** * @var int Player's top rank in the World Arena. * @see ARENA_RANK_ID */ private $top_rank_world_arena = 0; /** * @var int Player's top rank in the Special League. * @see ARENA_RANK_ID */ private $top_rank_special_league = 0; /** * @var int Player's top rank in Guild War. * @see ARENA_RANK_ID */ private $top_rank_gw = 0; /** * @var int Player's top rank in the Siege Battle. * @see ARENA_RANK_ID */ private $top_rank_siege = 0; /** * @var int Player's top rank in World Boss * @see WORLD_BOSS_RANK_ID */ private $top_rank_wboss = 0; /** * @var int Top floor reached in the Trial of Ascension Normal. */ private $top_rank_toan = 0; /** * @var int Top floor reached in the Trial of Ascension Hard. */ private $top_rank_toah = 0; /** * @var int Maximum stars achieved in the Trial of Ascension Hell. */ private $top_rank_toal = 0; /** * @var bool Internal flag to chek if Arena, GW and Siege defenses have been read. */ private $flag_defense = false; /** * @var Unit[] Arena defense. */ private $arena_defense = []; /** * @var Unit[][] Guild War defenses. */ private $gw_defense = [[], []]; /** * @var Unit[] Siege defenses. */ private $siege_defense = []; /** * @var int[] Various currencies. */ private $currency = [ "mana" => 0, "crystal" => 0, "energy" => 0, "energy_max" => 0, "arena_energy" => 0, "darkportal_energy" => 0, "dimension_energy" => 0, "honor_point" => 0, "guild_point" => 0, "honor_medal" => 0, "honor_mark" => 0, "event_coin" => 0, "social_point" => 0, "ancient_stone" => 0, "costume_point" => 0, ]; /** * @var bool Internal flag to check if the buildings and decorations have been loaded into the * entity. */ private $flag_building = false; /** * @var Building[] Player's buildings. */ private $building = []; /** * @var Decoration[] Player's decorations. */ private $decoration = []; /** * @var bool Internal flags to check if various types of inventory items have been loaded into * the entity; */ private $flag_item = false; /** * @var Item[] Player's scrolls. */ private $item_scroll = []; /** * @var Item[] Player's rune craft materials.. */ private $item_craft_rune = []; /** * @var Item[] Player's craft materials. */ private $item_craft = []; /** * @var Item[] Player's essences. */ private $item_essence = []; /** * @var bool Internal flag to check if the player records have been loaded into the entity. */ private $flag_record = false; /** * @var Record[] Player records. */ private $record = []; /** * @var bool Indicates the profile visibility. */ private $public = false; /** * Constructor. * * Searches the database and retrieves the information about the * player, populating it and it's items. * * @param int $id Player identifier. */ public function __construct($id){ $statement = get_context()->get_db()->prepare(" SELECT user, id, server, country, lang, name, level, experience, rep, mana, crystal, energy, energy_max, arena_energy, darkportal_energy, dimension_energy, honor_point, guild_point, honor_medal, honor_mark, event_coin, social_point, costume_point, joined, top_rank_arena, top_rank_world_arena, top_rank_special_league, top_rank_gw, top_rank_siege, top_rank_wboss, top_rank_toan, top_rank_toah, top_rank_toal, public FROM player WHERE id = :id; "); $statement->bindValue(':id', $id, SQLITE3_TEXT); $r = $statement->execute()->fetchArray(SQLITE3_ASSOC); if ($r){ $this->user = $r["user"]; $this->id = $r["id"]; $this->server = new Server($r["server"]); $this->country = $r["country"]; $this->lang = $r["lang"]; $this->name = $r["name"]; $this->level = $r["level"]; $this->experience = $r["experience"]; if (strlen($r["rep"]) > 0){ $this->rep_id = $r["rep"]; } $this->currency["mana"] = $r["mana"]; $this->currency["crystal"] = $r["crystal"]; $this->currency["energy"] = $r["energy"]; $this->currency["energy_max"] = $r["energy_max"]; $this->currency["arena_energy"] = $r["arena_energy"]; $this->currency["darkportal_energy"] = $r["darkportal_energy"]; $this->currency["dimension_energy"] = $r["dimension_energy"]; $this->currency["honor_point"] = $r["honor_point"]; $this->currency["guild_point"] = $r["guild_point"]; $this->currency["honor_medal"] = $r["honor_medal"]; $this->currency["honor_mark"] = $r["honor_mark"]; $this->currency["event_coin"] = $r["event_coin"]; $this->currency["social_point"] = $r["social_point"]; $this->currency["costume_point"] = $r["costume_point"]; $this->joined = new Datetime(); $this->joined->setTimestamp($r["joined"]); $this->top_rank_arena = $r["top_rank_arena"]; $this->top_rank_world_arena = $r["top_rank_world_arena"]; $this->top_rank_special_league = $r["top_rank_special_league"]; $this->top_rank_gw = $r["top_rank_gw"]; $this->top_rank_siege = $r["top_rank_siege"]; $this->top_rank_wboss = $r["top_rank_wboss"]; $this->top_rank_toan = $r["top_rank_toan"]; $this->top_rank_toah = $r["top_rank_toah"]; $this->top_rank_toal = $r["top_rank_toal"]; if (strlen($r["public"]) == 1){ $this->public = true; } } } /** * Loads the defenses into the entity. * * Must be called only once before trying to get the units in Arena, Guild War or Siege * defenses. Sets the flag {@link Player:$flag_defenses} to true. */ private function load_defenses(){ $statement = get_context()->get_db()->prepare(" SELECT unit FROM defense WHERE player = :player AND area_type = :area_type ORDER BY position; "); $statement->bindValue(':player', $this->id, SQLITE3_TEXT); $statement->bindValue(':area_type', AREA_TYPE_ID::ARENA, SQLITE3_INTEGER); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ array_push($this->arena_defense, new Unit($r["unit"], false)); } $statement = get_context()->get_db()->prepare(" SELECT unit, slot FROM defense WHERE player = :player AND area_type = :area_type ORDER BY slot, position; "); $statement->bindValue(':player', $this->id, SQLITE3_TEXT); $statement->bindValue(':area_type', AREA_TYPE_ID::GUILD_WAR, SQLITE3_INTEGER); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ array_push($this->gw_defense[$r["slot"]], new Unit($r["unit"], false)); } // TODO: Siege defenses $statement = get_context()->get_db()->prepare(" SELECT unit, position FROM defense WHERE player = :player AND area_type = :area_type ORDER BY slot, position; "); $statement->bindValue(':player', $this->id, SQLITE3_TEXT); $statement->bindValue(':area_type', AREA_TYPE_ID::GUILD_SIEGE, SQLITE3_INTEGER); $q = $statement->execute(); $i = 0; $siege = [null, null, null]; while ($r = $q->fetchArray(SQLITE3_ASSOC)){ $siege[$i] = new Unit($r["unit"]); $i ++; if ($i == 3){ array_push($this->siege_defense, $siege); $i = 0; $siege = [null, null, null]; } } $this->flag_defense = true; } /** * Loads buildings and decorations into the entity. * * Must be called only once before trying to get the buildings or decorations. Sets the flag * {@link Player:$flag_defenses} to true. */ private function load_buildings(){ $statement = get_context()->get_db()->prepare(" SELECT building.id AS id, min(building.buildable) AS min FROM building, buildable WHERE player = :player AND building.buildable = buildable.id GROUP BY building.buildable; "); $statement->bindValue(':player', $this->id, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ array_push($this->building, new Building($r["id"])); } $statement = get_context()->get_db()->prepare(" SELECT id FROM decoration WHERE player = :player; "); $statement->bindValue(':player', $this->id, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ array_push($this->decoration, new Decoration($r["id"])); } $this->flag_building = true; } /** * Loads items into the entity. * * Must be called only once before trying to get any of the items in the inventory. Sets the * flag {@link Player:$flag_defenses} to true. */ private function load_items(){ $statement = get_context()->get_db()->prepare(" SELECT id, type FROM item WHERE player = :player AND type = :type AND amount > 0 ORDER BY item.type; "); $statement->bindValue(':player', $this->id, SQLITE3_TEXT); $statement->bindValue(':type', INVENTORY_TYPE_ID::SCROLL, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ array_push($this->item_scroll, new Item($this->id, $r["id"], $r["type"])); } // Rune crafting items are marked as generic crafting. $statement = get_context()->get_db()->prepare(" SELECT id, type FROM item WHERE player = :player AND type = :type AND amount > 0 ORDER BY id; "); $statement->bindValue(':player', $this->id, SQLITE3_TEXT); $statement->bindValue(':type', INVENTORY_TYPE_ID::ENCHANTMENT, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ array_push($this->item_craft_rune, new Item($this->id, $r["id"], $r["type"])); } $statement = get_context()->get_db()->prepare(" SELECT id, type FROM item WHERE player = :player AND type = :type AND amount > 0 ORDER BY id; "); $statement->bindValue(':player', $this->id, SQLITE3_TEXT); $statement->bindValue(':type', INVENTORY_TYPE_ID::CRAFT_STUFF, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ array_push($this->item_craft, new Item($this->id, $r["id"], $r["type"])); } $statement = get_context()->get_db()->prepare(" SELECT item.id AS id, item.type AS type FROM item, inventory WHERE item.id = inventory.id AND item.type = inventory.type AND item.player = :player AND item.type = :type AND amount > 0 ORDER BY upper(inventory.name) NOT LIKE '%MAGIC%', upper(inventory.name) NOT LIKE '%FIRE%', upper(inventory.name) NOT LIKE '%WATER%', upper(inventory.name) NOT LIKE '%WIND%', upper(inventory.name) NOT LIKE '%LIGHT%', upper(inventory.name) NOT LIKE '%DARK%', upper(inventory.name) NOT LIKE '%LOW%', upper(inventory.name) NOT LIKE '%MID%', upper(inventory.name) NOT LIKE '%HIGH%' ; "); $statement->bindValue(':player', $this->id, SQLITE3_TEXT); $statement->bindValue(':type', INVENTORY_TYPE_ID::ESSENCES, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ array_push($this->item_essence, new Item($this->id, $r["id"], $r["type"])); } $this->flag_item = true; } /** * Loads the records into the entity. * * Must be called only once before trying to get records. Sets the flag * {@link Player:$flag_defenses} to true. */ private function load_records(){ $statement = get_context()->get_db()->prepare(" SELECT player, area_type, area FROM record WHERE player = :player ORDER BY CASE WHEN (area_type = 2 AND area = 8001) THEN 1 -- Giant's Keep WHEN (area_type = 2 AND area = 9001) THEN 2 -- Dragon's Lair WHEN (area_type = 2 AND area = 6001) THEN 3 -- Necropolis WHEN (area_type = 2 AND area = 9501) THEN 4 -- Steel Fortress WHEN (area_type = 2 AND area = 9502) THEN 5 -- Punisher's Crypt WHEN (area_type = 4) THEN 6 -- Rift of Worlds WHEN (area_type = 3 AND area = 1001) THEN 7 -- Rift Dungeon - Ice Beast WHEN (area_type = 3 AND area = 2001) THEN 8 -- Rift Dungeon - Fire Beast WHEN (area_type = 3 AND area = 3001) THEN 9 -- Rift Dungeon - Wind Beast WHEN (area_type = 3 AND area = 4001) THEN 10 -- Rift Dungeon - Light Beast WHEN (area_type = 3 AND area = 5001) THEN 11 -- Rift Dungeon - Dark Beast WHEN (area_type = 2 AND area = 5001) THEN 12 -- Hall of Magic WHEN (area_type = 2 AND area = 3001) THEN 13 -- Hall of Water WHEN (area_type = 2 AND area = 2001) THEN 14 -- Hall of Fire WHEN (area_type = 2 AND area = 4001) THEN 15 -- Hall of Wind WHEN (area_type = 2 AND area = 7001) THEN 16 -- Hall of Light WHEN (area_type = 2 AND area = 1001) THEN 17 -- Hall of Dark ELSE area END ASC "); $statement->bindValue(':player', $this->id, SQLITE3_TEXT); $q = $statement->execute(); while ($r = $q->fetchArray(SQLITE3_ASSOC)){ array_push($this->record, new Record($r["player"], $r["area_type"], $r["area"])); } $this->flag_record = true; } /** * Retrieves the user identifier * * @return int User ID. */ public function get_user(){ return $this->user; } /** * Retrieves the player identifier * * @return int Player ID. */ public function get_id(){ return $this->id; } /** * Retrieves the player server. * * @return Server The player's account server. */ public function get_server(){ return $this->server; } /** * Retrieves the player's country. * * @return string Two digit country code. */ public function get_country(){ return $this->country; } /** * Retrieves the player's language. * * @return string Two digit language code. */ public function get_language(){ return $this->language; } /** * Retrieves the player's level, * * @return int Player's level */ public function get_level(){ return $this->level; } /** * Retrieves the player's name * * @return string The playe's name. */ public function get_name(){ return $this->name; } /** * Retrieves the total experience earned by the user. * * @return int Total experience. */ public function get_experience(){ return $this->experience; } /** * Retrieves the player's representative unit. * * @return Unit Player's representative */ public function get_rep(){ if ($this->rep_id != null && $this->rep == null){ $this->rep = new Unit($this->rep_id); } return $this->rep; } /** * Gets the date the user joined the game. * * If $format is supplied, a string in the desired format will be returned. If not, the raw * DateTime object will e returned. * * @param string $format A date format (optional). * @return DateTime | string The raw date, or a formatted version. */ public function get_joined($format = null){ if (null == $format){ return $this->joined; } else{ return $this->joined->format($format); } } /** * Retrieves the user's top rank in the Arena. * * @return int Top rank. */ public function get_top_rank_arena(){ return $this->top_rank_arena; } /** * Retrieves the user's top rank in the WorldArena. * * @return int Top rank. */ public function get_top_rank_world_arena(){ return $this->top_rank_world_arena; } /** * Retrieves the user's top rank in the Arena. * * @return int Top rank. */ public function get_top_rank_special_league(){ return $this->top_rank_special_league; } /** * Retrieves the user's top rank in Guild War. * * @return int Top rank. */ public function get_top_rank_gw(){ return $this->top_rank_gw; } /** * Retrieves the user's top rank in Siege battle. * * @return int Top rank. */ public function get_top_rank_siege(){ return $this->top_rank_siege; } /** * Retrieves the user's top rank in the World Boss. * * @return int Top rank. */ public function get_top_rank_wboss(){ return $this->top_rank_wboss; } /** * Retrieves the user's top rank in the Trial of Ascension (normal difficulty). * * @return int Top rank. */ public function get_top_rank_toan(){ return $this->top_rank_toan; } /** * Retrieves the user's top rank in the Trial of Ascension (hard difficulty). * * @return int Top rank. */ public function get_top_rank_toah(){ return $this->top_rank_toah; } /** * Retrieves the user's top rank in the Trial of Ascension (hell difficulty). * * @return int Top rank. */ public function get_top_rank_toal(){ return $this->top_rank_toal; } /** * Retrieves the Arena defense units. * * @return \Unit[] Units in the arena defense. */ public function get_arena_defense(){ if (!$this->flag_defense){ $this->load_defenses(); } return $this->arena_defense; } /** * Retrieves the Guild War defenses. * * @return Unit[][]: Units in Guild War defense, grouped by team. */ public function get_gw_defense(){ if (!$this->flag_defense){ $this->load_defenses(); } return $this->gw_defense; } /** * Retrieves the Guild War defenses. * * @return Unit[][]: Units in Siege Battle defense, grouped by team. */ public function get_siege_defense(){ if (!$this->flag_defense){ $this->load_defenses(); } return $this->siege_defense; } /** * Retrieves various currencies. * * @return int[] Array with the keys: mana, crystal, energy, energy_max, arena_energy, * darkportal_energy, dimension_energy, honor_point, guild_point, honor_medal, honor_mark, * event_coin, social_point, ancient_stone, costume_point, */ public function get_currencies(){ return $this->currency; } /** * Retrieves the list of buildings owned by the user. * * @return \Building[] Buildings owned. */ public function get_buildings(){ if (!$this->flag_building){ $this->load_buildings(); } return $this->building; } /** * Retrieves the list of decorations owned by the user. * * @return \Decoration[] Owned decorations. */ public function get_decorations(){ if (!$this->flag_building){ $this->load_buildings(); } return $this->decoration; } /** * Retrieves the list of owned scrolls. * * @return \Item[] Scrolls. */ public function get_scrolls(){ if (!$this->flag_item){ $this->load_items(); } return $this->item_scroll; } /** * Retrieves the list of rune crafting mateials. * * @return \Item[] Rune craft materials. */ public function get_rune_craft_materials(){ if (!$this->flag_item){ $this->load_items(); } return $this->item_craft_rune; } /** * Retrieves the list of crafting materials. * * @return \Item[] Crafting materials */ public function get_craft_materials(){ if (!$this->flag_item){ $this->load_items(); } return $this->item_craft; } /** * Retrieves the list of essences owned by the player. * * @return \Item[] Essences. */ public function get_essences(){ if (!$this->flag_item){ $this->load_items(); } return $this->item_essence; } /** * Retrieves the list of the player's records in the logbook. * * @return \Record[] List of records. */ public function get_records(){ if (!$this->flag_record){ $this->load_records(); } return $this->record; } /** * Checks if the player profile is public. * * @return bool True for public profile, false otherwise. */ public function is_public(){ return $this->public; } }