prepare(" INSERT INTO artifact ( uid, id, type, attribute, archetype, level, quality, original_quality, value, efficiency, max_efficiency, locked ) VALUES ( :uid, :id, :type, :attribute, :archetype, :level, :quality, :original_quality, :value, :efficiency, :max_efficiency, :locked ); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":id", $artifact->{"rid"}, SQLITE3_INTEGER); if (intval($artifact->{"attribute"}) == 0){ $statement->bindValue(":attribute", null, SQLITE3_INTEGER); } else{ $statement->bindValue(":attribute", $artifact->{"attribute"}, SQLITE3_INTEGER); } if (intval($artifact->{"type"}) == 0){ $statement->bindValue(":type", null, SQLITE3_INTEGER); } else{ $statement->bindValue(":type", $artifact->{"type"}, SQLITE3_INTEGER); } if (intval($artifact->{"unit_style"}) == 0){ $statement->bindValue(":archetype", null, SQLITE3_INTEGER); } else{ $statement->bindValue(":archetype", $artifact->{"unit_style"}, SQLITE3_INTEGER); } $statement->bindValue(":level", $artifact->{"level"}, SQLITE3_INTEGER); $statement->bindValue(":quality", $artifact->{"rank"}, SQLITE3_INTEGER); $statement->bindValue(":original_quality", $artifact->{"natural_rank"}, SQLITE3_INTEGER); // I don'k know the value formula, but value only depends on quality, so... hardcoding. switch ($artifact->{"natural_rank"}){ case QUALITY_ID::LEGEND: $statement->bindValue(":value", 37660, SQLITE3_INTEGER); break; case QUALITY_ID::HERO: $statement->bindValue(":value", 25250, SQLITE3_INTEGER); break; case QUALITY_ID::RARE: $statement->bindValue(":value", 18461, SQLITE3_INTEGER); break; case QUALITY_ID::MAGIC: $statement->bindValue(":value", 9330, SQLITE3_INTEGER); break; default: $statement->bindValue(":value", 3870, SQLITE3_INTEGER); } $statement->bindValue(":locked", $artifact->{"locked"}, SQLITE3_INTEGER); // Efficienccis will be caculated later, when instantiating the artifact. $statement->bindValue(":efficiency", 0, SQLITE3_FLOAT); $statement->bindValue(":max_efficiency", 0, SQLITE3_FLOAT); $statement->execute(); // Main stat $statement = $db->prepare(" INSERT INTO artifact_stat ( artifact, stat, value ) VALUES ( :artifact, :stat, :value ); "); $statement->bindValue(":artifact", $artifact->{"rid"}, SQLITE3_INTEGER); $statement->bindValue(":stat", $artifact->{"pri_effect"}[0], SQLITE3_INTEGER); $statement->bindValue(":value", $artifact->{"pri_effect"}[1], SQLITE3_INTEGER); $statement->execute(); // Base effect insert query $effect_query = " INSERT INTO artifact_effect ( artifact, slot, effect, value, enchant, grind, rolls ) VALUES ( :artifact, :slot, :effect, :value, :enchant, :grind, :rolls ); "; // Effect 1 if (sizeof($artifact->{"sec_effects"}) > 0){ $statement = $db->prepare($effect_query); $statement->bindValue(":artifact", $artifact->{"rid"}, SQLITE3_INTEGER); $statement->bindValue(":slot", ARTIFACT_EFFECT_SLOT_ID::EFFECT_1, SQLITE3_INTEGER); $statement->bindValue(":effect", $artifact->{"sec_effects"}[0][0], SQLITE3_INTEGER); $statement->bindValue(":value", $artifact->{"sec_effects"}[0][1], SQLITE3_INTEGER); $statement->bindValue(":grind", $artifact->{"sec_effects"}[0][2], SQLITE3_INTEGER); $statement->bindValue(":enchant", $artifact->{"sec_effects"}[0][3], SQLITE3_INTEGER); $statement->bindValue(":rolls", 0, SQLITE3_INTEGER); $statement->execute(); } // Effect 2 if (sizeof($artifact->{"sec_effects"}) > 1){ $statement = $db->prepare($effect_query); $statement->bindValue(":artifact", $artifact->{"rid"}, SQLITE3_INTEGER); $statement->bindValue(":slot", ARTIFACT_EFFECT_SLOT_ID::EFFECT_2, SQLITE3_INTEGER); $statement->bindValue(":effect", $artifact->{"sec_effects"}[1][0], SQLITE3_INTEGER); $statement->bindValue(":value", $artifact->{"sec_effects"}[1][1], SQLITE3_INTEGER); $statement->bindValue(":grind", $artifact->{"sec_effects"}[1][2], SQLITE3_INTEGER); $statement->bindValue(":enchant", $artifact->{"sec_effects"}[1][3], SQLITE3_INTEGER); $statement->bindValue(":rolls", 0, SQLITE3_INTEGER); $statement->execute(); } // Effect 3 if (sizeof($artifact->{"sec_effects"}) > 2){ $statement = $db->prepare($effect_query); $statement->bindValue(":artifact", $artifact->{"rid"}, SQLITE3_INTEGER); $statement->bindValue(":slot", ARTIFACT_EFFECT_SLOT_ID::EFFECT_3, SQLITE3_INTEGER); $statement->bindValue(":effect", $artifact->{"sec_effects"}[2][0], SQLITE3_INTEGER); $statement->bindValue(":value", $artifact->{"sec_effects"}[2][1], SQLITE3_INTEGER); $statement->bindValue(":grind", $artifact->{"sec_effects"}[2][2], SQLITE3_INTEGER); $statement->bindValue(":enchant", $artifact->{"sec_effects"}[2][3], SQLITE3_INTEGER); $statement->bindValue(":rolls", 0, SQLITE3_INTEGER); $statement->execute(); } // Effect 4 if (sizeof($artifact->{"sec_effects"}) > 3){ $statement = $db->prepare($effect_query); $statement->bindValue(":artifact", $artifact->{"rid"}, SQLITE3_INTEGER); $statement->bindValue(":slot", ARTIFACT_EFFECT_SLOT_ID::EFFECT_4, SQLITE3_INTEGER); $statement->bindValue(":effect", $artifact->{"sec_effects"}[3][0], SQLITE3_INTEGER); $statement->bindValue(":value", $artifact->{"sec_effects"}[3][1], SQLITE3_INTEGER); $statement->bindValue(":grind", $artifact->{"sec_effects"}[3][2], SQLITE3_INTEGER); $statement->bindValue(":enchant", $artifact->{"sec_effects"}[3][3], SQLITE3_INTEGER); $statement->bindValue(":rolls", 0, SQLITE3_INTEGER); $statement->execute(); } // Instantiate and calculate efficiency: $instance = new Artifact($artifact->{"rid"}); // Assigned? if (intval($artifact->{"occupied_id"}) != 0){ $statement = $db->prepare(" INSERT INTO unit_artifact (unit, artifact, rta) VALUES (:unit, :artifact, :rta); "); $statement->bindValue(":unit", $artifact->{"occupied_id"}, SQLITE3_INTEGER); $statement->bindValue(":artifact", $artifact->{"rid"}, SQLITE3_INTEGER); $statement->bindValue(":rta", GAME_MODE_ID::NORMAL, SQLITE3_INTEGER); $statement->execute(); } } /** * Parses a rune and saves it to the database. * * @param string $uid Owner ID. * @param JSON rune JSON fragment of the rune. */ function parse_rune($uid, $rune, $lock_list){ global $db; $statement = $db->prepare(" INSERT INTO rune ( uid, id, type, slot, stars, ancient, level, quality, original_quality, value, efficiency, max_efficiency, locked ) VALUES ( :uid, :id, :type, :slot, :stars, :ancient, :level, :quality, :original_quality, :value, :efficiency, :max_efficiency, :locked ); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":id", $rune->{"rune_id"}, SQLITE3_INTEGER); $statement->bindValue(":type", $rune->{"set_id"}, SQLITE3_INTEGER); $statement->bindValue(":slot", $rune->{"slot_no"}, SQLITE3_INTEGER); $statement->bindValue(":value", $rune->{"sell_value"}, SQLITE3_INTEGER); if ($rune->{"class"} > 10){ // Ancient rune $statement->bindValue(":ancient", 1, SQLITE3_INTEGER); $statement->bindValue(":stars", intval($rune->{"class"}) - 10, SQLITE3_INTEGER); $statement->bindValue(":original_quality", intval($rune->{"extra"}) - 10, SQLITE3_INTEGER); } else{ // Non Ancient rune $statement->bindValue(":ancient", 0, SQLITE3_INTEGER); $statement->bindValue(":stars", $rune->{"class"}, SQLITE3_INTEGER); $statement->bindValue(":original_quality", $rune->{"extra"}, SQLITE3_INTEGER); } $level = $rune->{"upgrade_curr"}; $statement->bindValue(":level", $level, SQLITE3_INTEGER); $quality = QUALITY_ID::NORMAL; if ($level >= 12){ $quality = QUALITY_ID::LEGEND; } elseif ($level >= 9){ $quality = QUALITY_ID::HERO; } elseif ($level >= 6){ $quality = QUALITY_ID::RARE; } elseif ($level >= 3){ $quality = QUALITY_ID::MAGIC; } if ($rune->{"extra"} > $quality){ $quality = $rune->{"extra"}; } $statement->bindValue(":quality", $quality, SQLITE3_INTEGER); $lock = 0; if (in_array($rune->{"rune_id"}, $lock_list)){ $lock = 1; } $statement->bindValue(":locked", $lock, SQLITE3_INTEGER); $efficiency = null; $max_efficiency = null; $statement->bindValue(":efficiency", $efficiency, SQLITE3_FLOAT); $statement->bindValue(":max_efficiency", $max_efficiency, SQLITE3_FLOAT); $statement->execute(); $stat_statement = " INSERT INTO rune_stat (rune, slot, stat, value, enchant, grind, rolls) VALUES (:rune, :slot, :stat, :value, :enchant, :grind, :rolls); "; // Main stat $statement = $db->prepare($stat_statement); $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER); $statement->bindValue(":slot", RUNE_STAT_SLOT_ID::MAIN, SQLITE3_INTEGER); $statement->bindValue(":stat", $rune->{"pri_eff"}[0], SQLITE3_INTEGER); $statement->bindValue(":value", $rune->{"pri_eff"}[1], SQLITE3_INTEGER); $statement->bindValue(":enchant", 0, SQLITE3_INTEGER); $statement->bindValue(":grind", 0, SQLITE3_INTEGER); $statement->bindValue(":rolls", 0, SQLITE3_INTEGER); $statement->execute(); // Innate stat if ($rune->{"prefix_eff"}[0] > 0){ // Main stat $statement = $db->prepare($stat_statement); $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER); $statement->bindValue(":slot", RUNE_STAT_SLOT_ID::INNATE, SQLITE3_INTEGER); $statement->bindValue(":stat", $rune->{"prefix_eff"}[0], SQLITE3_INTEGER); $statement->bindValue(":value", $rune->{"prefix_eff"}[1], SQLITE3_INTEGER); $statement->bindValue(":enchant", 0, SQLITE3_INTEGER); $statement->bindValue(":grind", 0, SQLITE3_INTEGER); $statement->bindValue(":rolls", 0, SQLITE3_INTEGER); $statement->execute(); } if (sizeof($rune->{"sec_eff"}) > 0){ $statement = $db->prepare($stat_statement); $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER); $statement->bindValue(":slot", RUNE_STAT_SLOT_ID::SUBSTAT_1, SQLITE3_INTEGER); $statement->bindValue(":stat", $rune->{"sec_eff"}[0][0], SQLITE3_INTEGER); $statement->bindValue(":value", $rune->{"sec_eff"}[0][1], SQLITE3_INTEGER); $statement->bindValue(":enchant", $rune->{"sec_eff"}[0][2], SQLITE3_INTEGER); $statement->bindValue(":grind", $rune->{"sec_eff"}[0][3], SQLITE3_INTEGER); // TODO: Calculate rolls $statement->bindValue(":rolls", 0, SQLITE3_INTEGER); $statement->execute(); } if (sizeof($rune->{"sec_eff"}) > 1){ $statement = $db->prepare($stat_statement); $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER); $statement->bindValue(":slot", RUNE_STAT_SLOT_ID::SUBSTAT_2, SQLITE3_INTEGER); $statement->bindValue(":stat", $rune->{"sec_eff"}[1][0], SQLITE3_INTEGER); $statement->bindValue(":value", $rune->{"sec_eff"}[1][1], SQLITE3_INTEGER); $statement->bindValue(":enchant", $rune->{"sec_eff"}[1][2], SQLITE3_INTEGER); $statement->bindValue(":grind", $rune->{"sec_eff"}[1][3], SQLITE3_INTEGER); // TODO: Calculate rolls $statement->bindValue(":rolls", 0, SQLITE3_INTEGER); $statement->execute(); } if (sizeof($rune->{"sec_eff"}) > 2){ $statement = $db->prepare($stat_statement); $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER); $statement->bindValue(":slot", RUNE_STAT_SLOT_ID::SUBSTAT_3, SQLITE3_INTEGER); $statement->bindValue(":stat", $rune->{"sec_eff"}[2][0], SQLITE3_INTEGER); $statement->bindValue(":value", $rune->{"sec_eff"}[2][1], SQLITE3_INTEGER); $statement->bindValue(":enchant", $rune->{"sec_eff"}[2][2], SQLITE3_INTEGER); $statement->bindValue(":grind", $rune->{"sec_eff"}[2][3], SQLITE3_INTEGER); // TODO: Calculate rolls $statement->bindValue(":rolls", 0, SQLITE3_INTEGER); $statement->execute(); } if (sizeof($rune->{"sec_eff"}) > 3){ $statement = $db->prepare($stat_statement); $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER); $statement->bindValue(":slot", RUNE_STAT_SLOT_ID::SUBSTAT_4, SQLITE3_INTEGER); $statement->bindValue(":stat", $rune->{"sec_eff"}[3][0], SQLITE3_INTEGER); $statement->bindValue(":value", $rune->{"sec_eff"}[3][1], SQLITE3_INTEGER); $statement->bindValue(":enchant", $rune->{"sec_eff"}[3][2], SQLITE3_INTEGER); $statement->bindValue(":grind", $rune->{"sec_eff"}[3][3], SQLITE3_INTEGER); // TODO: Calculate rolls $statement->bindValue(":rolls", 0, SQLITE3_INTEGER); $statement->execute(); } // Instantiate and calculate efficiency: $instance = new Rune($rune->{"rune_id"}); // Assigned? if (intval($rune->{"occupied_id"}) != 0){ $statement = $db->prepare(" INSERT INTO unit_rune (unit, rune, rta) VALUES (:unit, :rune, :rta); "); $statement->bindValue(":unit", $rune->{"occupied_id"}, SQLITE3_INTEGER); $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER); $statement->bindValue(":rta", GAME_MODE_ID::NORMAL, SQLITE3_INTEGER); $statement->execute(); } } /** * Parses the response to the HubUserLogin command and updates profile. * * @param resource $db Database connection. * @param int $uid Player UID. * @param mixed[] $json Response. */ function parse_profile($db, $uid, $json){ // Save data file $uname = $json->{"wizard_info"}->{"wizard_name"}; $dtime = (new DateTime())->format("Y-m-dTH:i:s"); $fname = ($_SERVER["DOCUMENT_ROOT"] . "/../data/profile_" . $uid . "_" . $uname . "_" . $dtime . ".json"); try{ file_put_contents($fname, json_encode($json)); } catch(Exception $e) { header("HTTP/1.1 500 Unable to save profile file: " . $e->getMessage()); syslog(LOG_INFO, "[APIv3] HTTP/1.1 500 Unable to save profile file: " . $e->getMessage()); return 500; } // Clear previous profile data $db->query("PRAGMA foreign_keys = OFF;"); $statement = $db->prepare("DELETE FROM unit_skill WHERE unit IN (SELECT id FROM unit WHERE uid = :uid);"); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->execute(); $statement = $db->prepare("DELETE FROM unit_rune WHERE unit IN (SELECT id FROM unit WHERE uid = :uid);"); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->execute(); $statement = $db->prepare("DELETE FROM rune_stat WHERE rune IN (SELECT id FROM rune WHERE uid = :uid);"); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->execute(); $statement = $db->prepare("DELETE FROM unit_artifact WHERE unit IN (SELECT id FROM unit WHERE uid = :uid);"); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->execute(); $statement = $db->prepare("DELETE FROM artifact_stat WHERE artifact IN (SELECT id FROM artifact WHERE uid = :uid);"); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->execute(); $statement = $db->prepare("DELETE FROM artifact_effect WHERE artifact IN (SELECT id FROM artifact WHERE uid = :uid);"); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->execute(); $tables_to_clear = [ "scenario", "defense", "gw_defense", "unit", "rune", "artifact", "building", "decoration", "inventory", "enchantment" ]; foreach ($tables_to_clear as $table){ $statement = $db->prepare("DELETE FROM $table WHERE uid = :uid;"); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->execute(); } $db->query("DELETE FROM summon_special"); # For every player, will be reloaded. // Get rune lock list $rune_lock_list = $json->{"rune_lock_list"}; // Update player data $statement = $db->prepare(" UPDATE player SET name = :name, mana = :mana, crystal = :crystal, country = :country, lang = :lang, level = :level, experience = :experience, energy = :energy, energy_max = :energy_max, energy_per_min = :energy_per_min, arena_energy = :arena_energy, arena_energy_max = :arena_energy_max, rep = :rep, social_point = :social_point, honor_point = :honor_point, guild_point = :guild_point, darkportal_energy = :darkportal_energy, darkportal_energy_max = :darkportal_energy_max, dimension_energy = :dimension_energy, dimension_energy_max = :dimension_energy_max, costume_point = :costume_point, costume_point_max = :costume_point_max, honor_medal = :honor_medal, honor_mark = :honor_mark, event_coin = :event_coin, storage_slots = :storage_slots, island = :island_upgrade WHERE uid = :uid; "); $statement->bindValue(":name", $json->{"wizard_info"}->{"wizard_name"}, SQLITE3_TEXT); $statement->bindValue(":mana", $json->{"wizard_info"}->{"wizard_mana"}, SQLITE3_INTEGER); $statement->bindValue(":crystal", $json->{"wizard_info"}->{"wizard_crystal"}, SQLITE3_INTEGER); $statement->bindValue(":country", $json->{"wizard_info"}->{"wizard_last_country"}, SQLITE3_TEXT); $statement->bindValue(":lang", $json->{"wizard_info"}->{"wizard_last_lang"}, SQLITE3_TEXT); $statement->bindValue(":level", $json->{"wizard_info"}->{"wizard_level"}, SQLITE3_INTEGER); $statement->bindValue(":experience", $json->{"wizard_info"}->{"experience"}, SQLITE3_INTEGER); $statement->bindValue(":energy", $json->{"wizard_info"}->{"wizard_energy"}, SQLITE3_INTEGER); $statement->bindValue(":energy_max", $json->{"wizard_info"}->{"energy_max"}, SQLITE3_INTEGER); $statement->bindValue(":energy_per_min", $json->{"wizard_info"}->{"energy_per_min"}, SQLITE3_INTEGER); $statement->bindValue(":arena_energy", $json->{"wizard_info"}->{"arena_energy"}, SQLITE3_INTEGER); $statement->bindValue(":arena_energy_max", $json->{"wizard_info"}->{"arena_energy_max"}, SQLITE3_INTEGER); $statement->bindValue(":rep", $json->{"wizard_info"}->{"rep_unit_id"}, SQLITE3_INTEGER); $statement->bindValue(":social_point", $json->{"wizard_info"}->{"social_point_current"}, SQLITE3_INTEGER); $statement->bindValue(":honor_point", $json->{"wizard_info"}->{"honor_point"}, SQLITE3_INTEGER); $statement->bindValue(":guild_point", $json->{"wizard_info"}->{"guild_point"}, SQLITE3_INTEGER); $statement->bindValue(":darkportal_energy", $json->{"wizard_info"}->{"darkportal_energy"}, SQLITE3_INTEGER); $statement->bindValue(":darkportal_energy_max", $json->{"wizard_info"}->{"darkportal_energy_max"}, SQLITE3_INTEGER); $statement->bindValue(":dimension_energy", $json->{"dimension_hole_info"}->{"energy"}, SQLITE3_INTEGER); $statement->bindValue(":dimension_energy_max", $json->{"dimension_hole_info"}->{"energy_max"}, SQLITE3_INTEGER); $statement->bindValue(":costume_point", $json->{"wizard_info"}->{"costume_point"}, SQLITE3_INTEGER); $statement->bindValue(":costume_point_max", $json->{"wizard_info"}->{"costume_point_max"}, SQLITE3_INTEGER); $statement->bindValue(":honor_medal", $json->{"wizard_info"}->{"honor_medal"}, SQLITE3_INTEGER); $statement->bindValue(":honor_mark", $json->{"wizard_info"}->{"honor_mark"}, SQLITE3_INTEGER); $statement->bindValue(":event_coin", $json->{"wizard_info"}->{"event_coin"}, SQLITE3_INTEGER); $statement->bindValue(":storage_slots", $json->{"unit_depository_slots"}->{"number"}, SQLITE3_INTEGER); $island_upgrade = 0; foreach ($json->{"island_info"} as $island){ if (intval($island->{"id"}) > 100 && intval($island->{"open"}) == 1){ $island_upgrade = intval($island->{"id"}); } } $statement->bindValue(":island_upgrade", $island_upgrade, SQLITE3_INTEGER); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->execute(); // Update scenarion completion foreach ($json->{"scenario_list"} as $sce){ $statement = $db->prepare(" INSERT INTO scenario ( uid, region, difficulty, cleared, max_cleared ) VALUES ( :uid, :region, :difficulty, :cleared, :max_cleared ); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":region", $sce->{"region_id"}, SQLITE3_INTEGER); $statement->bindValue(":difficulty", $sce->{"difficulty"}, SQLITE3_INTEGER); $statement->bindValue(":cleared", $sce->{"cleared"}, SQLITE3_INTEGER); $max_cleared = 0; foreach ($sce->{"stage_list"} as $stage){ if (intval($stage->{"cleared"}) == 1){ $max_cleared = intval($stage->{"stage_no"}); } } $statement->bindValue(":max_cleared", $max_cleared, SQLITE3_INTEGER); $statement->execute(); } // Parse Arena defense foreach ($json->{"defense_unit_list"} as $defense){ $statement = $db->prepare(" INSERT INTO defense ( uid, unit, position ) VALUES ( :uid, :unit, :position ); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":unit", $defense->{"unit_id"}, SQLITE3_INTEGER); $statement->bindValue(":position", $defense->{"pos_id"}, SQLITE3_INTEGER); $statement->execute(); } // Parse GW defense if ($json->{"guildwar_defense_unit_list"}[0]){ $position = 1; foreach ($json->{"guildwar_defense_unit_list"}[0] as $defense){ $statement = $db->prepare(" INSERT INTO gw_defense ( uid, unit, position ) VALUES ( :uid, :unit, :position ); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":unit", $defense->{"unit_id"}, SQLITE3_INTEGER); $statement->bindValue(":position", $position, SQLITE3_INTEGER); $statement->execute(); $position ++; } } if ($json->{"guildwar_defense_unit_list"}[1]){ $position = 4; foreach ($json->{"guildwar_defense_unit_list"}[1] as $defense){ $statement = $db->prepare(" INSERT INTO gw_defense ( uid, unit, position ) VALUES ( :uid, :unit, :position ); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":unit", $defense->{"unit_id"}, SQLITE3_INTEGER); $statement->bindValue(":position", $position, SQLITE3_INTEGER); $statement->execute(); $position ++; } } // Parse buildings foreach($json->{"building_list"} as $building){ $statement = $db->prepare(" INSERT INTO building ( uid, id, building, gain ) VALUES ( :uid, :id, :building, :gain ); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":id", $building->{"building_id"}, SQLITE3_INTEGER); $statement->bindValue(":building", $building->{"building_master_id"}, SQLITE3_INTEGER); $statement->bindValue(":gain", $building->{"gain_per_hour"}, SQLITE3_INTEGER); $statement->execute(); } // Parse decorarion foreach($json->{"deco_list"} as $building){ $statement = $db->prepare(" INSERT INTO decoration ( uid, id, decoration, level ) VALUES ( :uid, :id, :decoration, :level ); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":id", $building->{"deco_id"}, SQLITE3_INTEGER); $statement->bindValue(":decoration", $building->{"master_id"}, SQLITE3_INTEGER); $statement->bindValue(":level", $building->{"level"}, SQLITE3_INTEGER); $statement->execute(); } // Parse units $lock_list = $json->{"unit_lock_list"}; foreach ($json->{"unit_list"} as $unit){ $statement = $db->prepare(" INSERT INTO unit ( uid, id, building, unit, level, stars, hp, attack, defense, speed, crit_rate, crit_damage, resistance, accuracy, experience, exp_gained, exp_gain_rate, costume, attribute, source, create_time, homunculus, homunculus_name, lock ) VALUES ( :uid, :id, :building, :unit, :level, :stars, :hp, :attack, :defense, :speed, :crit_rate, :crit_damage, :resistance, :accuracy, :experience, :exp_gained, :exp_gain_rate, :costume, :attribute, :source, :create_time, :homunculus, :homunculus_name, :lock ); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":id", $unit->{"unit_id"}, SQLITE3_INTEGER); $statement->bindValue(":building", $unit->{"building_id"}, SQLITE3_INTEGER); $statement->bindValue(":unit", $unit->{"unit_master_id"}, SQLITE3_INTEGER); $statement->bindValue(":level", $unit->{"unit_level"}, SQLITE3_INTEGER); $statement->bindValue(":stars", $unit->{"class"}, SQLITE3_INTEGER); $statement->bindValue(":hp", intval($unit->{"con"}) * 15, SQLITE3_INTEGER); # Always x15 $statement->bindValue(":attack", $unit->{"atk"}, SQLITE3_INTEGER); $statement->bindValue(":defense", $unit->{"def"}, SQLITE3_INTEGER); $statement->bindValue(":speed", $unit->{"spd"}, SQLITE3_INTEGER); $statement->bindValue(":crit_rate", $unit->{"critical_rate"}, SQLITE3_INTEGER); $statement->bindValue(":crit_damage", $unit->{"critical_damage"}, SQLITE3_INTEGER); $statement->bindValue(":resistance", $unit->{"resist"}, SQLITE3_INTEGER); $statement->bindValue(":accuracy", $unit->{"accuracy"}, SQLITE3_INTEGER); $statement->bindValue(":experience", $unit->{"experience"}, SQLITE3_INTEGER); $statement->bindValue(":exp_gained", $unit->{"exp_gained"}, SQLITE3_INTEGER); $statement->bindValue(":exp_gain_rate", $unit->{"exp_gain_rate"}, SQLITE3_INTEGER); $statement->bindValue(":costume", $unit->{"costume_master_id"}, SQLITE3_INTEGER); $statement->bindValue(":attribute", $unit->{"attribute"}, SQLITE3_INTEGER); $statement->bindValue(":source", $unit->{"source"}, SQLITE3_INTEGER); $statement->bindValue(":create_time", $unit->{"create_time"}, SQLITE3_INTEGER); $statement->bindValue(":homunculus", $unit->{"homunculus"}, SQLITE3_INTEGER); $statement->bindValue(":homunculus_name", $unit->{"homunculus_name"}, SQLITE3_TEXT); $lock = 0; if (in_array($unit->{"unit_id"}, $lock_list)){ $lock = 1; } $statement->bindValue(":lock", $lock, SQLITE3_INTEGER); $statement->execute(); foreach ($unit->{"skills"} as $skill){ $statement = $db->prepare(" INSERT INTO unit_skill ( unit, skill, level ) VALUES ( :unit, :skill, :level ); "); $statement->bindValue(":unit", $unit->{"unit_id"}, SQLITE3_INTEGER); $statement->bindValue(":skill", $skill[0], SQLITE3_INTEGER); $statement->bindValue(":level", $skill[1], SQLITE3_INTEGER); $statement->execute(); } } // Parse inventory foreach ($json->{"inventory_info"} as $item){ $statement = $db->prepare(" INSERT INTO inventory ( uid, id, type, amount ) VALUES ( :uid, :id, :type, :amount ); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":id", $item->{"item_master_id"}, SQLITE3_INTEGER); $statement->bindValue(":type", $item->{"item_master_type"}, SQLITE3_INTEGER); $statement->bindValue(":amount", $item->{"item_quantity"}, SQLITE3_INTEGER); $statement->execute(); } // Fix rune craft item type. $db->query("UPDATE inventory SET type = 27 WHERE type = 29 AND id IN (2001, 4001, 4002, 4003, 9001, 9002, 9003, 8001);"); // Parse Summon Stone summoning list // TODO: Set propper dates foreach ($json->{"summon_special_info"}->{"this"} as $unit){ $statement = $db->prepare(" INSERT INTO summon_special ( week, unit ) VALUES ( :week, :unit ); "); $statement->bindValue(":week", 0, SQLITE3_INTEGER); $statement->bindValue(":unit", $unit, SQLITE3_INTEGER); $statement->execute(); } foreach ($json->{"summon_special_info"}->{"next"} as $unit){ $statement = $db->prepare(" INSERT INTO summon_special ( week, unit ) VALUES ( :week, :unit ); "); $statement->bindValue(":week", 1, SQLITE3_INTEGER); $statement->bindValue(":unit", $unit, SQLITE3_INTEGER); $statement->execute(); } foreach ($json->{"summon_special_info"}->{"third"} as $unit){ $statement = $db->prepare(" INSERT INTO summon_special ( week, unit ) VALUES ( :week, :unit ); "); $statement->bindValue(":week", 2, SQLITE3_INTEGER); $statement->bindValue(":unit", $unit, SQLITE3_INTEGER); $statement->execute(); } foreach ($json->{"summon_special_info"}->{"fourth"} as $unit){ $statement = $db->prepare(" INSERT INTO summon_special ( week, unit ) VALUES ( :week, :unit ); "); $statement->bindValue(":week", 3, SQLITE3_INTEGER); $statement->bindValue(":unit", $unit, SQLITE3_INTEGER); $statement->execute(); } // Parse runes foreach ($json->{"runes"} as $rune){ parse_rune($uid, $rune, $rune_lock_list); } foreach ($json->{"unit_list"} as $unit){ foreach ($unit->{"runes"} as $rune){ parse_rune($uid, $rune, $rune_lock_list); } } foreach ($json->{"world_arena_rune_equip_list"} as $rta_rune){ $statement = $db->prepare(" INSERT INTO unit_rune (unit, rune, rta) VALUES (:unit, :rune, :rta); "); $statement->bindValue(":unit", $rta_rune->{"occupied_id"}, SQLITE3_INTEGER); $statement->bindValue(":rune", $rta_rune->{"rune_id"}, SQLITE3_INTEGER); $statement->bindValue(":rta", GAME_MODE_ID::RTA, SQLITE3_INTEGER); $statement->execute(); } // Parse artifacts foreach ($json->{"artifacts"} as $artifact){ parse_artifact($uid, $artifact); } foreach ($json->{"unit_list"} as $unit){ foreach ($unit->{"artifacts"} as $artifact){ parse_artifact($uid, $artifact); } } foreach ($json->{"world_arena_artifact_equip_list"} as $rta_artifact){ $statement = $db->prepare(" INSERT INTO unit_artifact (unit, artifact, rta) VALUES (:unit, :artifact, :rta); "); $statement->bindValue(":unit", $rta_artifact->{"occupied_id"}, SQLITE3_INTEGER); $statement->bindValue(":artifact", $rta_artifact->{"artifact_id"}, SQLITE3_INTEGER); $statement->bindValue(":rta", GAME_MODE_ID::RTA, SQLITE3_INTEGER); $statement->execute(); } // Parse enchantments foreach ($json->{"rune_craft_item_list"} as $item){ $statement = $db->prepare(" INSERT INTO enchantment ( uid, id, type, quality, rune, stat, value, amount ) VALUES ( :uid, :id, :type, :quality, :rune, :stat, :value, :amount ); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":id", $item->{"craft_item_id"}, SQLITE3_INTEGER); $statement->bindValue(":type", $item->{"craft_type"}, SQLITE3_INTEGER); $statement->bindValue(":value", $item->{"sell_value"}, SQLITE3_INTEGER); $statement->bindValue(":amount", $item->{"amount"}, SQLITE3_INTEGER); $info = str_pad(intval($item->{"craft_type_id"}), 6, "0", STR_PAD_LEFT); /* info : 5 or 6 digit number: RRSSQQ RR: Rune (may not be padded) SS: Stat QQ: Quality */ $statement->bindValue(":quality", intval(substr($info, 4, 2)), SQLITE3_INTEGER); $statement->bindValue(":stat", intval(substr($info, 2, 2)), SQLITE3_INTEGER); $statement->bindValue(":rune", intval(substr($info, 0, 2)), SQLITE3_INTEGER); $statement->execute(); } // Parse guild if ($json->{"guild"}->{"guild_info"} != null){ $guild = $json->{"guild"}->{"guild_info"}; $statement = $db->prepare("DELETE FROM guild WHERE id = :id;"); $statement->bindValue(":id", $guild->{"guild_id"}, SQLITE3_INTEGER); $statement->execute(); $statement = $db->prepare("DELETE FROM guild_member WHERE guild = :guild;"); $statement->bindValue(":guild", $guild->{"guild_id"}, SQLITE3_INTEGER); $statement->execute(); $statement = $db->prepare(" INSERT INTO guild ( id, name, level, experience, recruiting, members, leader, comment, notice ) VALUES ( :id, :name, :level, :experience, :recruiting, :members, :leader, :comment, :notice ); "); $statement->bindValue(":id",$guild->{"guild_id"}, SQLITE3_INTEGER); $statement->bindValue(":name",$guild->{"name"}, SQLITE3_TEXT); $statement->bindValue(":level",$guild->{"level"}, SQLITE3_INTEGER); $statement->bindValue(":experience",$guild->{"experience"}, SQLITE3_INTEGER); $statement->bindValue(":recruiting",$guild->{"recruit_status"}, SQLITE3_INTEGER); $statement->bindValue(":members",$guild->{"member_now"}, SQLITE3_INTEGER); $statement->bindValue(":leader",$guild->{"master_wizard_id"}, SQLITE3_INTEGER); $statement->bindValue(":comment",$guild->{"comment"}, SQLITE3_TEXT); $statement->bindValue(":notice",$guild->{"notice"}, SQLITE3_TEXT); $statement->execute(); foreach ($json->{"guild"}->{"guild_members"} as $member){ $statement = $db->prepare(" INSERT INTO guild_member ( id, guild, grade, name, level, rating, arena_score, joined, last_login, in_war, has_defense ) VALUES ( :id, :guild, :grade, :name, :level, :rating, :arena_score, :joined, :last_login, :in_war, :has_defense ); "); $statement->bindValue(":id", $member->{"wizard_id"}, SQLITE3_INTEGER); $statement->bindValue(":guild", $member->{"guild_id"}, SQLITE3_INTEGER); $statement->bindValue(":grade", $member->{"grade"}, SQLITE3_INTEGER); $statement->bindValue(":name", $member->{"wizard_name"}, SQLITE3_TEXT); $statement->bindValue(":level", $member->{"wizard_level"}, SQLITE3_INTEGER); $statement->bindValue(":rating", $member->{"rating_id"}, SQLITE3_INTEGER); $statement->bindValue(":arena_score", $member->{"arena_score"}, SQLITE3_INTEGER); $statement->bindValue(":joined", $member->{"join_timestamp"}, SQLITE3_TEXT); $statement->bindValue(":last_login", $member->{"last_login_timestamp"}, SQLITE3_TEXT); $in_war = 0; foreach ($json->{"guildwar_member_list"} as $war){ if ($war->{"wizard_id"} == $member->{"wizard_id"}){ $in_war = 1; break; } } $has_defense = 0; foreach ($json->{"guild_member_defense_list"} as $defense){ if ($defense->{"wizard_id"} == $member->{"wizard_id"}){ $has_defense = 1; break; } } $statement->bindValue(":in_war", $in_war, SQLITE3_INTEGER); $statement->bindValue(":has_defense", $has_defense, SQLITE3_INTEGER); $statement->execute(); } } // Update invalid teams $statement = $db->prepare(" DELETE FROM team WHERE id IN ( SELECT DISTINCT team FROM team_unit WHERE unit NOT IN ( SELECT DISTINCT id FROM unit WHERE uid = :uid ) ) AND uid = :uid "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->execute(); $db->query(" DELETE FROM team_unit WHERE unit NOT IN ( SELECT DISTINCT id FROM unit ) OR team NOT IN ( SELECT DISTINCT id FROM team );" ); // Return success return "201 Created."; } /** * Parses the response to the GetUnitCollection command and updates the * user monster collection status. * * @param resource $db Database connection. * @param int $uid Player UID. * @param mixed[] $json Response. */ function parse_collection($db, $uid, $json){ // Clear previous collection data $db->query("PRAGMA foreign_keys = OFF;"); $statement = $db->prepare("DELETE FROM collection WHERE uid = :uid;"); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->execute(); foreach ($json->{"collection"} as $unit){ $statement = $db->prepare(" INSERT INTO collection (uid, unit, open) VALUES (:uid, :unit, :open); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":unit", $unit->{"unit_master_id"}, SQLITE3_INTEGER); $statement->bindValue(":open", $unit->{"open"}, SQLITE3_INTEGER); $statement->execute(); } // Return success return "201 Created."; } /** * Parses the response to the GetLobbyWizardLog command and updates the * user records. * * @param resource $db Database connection. * @param int $uid Player UID. * @param mixed[] $json Response. */ function parse_records($db, $uid, $json){ # Page 1: Cairos non-elemental, rift raid, rift dungeon. if (intval($json->{"lobby_wizard_log"}->{"page_no"}) == 1){ // Update data in player table $db->query("PRAGMA foreign_keys = OFF;"); $statement = $db->prepare(" UPDATE player SET joined = :joined, top_rank_arena = :top_rank_arena, top_rank_world_arena = :top_rank_world_arena, top_rank_special_league = :top_rank_special_league, top_rank_gw = :top_rank_gw, top_rank_siege = :top_rank_siege, top_rank_wboss = :top_rank_wboss, top_rank_toan = :top_rank_toan, top_rank_toah = :top_rank_toah WHERE uid = :uid; "); $statement->bindValue(":joined", $json->{"lobby_wizard_log"}->{"account_create_timestamp"}, SQLITE3_TEXT); $statement->bindValue(":top_rank_arena", $json->{"lobby_wizard_log"}->{"pvp_best_rating_id"}, SQLITE3_INTEGER); $statement->bindValue(":top_rank_world_arena", $json->{"lobby_wizard_log"}->{"rtpvp_rank_best_rating_id"}, SQLITE3_INTEGER); $statement->bindValue(":top_rank_special_league", $json->{"lobby_wizard_log"}->{"rtpvp_contest_best_rating_id"}, SQLITE3_INTEGER); $statement->bindValue(":top_rank_gw", $json->{"lobby_wizard_log"}->{"guildwar_best_rating_id"}, SQLITE3_INTEGER); $statement->bindValue(":top_rank_siege", $json->{"lobby_wizard_log"}->{"guildsiege_best_rating_id"}, SQLITE3_INTEGER); $statement->bindValue(":top_rank_wboss", $json->{"lobby_wizard_log"}->{"world_boss_best_rank_id"}, SQLITE3_INTEGER); $statement->bindValue(":top_rank_toan", $json->{"lobby_wizard_log"}->{"trial_tower_normal_best_floor"}, SQLITE3_INTEGER); $statement->bindValue(":top_rank_toah", $json->{"lobby_wizard_log"}->{"trial_tower_hard_best_floor"}, SQLITE3_INTEGER); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->execute(); // Loop Cairos records foreach ($json->{"lobby_wizard_log"}->{"dungeon_best_clear_info_list"} as $record){ // Delete prevous data $statement = $db->prepare(" DELETE FROM record_party WHERE uid = :uid AND area_type = :area_type AND area = :area; "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::CAIROS_DUNGEON, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"dungeon_id"}, SQLITE3_INTEGER); $statement->execute(); $statement = $db->prepare(" DELETE FROM record WHERE uid = :uid AND area_type = :area_type AND area = :area; "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::CAIROS_DUNGEON, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"dungeon_id"}, SQLITE3_INTEGER); $statement->execute(); // Insert new data $statement = $db->prepare(" INSERT INTO record (uid, area_type, area, stage, time, score, rank) VALUES (:uid, :area_type, :area, :stage, :time, :score, :rank); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::CAIROS_DUNGEON, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"dungeon_id"}, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"dungeon_id"}, SQLITE3_INTEGER); $statement->bindValue(":stage", $record->{"stage_id"}, SQLITE3_INTEGER); $statement->bindValue(":time", $record->{"clear_time"}, SQLITE3_INTEGER); $statement->bindValue(":score", 0, SQLITE3_INTEGER); $statement->bindValue(":rank", null, SQLITE3_TEXT); $statement->execute(); // Loop party foreach ($record->{"my_unit_deck_list"} as $party){ $statement = $db->prepare(" INSERT INTO record_party (uid, area_type, area, unit, k_unit, leader, front) VALUES (:uid, :area_type, :area, :unit, :k_unit, :leader, :front); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::CAIROS_DUNGEON, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"dungeon_id"}, SQLITE3_INTEGER); $statement->bindValue(":unit", $party->{"unit_id"}, SQLITE3_INTEGER); $statement->bindValue(":k_unit", $party->{"unit_master_id"}, SQLITE3_INTEGER); $statement->bindValue(":leader", $party->{"leader"}, SQLITE3_INTEGER); $statement->bindValue(":front", 0, SQLITE3_INTEGER); $statement->execute(); } } // Rift Raid record if (sizeof($json->{"lobby_wizard_log"}->{"raid_best_clear_info_list"}) > 0){ $record = $json->{"lobby_wizard_log"}->{"raid_best_clear_info_list"}[0]; // Delete prevous data $statement = $db->prepare(" DELETE FROM record_party WHERE uid = :uid AND area_type = :area_type AND area = :area; "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::RIFT_RAID, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"stage_id"}, SQLITE3_INTEGER); $statement->execute(); $statement = $db->prepare(" DELETE FROM record WHERE uid = :uid AND area_type = :area_type AND area = :area; "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::RIFT_RAID, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"stage_id"}, SQLITE3_INTEGER); $statement->execute(); // Insert new data $statement = $db->prepare(" INSERT INTO record (uid, area_type, area, stage, time, score, rank) VALUES (:uid, :area_type, :area, :stage, :time, :score, :rank); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::RIFT_RAID, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"stage_id"}, SQLITE3_INTEGER); $statement->bindValue(":stage", $record->{"stage_id"}, SQLITE3_INTEGER); $statement->bindValue(":time", $record->{"clear_time"}, SQLITE3_TEXT); $statement->bindValue(":score", 0, SQLITE3_INTEGER); $statement->bindValue(":rank", null, SQLITE3_TEXT); $statement->execute(); // Loop party foreach ($record->{"my_unit_deck_list"} as $party){ $statement = $db->prepare(" INSERT INTO record_party (uid, area_type, area, unit, k_unit, leader, front) VALUES (:uid, :area_type, :area, :unit, :k_unit, :leader, :front); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::RIFT_RAID, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"stage_id"}, SQLITE3_INTEGER); $statement->bindValue(":unit", $party->{"unit_id"}, SQLITE3_INTEGER); $statement->bindValue(":k_unit", $party->{"unit_master_id"}, SQLITE3_INTEGER); $statement->bindValue(":leader", $party->{"leader"}, SQLITE3_INTEGER); if ($party->{"slot_index"} <= 4){ $statement->bindValue(":front", 1, SQLITE3_INTEGER); } else{ $statement->bindValue(":front", 0, SQLITE3_INTEGER); } $statement->execute(); } } // Loop Rift Dungeon records foreach ( $json->{"lobby_wizard_log"}->{"rift_dungeon_best_clear_info_list"} as $record){ // Delete prevous data $statement = $db->prepare(" DELETE FROM record_party WHERE uid = :uid AND area_type = :area_type AND area = :area; "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::RIFT_DUNGEON, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"rift_dungeon_id"}, SQLITE3_INTEGER); $statement->execute(); $statement = $db->prepare(" DELETE FROM record WHERE uid = :uid AND area_type = :area_type AND area = :area; "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::RIFT_DUNGEON, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"rift_dungeon_id"}, SQLITE3_INTEGER); $statement->execute(); // Insert new data $statement = $db->prepare(" INSERT INTO record (uid, area_type, area, stage, time, score, rank) VALUES (:uid, :area_type, :area, :stage, :time, :score, :rank); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::RIFT_DUNGEON, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"rift_dungeon_id"}, SQLITE3_INTEGER); $statement->bindValue(":stage", 0, SQLITE3_INTEGER); $statement->bindValue(":time", 0, SQLITE3_INTEGER); $statement->bindValue(":score", $record->{"clear_damage"}, SQLITE3_INTEGER); switch (intval($record->{"clear_rating"})){ case 2: $statement->bindValue(":rank", "D", SQLITE3_TEXT); break; case 3: $statement->bindValue(":rank", "C", SQLITE3_TEXT); break; case 4: $statement->bindValue(":rank", "B-", SQLITE3_TEXT); break; case 5: $statement->bindValue(":rank", "B", SQLITE3_TEXT); break; case 6: $statement->bindValue(":rank", "B+", SQLITE3_TEXT); break; case 7: $statement->bindValue(":rank", "A-", SQLITE3_TEXT); break; case 8: $statement->bindValue(":rank", "A", SQLITE3_TEXT); break; case 9: $statement->bindValue(":rank", "A+", SQLITE3_TEXT); break; case 10: $statement->bindValue(":rank", "S", SQLITE3_TEXT); break; case 11: $statement->bindValue(":rank", "SS", SQLITE3_TEXT); break; case 12: $statement->bindValue(":rank", "SS", SQLITE3_TEXT); break; default: $statement->bindValue(":rank", "F", SQLITE3_TEXT); } $statement->execute(); // Loop party foreach ($record->{"my_unit_deck_list"} as $party){ $statement = $db->prepare(" INSERT INTO record_party (uid, area_type, area, unit, k_unit, leader, front) VALUES (:uid, :area_type, :area, :unit, :k_unit, :leader, :front); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::RIFT_DUNGEON, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"rift_dungeon_id"}, SQLITE3_INTEGER); $statement->bindValue(":unit", $party->{"unit_id"}, SQLITE3_INTEGER); $statement->bindValue(":k_unit", $party->{"unit_master_id"}, SQLITE3_INTEGER); $statement->bindValue(":leader", $party->{"leader"}, SQLITE3_INTEGER); if ($party->{"slot_index"} <= 4){ $statement->bindValue(":front", 1, SQLITE3_INTEGER); } else{ $statement->bindValue(":front", 0, SQLITE3_INTEGER); } $statement->execute(); } } } # Page 2: Cairos non-elemental, rift raid, rift dungeon. elseif (intval($json->{"lobby_wizard_log"}->{"page_no"} == 2)){ // Loop Cairos records foreach ($json->{"lobby_wizard_log"}->{"dungeon_best_clear_info_list"} as $record){ // Delete prevous data $statement = $db->prepare(" DELETE FROM record_party WHERE uid = :uid AND area_type = :area_type AND area = :area; "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::CAIROS_DUNGEON, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"dungeon_id"}, SQLITE3_INTEGER); $statement->execute(); $statement = $db->prepare(" DELETE FROM record WHERE uid = :uid AND area_type = :area_type AND area = :area; "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::CAIROS_DUNGEON, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"dungeon_id"}, SQLITE3_INTEGER); $statement->execute(); // Insert new data $statement = $db->prepare(" INSERT INTO record (uid, area_type, area, stage, time, score, rank) VALUES (:uid, :area_type, :area, :stage, :time, :score, :rank); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::CAIROS_DUNGEON, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"dungeon_id"}, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"dungeon_id"}, SQLITE3_INTEGER); $statement->bindValue(":stage", $record->{"stage_id"}, SQLITE3_INTEGER); $statement->bindValue(":time", $record->{"clear_time"}, SQLITE3_INTEGER); $statement->bindValue(":score", 0, SQLITE3_INTEGER); $statement->bindValue(":rank", null, SQLITE3_TEXT); $statement->execute(); // Loop party foreach ($record->{"my_unit_deck_list"} as $party){ $statement = $db->prepare(" INSERT INTO record_party (uid, area_type, area, unit, k_unit, leader, front) VALUES (:uid, :area_type, :area, :unit, :k_unit, :leader, :front); "); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":area_type", AREA_TYPE_ID::CAIROS_DUNGEON, SQLITE3_INTEGER); $statement->bindValue(":area", $record->{"dungeon_id"}, SQLITE3_INTEGER); $statement->bindValue(":unit", $party->{"unit_id"}, SQLITE3_INTEGER); $statement->bindValue(":k_unit", $party->{"unit_master_id"}, SQLITE3_INTEGER); $statement->bindValue(":leader", $party->{"leader"}, SQLITE3_INTEGER); $statement->bindValue(":front", 0, SQLITE3_INTEGER); $statement->execute(); } } } elseif (intval($json->{"lobby_wizard_log"}->{"page_no"}) == 3){ return "204 Page not logged (only pages 1 and 2 are needed)."; } elseif (intval($json->{"lobby_wizard_log"}->{"page_no"}) == 4){ return "204 Page not logged (only pages 1 and 2 are needed)."; } else{ return "400 Unknown page."; } // Return success return "201 Created."; } try{ header("Content-type: application/json; charset=utf-8"); // Get put data $_PUT = []; parse_str(file_get_contents("php://input"), $_PUT); // Check API key. $key = $_PUT["key"]; if ($key == null || $key == false){ header("HTTP/1.1 400 API key not received."); syslog(LOG_INFO, "[APIv3] HTTP/1.1 400 API key not received."); return 400; } // Check data $data = $_PUT["response"]; if ($data == null || $data == false){ header("HTTP/1.1 400 No data received."); syslog(LOG_INFO, "[APIv3] HTTP/1.1 400 No data received."); return 400; } // Check data format. $json = json_decode($data); if ($json === null){ header("HTTP/1.1 400 Data is no valid JSON."); syslog(LOG_INFO, "[APIv3] HTTP/1.1 400 Data is no valid JSON."); return 400; } // Get and validate command $command = $json->{"command"}; $accepted_commands = [ "HubUserLogin", // Login, full profile "GetUnitCollection", // Unit collection "GetLobbyWizardLog" // Records ]; if (!in_array($command, $accepted_commands)){ header("HTTP/1.1 405 Command not implemented."); syslog(LOG_INFO, "[APIv3] HTTP/1.1 405 Command not implemented."); return 405; } // Get user info and Authenticate switch ($command){ case "HubUserLogin": $uid = $json->{"wizard_id"}; $statement = $db->prepare("SELECT COUNT(uid) AS c FROM player WHERE uid = :uid AND api_key = :api_key;"); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":api_key", $key, SQLITE3_TEXT); if (1 != $statement->execute()->fetchArray(SQLITE3_ASSOC)["c"]){ header("HTTP/1.1 401 Invalid credentials."); syslog(LOG_INFO, "[APIv3] HTTP/1.1 401 Invalid credentials."); return 401; } break; case "GetUnitCollection": // No identification in this JSON, get uid from databases $statement = $db->prepare("SELECT uid FROM player WHERE api_key = :api_key;"); $statement->bindValue(":api_key", $key, SQLITE3_TEXT); $r = $statement->execute()->fetchArray(SQLITE3_ASSOC); if ($r){ $uid = $r["uid"]; } else{ header("HTTP/1.1 401 Invalid credentials."); syslog(LOG_INFO, "[APIv3] HTTP/1.1 401 Invalid credentials."); return 401; } break; case "GetLobbyWizardLog": $uid = $json->{"lobby_wizard_log"}->{"wizard_id"}; $statement = $db->prepare("SELECT COUNT(uid) AS c FROM player WHERE uid = :uid AND api_key = :api_key;"); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":api_key", $key, SQLITE3_TEXT); if (1 != $statement->execute()->fetchArray(SQLITE3_ASSOC)["c"]){ header("HTTP/1.1 401 Invalid credentials."); syslog(LOG_INFO, "[APIv3] HTTP/1.1 401 Invalid credentials."); return 401; } break; } if ($command == "GetUnitCollection"){ // This command doesnt provide wizard_id $statement = $db->prepare("SELECT COUNT(uid) AS c FROM player WHERE uid = :uid AND api_key = :api_key;"); $statement->bindValue(":uid", $uid, SQLITE3_INTEGER); $statement->bindValue(":api_key", $key, SQLITE3_TEXT); if (1 != $statement->execute()->fetchArray(SQLITE3_ASSOC)["c"]){ header("HTTP/1.1 401 Invalid credentials."); syslog(LOG_INFO, "[APIv3] HTTP/1.1 401 Invalid credentials."); return 401; } } // Run parser $result = "500 Unknown Error"; switch($command){ case "HubUserLogin": $result = parse_profile($db, $uid, $json); break; case "GetUnitCollection": $result = parse_collection($db, $uid, $json); break; case "GetLobbyWizardLog": $result = parse_records($db, $uid, $json); break; } // Process result $status_code = intval(substr($result, 0, 3)); $status_message = substr($result, 4); if ($status_code == 0 || $status_code < 100 || $status_code > 599){ header("HTTP/1.1 500 Unknown error."); syslog(LOG_ERR, "[APIv3] HTTP/1.1 500 Unknown error."); return 500; } else{ header("HTTP/1.1 $status_code $status_message"); syslog(LOG_INFO, "[APIv3] HTTP/1.1 $status_code $status_message"); return $status_code; } } catch(Exception $e) { header("HTTP/1.1 500 Unexpeced error: " . $e->getMessage()); syslog(LOG_INFO, "[APIv3] HTTP/1.1 500 Unexpected error: " . $e->getMessage()); return 500; } ?>