swarfarm_parser 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938
  1. #!/bin/php
  2. <?php
  3. /**
  4. * Swarfarm data parser
  5. *
  6. * Script that parses game data from swarfarm.com.
  7. *
  8. * @author Iñigo Valentin <i@inigovalentin.com>
  9. * @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License V3
  10. * @package SWDB
  11. */
  12. /**
  13. * Swarfarm URL of the monster list (first page).
  14. */
  15. CONST URL_UNIT = 'https://swarfarm.com/api/v2/monsters/';
  16. /**
  17. * Swarfarm URL of the skill list (first page).
  18. */
  19. CONST URL_SKILL = 'https://swarfarm.com/api/v2/skills/';
  20. /**
  21. * Path to the application
  22. */
  23. CONST PATH = __DIR__ . "/../";
  24. /*
  25. * Script verbosity
  26. *
  27. * 0: Critical
  28. * 1: Error
  29. * 2: Warning
  30. * 3: Info
  31. * 4: Debug
  32. * 5: Trace
  33. */
  34. $args = array(
  35. "verbosity" => 3,
  36. "override_images" => false,
  37. "skip_downloads" => false,
  38. "only_downloads" => false,
  39. "only_new" => false
  40. );
  41. /**
  42. * Echoes an output message to stdout, depending on the verbosity level.
  43. *
  44. * @param int $level Message priority.
  45. * @param string $message content.
  46. */
  47. function output($level, $message, $keep_format = false){
  48. global $args;
  49. if ($level <= $args["verbosity"]){
  50. if ($keep_format == false){
  51. $message = str_replace("\n", " ", $message);
  52. while (strpos($message, " ") !== false){
  53. $message = str_replace(" ", " ", $message);
  54. }
  55. }
  56. if (substr($message, -1) != PHP_EOL && $keep_format == false){
  57. $message .= PHP_EOL;
  58. }
  59. echo $message;
  60. }
  61. }
  62. /**
  63. * Downloads a file.
  64. *
  65. * @param string $url The file to download.
  66. * @param string $target File destination.
  67. * @return boolean true on success, false on error.
  68. */
  69. function download($url, $target){
  70. global $args;
  71. if ($args["skip_downloads"] == true){
  72. return true;
  73. }
  74. if (!file_exists($target) || $args["override_images"] == true){
  75. output(4, "Downloading file '$url' to: '$target'");
  76. if (!file_put_contents($target, file_get_contents($url))) {
  77. output(1, "Error downloading file '$url' to: '$target'");
  78. return false;
  79. }
  80. else{
  81. return true;
  82. }
  83. }
  84. else{
  85. return true;
  86. }
  87. }
  88. /**
  89. * Gets an unit com2us_id from it's Swarfarm id.
  90. *
  91. * @param int $swarfarm_id Unit's Swarfarm ID.
  92. * @return int Skill's com2us_id, -1 on error.
  93. */
  94. function get_com2us_id($swarfarm_id){
  95. if ($swarfarm_id == null){
  96. return null;
  97. }
  98. $contents = file_get_contents(URL_UNIT . $swarfarm_id . "/");
  99. if($contents === false){
  100. output(1, "Unable to retrieve unit ID by swarfarm ID: " . $swarfarm_id);
  101. return -1;
  102. }
  103. $contents = json_decode($contents);
  104. return $contents->com2us_id;
  105. }
  106. /**
  107. * Gets an skill com2us_id from it's Swarfarm id.
  108. *
  109. * @param int $swarfarm_id Skill's Swarfarm ID.
  110. * @return int Skill's com2us_id, -1 on error.
  111. */
  112. function get_com2us_skill_id($swarfarm_id){
  113. if ($swarfarm_id == null){
  114. return null;
  115. }
  116. $contents = file_get_contents(URL_SKILL . $swarfarm_id . "/");
  117. if($contents === false){
  118. output(1, "Unable to retrieve skill ID by swarfarm ID: " . $swarfarm_id);
  119. return -1;
  120. }
  121. $contents = json_decode($contents);
  122. return $contents->com2us_id;
  123. }
  124. /**
  125. * Gets an element ID from it's name
  126. *
  127. * @param string $name Element name (case insensitive).
  128. * @return int Element ID, -1 on unknown element.
  129. */
  130. function get_element_id($name){
  131. $id = -1;
  132. switch (strtoupper($name)){
  133. case "MAGIC":
  134. $id = 0;
  135. break;
  136. case "WATER":
  137. $id = 1;
  138. break;
  139. case "FIRE":
  140. $id = 2;
  141. break;
  142. case "WIND":
  143. $id = 3;
  144. break;
  145. case "LIGHT":
  146. $id = 4;
  147. break;
  148. case "DARK":
  149. $id = 5;
  150. break;
  151. case "PURE":
  152. $id = 6;
  153. break;
  154. }
  155. return $id;
  156. }
  157. /**
  158. * Gets an archetype ID from it's name
  159. *
  160. * @param string $name Archetype name (case insensitive).
  161. * @return int Archetype ID, -1 on unknown archetype.
  162. */
  163. function get_archetype_id($name){
  164. $id = 0; // NONE
  165. switch (strtoupper($name)){
  166. case "ATTACK":
  167. $id = 1;
  168. break;
  169. case "DEFENSE":
  170. $id = 2;
  171. break;
  172. case "HP":
  173. $id = 3;
  174. break;
  175. case "SUPPORT":
  176. $id = 4;
  177. break;
  178. case "MATERIAL":
  179. $id = 5;
  180. break;
  181. }
  182. return $id;
  183. }
  184. /**
  185. * Prints the help message.
  186. */
  187. function show_help(){
  188. echo "\nSwarfarm parser\n\n";
  189. echo "Refreshes data using the Swarfarm API.\n\n";
  190. echo "Usage:\n\n";
  191. echo " swarfarm_parser <options...>\n\n";
  192. echo "Options:\n\n";
  193. echo " +--------+------------------+---------------------------------------------------+\n";
  194. echo " | -s | --skip-downloads | Don't download images. |\n";
  195. echo " +--------+------------------+---------------------------------------------------+\n";
  196. echo " | -o | --only-downloads | Download images, but don't make changes to |\n";
  197. echo " | | | the database. |\n";
  198. echo " +--------+------------------+---------------------------------------------------+\n";
  199. echo " | -n | --only-new | Look for new monsters or skills, but don't |\n";
  200. echo " | | | update existing ones. |\n";
  201. echo " +--------+------------------+---------------------------------------------------+\n";
  202. echo " | -v [n] | --verbosity [n] | Controls the script output to the console. |\n";
  203. echo " | | | Values for [n]: |\n";
  204. echo " | | | 0: Only show critical errors. |\n";
  205. echo " | | | 1: Only error messages. |\n";
  206. echo " | | | 2: Only error and warning messages. |\n";
  207. echo " | | | 3: Standard output. |\n";
  208. echo " | | | 4: Include debug messages. |\n";
  209. echo " | | | 5: Print traces (lots of lines!). |\n";
  210. echo " +--------+------------------+---------------------------------------------------+\n";
  211. }
  212. /**
  213. * Establishes a connection with the database.
  214. *
  215. * @param string $name Archetype name (case insensitive).
  216. * @return resource Database connection
  217. */
  218. function connect_to_database(){
  219. // Connect to the database
  220. $db = new SQLite3(PATH . "application/key.sqlite");
  221. if (!$db) {
  222. output(0, "Error connecting to th database: " . $db->lastErrorMsg());
  223. exit();
  224. }
  225. // Disable integrity
  226. $db->query("PRAGMA foreign_keys=OFF;");
  227. output(4, "Connected to dataabse: " . PATH . "application/key.sqlite");
  228. return $db;
  229. }
  230. // Parse arguments
  231. $accepted = array(
  232. "--verbosity", "-v",
  233. "--skip-downloads", "-s",
  234. "--only-downloads", "-d",
  235. "--only-new", "-n",
  236. "--override-images", "-o",
  237. "--help", "-h"
  238. );
  239. for ($i = 1; $i < count($argv); $i++){
  240. if ($argv[$i] == "--help" || $argv[$i] == "-h"){
  241. show_help();
  242. return 0;
  243. }
  244. elseif (!in_array($argv[$i], $accepted)){
  245. echo "Unrecognized option " . $argv[$i] . "\n";
  246. return -1;
  247. }
  248. elseif ($argv[$i] == "--verbosity" || $argv[$i] == "-v"){
  249. if (count($argv) >= $i + 2 && ctype_digit($argv[$i + 1]) && intval($argv[$i + 1]) >= 0 && intval($argv[$i + 1]) <= 5){
  250. $args["verbosity"] = intval($argv[$i + 1]);
  251. $i ++;
  252. }
  253. else{
  254. echo "Unrecognized value for parameter " . $argv[$i] . ": " . $argv[$i + 1] . "\n";
  255. echo "Accepted values are:\n";
  256. echo " 0 (critical)\n";
  257. echo " 1 (error)\n";
  258. echo " 2 (warning)\n";
  259. echo " 3 (info)\n";
  260. echo " 4 (debug)\n";
  261. echo " 5 (trace)\n";
  262. }
  263. }
  264. elseif ($argv[$i] == "--skip-downloads" || $argv[$i] == "-s"){
  265. if (in_array("-d", $argv)){
  266. echo "Conflicting arguments: '-d' and '" . $argv[$i] . "'\n";
  267. return -1;
  268. }
  269. elseif (in_array("--only-downloads", $argv)){
  270. echo "Conflicting arguments: '--only-downloads' and '" . $argv[$i] . "'\n";
  271. return -1;
  272. }
  273. else{
  274. $args["skip_downloads"] = true;
  275. }
  276. }
  277. elseif ($argv[$i] == "--only-downloads" || $argv[$i] == "-s"){
  278. if (in_array("-s", $argv)){
  279. echo "Conflicting arguments: '-s' and '" . $argv[$i] . "'\n";
  280. return -1;
  281. }
  282. elseif (in_array("--skip-downloads", $argv)){
  283. echo "Conflicting arguments: '--skip-downloads' and '" . $argv[$i] . "'\n";
  284. return -1;
  285. }
  286. else{
  287. $args["only_downloads"] = true;
  288. }
  289. }
  290. elseif ($argv[$i] == "--only-new" || $argv[$i] == "-n"){
  291. $args["only_new"] = true;
  292. }
  293. elseif ($argv[$i] == "--override-images" || $argv[$i] == "-o"){
  294. if (in_array("-s", $argv)){
  295. echo "Conflicting arguments: '-s' and '" . $argv[$i] . "'\n";
  296. return -1;
  297. }
  298. elseif (in_array("--skip-downloads", $argv)){
  299. echo "Conflicting arguments: '--skip-downloads' and '" . $argv[$i] . "'\n";
  300. return -1;
  301. }
  302. else{
  303. $args["override_images"] = true;
  304. }
  305. }
  306. }
  307. output(4, "Resolved arguments:");
  308. foreach($args as $key => $value) {
  309. output(4, " $key => " . var_export($value, true));
  310. }
  311. // Connect to the database
  312. $db = connect_to_database();
  313. // Loop skills pages
  314. $next = URL_SKILL;
  315. while ($next != null){
  316. output(3, "Reading skills page: $next");
  317. $contents = file_get_contents($next);
  318. if ($contents === false){
  319. output(0, "Unable to read skill page: $next");
  320. return -1;
  321. }
  322. $contents = json_decode($contents);
  323. $next = $contents->next;
  324. $list = $contents->results;
  325. foreach ($list as $skill){
  326. $statement = $db->prepare("SELECT * FROM skill WHERE id = :id");
  327. $statement->bindValue(":id", $skill->com2us_id, SQLITE3_INTEGER);
  328. $q = $statement->execute();
  329. $r = $q->fetchArray(SQLITE3_ASSOC);
  330. if (!$r){
  331. // New skill, insert directly
  332. $statement = $db->prepare("
  333. INSERT INTO skill(
  334. id,
  335. name,
  336. description,
  337. slot,
  338. cooltime,
  339. hits,
  340. passive,
  341. aoe,
  342. max_level,
  343. multiplier_formula
  344. ) VALUES (
  345. :id,
  346. :name,
  347. :description,
  348. :slot,
  349. :cooltime,
  350. :hits,
  351. :passive,
  352. :aoe,
  353. :max_level,
  354. :multiplier_formula
  355. );
  356. ");
  357. $statement->bindValue(":id", $skill->com2us_id, SQLITE3_INTEGER);
  358. $statement->bindValue(":name", $skill->name, SQLITE3_TEXT);
  359. $statement->bindValue(":description", $skill->name, SQLITE3_TEXT);
  360. $statement->bindValue(":slot", $skill->slot, SQLITE3_TEXT);
  361. $statement->bindValue(":cooltime", $skill->cooltime, SQLITE3_INTEGER);
  362. $statement->bindValue(":hits", $skill->hits, SQLITE3_INTEGER);
  363. $statement->bindValue(":passive", $skill->passive, SQLITE3_INTEGER);
  364. $statement->bindValue(":aoe", $skill->aoe, SQLITE3_INTEGER);
  365. $statement->bindValue(":max_level", $skill->max_level, SQLITE3_INTEGER);
  366. $statement->bindValue(":multiplier_formula", $skill->multiplier_formula, SQLITE3_TEXT);
  367. output(4, "QUERY: " . $statement->getSQL(true));
  368. $statement->execute();
  369. $url = 'https://swarfarm.com/static/herders/images/skills/' . $skill->icon_filename;
  370. $out = PATH . "public/img/skill/" . sprintf('%08d', $skill->com2us_id) . ".png";
  371. download($url, $out);
  372. $level = 1;
  373. $statement = $db->prepare("INSERT INTO skill_level (skill, level, description) VALUES (:skill, :level, :description);");
  374. $statement->bindValue(":skill", $skill->com2us_id, SQLITE3_INTEGER);
  375. $statement->bindValue(":level", $level, SQLITE3_INTEGER);
  376. foreach ($skill->upgrades as $upgrade){
  377. $level ++;
  378. $statement = $db->prepare("INSERT INTO skill_level (skill, level, description) VALUES (:skill, :level, :description);");
  379. $statement->bindValue(":skill", $skill->com2us_id, SQLITE3_INTEGER);
  380. $statement->bindValue(":level", $level, SQLITE3_INTEGER);
  381. $statement->bindValue(":description", str_replace("{0}", $upgrade->amount, $upgrade->effect), SQLITE3_TEXT);
  382. output(4, "QUERY: " . $statement->getSQL(true));
  383. $statement->execute();
  384. }
  385. foreach ($skill->effects as $effect){
  386. $statement = $db->prepare("INSERT INTO skill_effect (skill, effect) VALUES (:skill, :effect);");
  387. $statement->bindValue(":skill", $skill->com2us_id, SQLITE3_INTEGER);
  388. $statement->bindValue(":effect", $effect->effect->id, SQLITE3_INTEGER);
  389. output(4, "QUERY: " . $statement->getSQL(true));
  390. $statement->execute();
  391. }
  392. }
  393. else{
  394. // Existing skill, compare all values
  395. if ($r["name"] != $skill->name){
  396. $statement = $db->prepare("UPDATE skill SET name = :name WHERE id = :id;");
  397. $statement->bindValue(":name", $skill->name, SQLITE3_TEXT);
  398. $statement->bindValue(":id", $skill->com2us_id, SQLITE3_INTEGER);
  399. output(4, "QUERY: " . $statement->getSQL(true));
  400. $statement->execute();
  401. }
  402. if ($r["description"] != $skill->description){
  403. $statement = $db->prepare("UPDATE skill SET description = :description WHERE id = :id;");
  404. $statement->bindValue(":description", $skill->description, SQLITE3_TEXT);
  405. $statement->bindValue(":id", $skill->com2us_id, SQLITE3_INTEGER);
  406. output(4, "QUERY: " . $statement->getSQL(true));
  407. $statement->execute();
  408. }
  409. if ($r["slot"] != $skill->slot){
  410. $statement = $db->prepare("UPDATE skill SET slot = :slot WHERE id = :id;");
  411. $statement->bindValue(":slot", $skill->slot, SQLITE3_TEXT);
  412. $statement->bindValue(":id", $skill->com2us_id, SQLITE3_INTEGER);
  413. output(4, "QUERY: " . $statement->getSQL(true));
  414. $statement->execute();
  415. }
  416. if ($r["cooltime"] != $skill->cooltime){
  417. $statement = $db->prepare("UPDATE skill SET cooltime = :cooltime WHERE id = :id;");
  418. $statement->bindValue(":cooltime", $skill->cooltime, SQLITE3_TEXT);
  419. $statement->bindValue(":id", $skill->com2us_id, SQLITE3_INTEGER);
  420. output(4, "QUERY: " . $statement->getSQL(true));
  421. $statement->execute();
  422. }
  423. if ($r["hits"] != $skill->hits){
  424. $statement = $db->prepare("UPDATE skill SET hits = :hits WHERE id = :id;");
  425. $statement->bindValue(":hits", $skill->hits, SQLITE3_TEXT);
  426. $statement->bindValue(":id", $skill->com2us_id, SQLITE3_INTEGER);
  427. output(4, "QUERY: " . $statement->getSQL(true));
  428. $statement->execute();
  429. }
  430. $passive = ($skill->passive == 1) ? (1) : (0);
  431. if ($r["passive"] != $passive){
  432. $statement = $db->prepare("UPDATE skill SET passive = :passive WHERE id = :id;");
  433. $statement->bindValue(":passive", $passive, SQLITE3_TEXT);
  434. $statement->bindValue(":id", $skill->com2us_id, SQLITE3_INTEGER);
  435. output(4, "QUERY: " . $statement->getSQL(true));
  436. $statement->execute();
  437. }
  438. $aoe = ($skill->aoe == 1) ? (1) : (0);
  439. if ($r["aoe"] != $aoe){
  440. $statement = $db->prepare("UPDATE skill SET aoe = :aoe WHERE id = :id;");
  441. $statement->bindValue(":aoe", $aoe, SQLITE3_TEXT);
  442. $statement->bindValue(":id", $skill->com2us_id, SQLITE3_INTEGER);
  443. output(4, "QUERY: " . $statement->getSQL(true));
  444. $statement->execute();
  445. }
  446. if ($r["max_level"] != $skill->max_level){
  447. $statement = $db->prepare("UPDATE skill SET max_level = :max_level WHERE id = :id;");
  448. $statement->bindValue(":max_level", $skill->max_level, SQLITE3_TEXT);
  449. $statement->bindValue(":id", $skill->com2us_id, SQLITE3_INTEGER);
  450. output(4, "QUERY: " . $statement->getSQL(true));
  451. $statement->execute();
  452. }
  453. if ($r["multiplier_formula"] != $skill->multiplier_formula){
  454. $statement = $db->prepare("UPDATE skill SET multiplier_formula = :multiplier_formula WHERE id = :id;");
  455. $statement->bindValue(":multiplier_formula", $skill->multiplier_formula, SQLITE3_TEXT);
  456. $statement->bindValue(":id", $skill->com2us_id, SQLITE3_INTEGER);
  457. output(4, "QUERY: " . $statement->getSQL(true));
  458. $statement->execute();
  459. }
  460. // Compare existing effects
  461. $statement = $db->prepare("SELECT count(effect) AS c FROM skill_effect WHERE skill = :skill;");
  462. $statement->bindValue(":skill", $skill->com2us_id, SQLITE3_INTEGER);
  463. $q = $statement->execute();
  464. $r = $q->fetchArray(SQLITE3_ASSOC);
  465. if ($r["c"] != sizeof($skill->effects)){
  466. $statement = $db->prepare("DELETE FROM skill_effect WHERE skill = :skill;");
  467. $statement->bindValue(":skill", $skill->com2us_id, SQLITE3_INTEGER);
  468. output(4, "QUERY: " . $statement->getSQL(true));
  469. $statement->execute();
  470. foreach ($skill->effects as $effect){
  471. $statement = $db->prepare("INSERT INTO skill_effect (skill, effect) VALUES (:skill, :effect);");
  472. $statement->bindValue(":skill", $skill->com2us_id, SQLITE3_INTEGER);
  473. $statement->bindValue(":effect", $effect->effect->id, SQLITE3_INTEGER);
  474. output(4, "QUERY: " . $statement->getSQL(true));
  475. $statement->execute();
  476. }
  477. }
  478. // Image download
  479. $out = PATH . "public/img/skill/" . sprintf('%08d', $skill->com2us_id) . ".png";
  480. $url = 'https://swarfarm.com/static/herders/images/skills/' . $skill->icon_filename;
  481. download($url, $out);
  482. }
  483. }
  484. //echo "NEXTPAGE: " . $next;
  485. }
  486. // Loop monsters pages
  487. $next = URL_UNIT;
  488. while ($next != null){
  489. output(3, "Reading monsters page: $next");
  490. $contents = file_get_contents($next);
  491. if($contents === false){
  492. output(0, "Unable to retrieve monster list.");
  493. return -1;
  494. }
  495. $contents = json_decode($contents);
  496. $next = $contents->next;
  497. $list = $contents->results;
  498. foreach ($list as $monster){
  499. $statement = $db->prepare("SELECT * FROM monster WHERE id = :id");
  500. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  501. $q = $statement->execute();
  502. $r = $q->fetchArray(SQLITE3_ASSOC);
  503. if (!$r){
  504. $statement = $db->prepare("
  505. INSERT INTO monster(
  506. id,
  507. family,
  508. name,
  509. element,
  510. archetype,
  511. base_stars,
  512. natural_stars,
  513. obtainable,
  514. can_awaken,
  515. awaken_bonus,
  516. skill_ups_to_max,
  517. leader_skill,
  518. hp,
  519. attack,
  520. defense,
  521. speed,
  522. crit_rate,
  523. crit_damage,
  524. resistance,
  525. accuracy,
  526. raw_hp,
  527. raw_attack,
  528. raw_defense,
  529. max_lvl_hp,
  530. max_lvl_attack,
  531. max_lvl_defense,
  532. awakens_from,
  533. awakens_to,
  534. fusion_food,
  535. homunculus,
  536. craft_cost
  537. ) VALUES (
  538. :id,
  539. :family,
  540. :name,
  541. :element,
  542. :archetype,
  543. :base_stars,
  544. :natural_stars,
  545. :obtainable,
  546. :can_awaken,
  547. :awaken_bonus,
  548. :skill_ups_to_max,
  549. :leader_skill,
  550. :hp,
  551. :attack,
  552. :defense,
  553. :speed,
  554. :crit_rate,
  555. :crit_damage,
  556. :resistance,
  557. :accuracy,
  558. :raw_hp,
  559. :raw_attack,
  560. :raw_defense,
  561. :max_lvl_hp,
  562. :max_lvl_attack,
  563. :max_lvl_defense,
  564. :awakens_from,
  565. :awakens_to,
  566. :fusion_food,
  567. :homunculus,
  568. :craft_cost
  569. );
  570. ");
  571. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_TEXT);
  572. $statement->bindValue(":family", $monster->family_id, SQLITE3_INTEGER);
  573. $statement->bindValue(":name", $monster->name, SQLITE3_TEXT);
  574. $statement->bindValue(":element", get_element_id($monster->element), SQLITE3_INTEGER);
  575. $statement->bindValue(":archetype", get_archetype_id($monster->archetype), SQLITE3_INTEGER);
  576. $statement->bindValue(":base_stars", $monster->base_stars, SQLITE3_INTEGER);
  577. $statement->bindValue(":natural_stars", $monster->natural_stars, SQLITE3_INTEGER);
  578. $statement->bindValue(":obtainable", $monster->obtainable, SQLITE3_INTEGER);
  579. $statement->bindValue(":can_awaken", $monster->can_awaken, SQLITE3_INTEGER);
  580. $statement->bindValue(":awaken_bonus", $monster->awaken_bonus, SQLITE3_TEXT);
  581. $statement->bindValue(":skill_ups_to_max", $monster->skill_ups_to_max, SQLITE3_INTEGER);
  582. if (isset($monster->leader_skill->id)){
  583. $statement->bindValue(":leader_skill", $monster->leader_skill, SQLITE3_INTEGER);
  584. }
  585. else{
  586. $statement->bindValue(":leader_skill", null, SQLITE3_INTEGER);
  587. }
  588. $statement->bindValue(":hp", $monster->base_hp, SQLITE3_INTEGER);
  589. $statement->bindValue(":attack", $monster->base_attack, SQLITE3_INTEGER);
  590. $statement->bindValue(":defense", $monster->base_defense, SQLITE3_INTEGER);
  591. $statement->bindValue(":speed", $monster->speed, SQLITE3_INTEGER);
  592. $statement->bindValue(":crit_rate", $monster->crit_rate, SQLITE3_INTEGER);
  593. $statement->bindValue(":crit_damage", $monster->crit_damage, SQLITE3_INTEGER);
  594. $statement->bindValue(":resistance", $monster->resistance, SQLITE3_INTEGER);
  595. $statement->bindValue(":accuracy", $monster->accuracy, SQLITE3_INTEGER);
  596. $statement->bindValue(":raw_hp", $monster->raw_hp, SQLITE3_INTEGER);
  597. $statement->bindValue(":raw_attack", $monster->raw_attack, SQLITE3_INTEGER);
  598. $statement->bindValue(":raw_defense", $monster->raw_defense, SQLITE3_INTEGER);
  599. $statement->bindValue(":max_lvl_hp", $monster->max_lvl_hp, SQLITE3_INTEGER);
  600. $statement->bindValue(":max_lvl_attack", $monster->max_lvl_attack, SQLITE3_INTEGER);
  601. $statement->bindValue(":max_lvl_defense", $monster->max_lvl_defense, SQLITE3_INTEGER);
  602. $statement->bindValue(":awakens_from", get_com2us_id($monster->awakens_from), SQLITE3_TEXT);
  603. $statement->bindValue(":awakens_to", get_com2us_id($monster->awakens_to), SQLITE3_TEXT);
  604. $statement->bindValue(":fusion_food", $monster->fusion_food, SQLITE3_INTEGER);
  605. $statement->bindValue(":homunculus", $monster->homunculus, SQLITE3_INTEGER);
  606. $statement->bindValue(":craft_cost", 0, SQLITE3_INTEGER);
  607. output(4, "QUERY: " . $statement->getSQL(true));
  608. $statement->execute();
  609. $url = 'https://swarfarm.com/static/herders/images/monsters/' . $monster->image_filename;
  610. $out = PATH . "public/img/unit/" . sprintf('%08d', $monster->com2us_id) . ".png";
  611. download($url, $out);
  612. // Skills (not in database yet, but they will be once skills are parsed)
  613. foreach ($monster->skills as $skill){
  614. $statement = $db->prepare("INSERT INTO monster_skill (monster, skill) VALUES (:monster, :skill);");
  615. $statement->bindValue(":monster", $monster->com2us_id, SQLITE3_INTEGER);
  616. $statement->bindValue(":skill", get_com2us_skill_id($skill), SQLITE3_INTEGER);
  617. output(4, "QUERY: " . $statement->getSQL(true));
  618. $statement->execute();
  619. }
  620. // Essences to awaken
  621. foreach ($monster->awaken_cost as $essence){
  622. $statement = $db->prepare("INSERT INTO monster_essence (monster, item, amount) VALUES (:monster, :item, :amount);");
  623. $statement->bindValue(":monster", $monster->com2us_id, SQLITE3_INTEGER);
  624. $statement->bindValue(":item", $essence->item->com2us_id, SQLITE3_INTEGER);
  625. $statement->bindValue(":amount", $essence->quantity, SQLITE3_INTEGER);
  626. output(4, "QUERY: " . $statement->getSQL(true));
  627. $statement->execute();
  628. }
  629. // Unit sources
  630. foreach ($monster->source as $source){
  631. $statement = $db->prepare("INSERT INTO monster_source (monster, source) VALUES (:monster, :source);");
  632. $statement->bindValue(":monster", $monster->com2us_id, SQLITE3_INTEGER);
  633. $statement->bindValue(":source", $source->id, SQLITE3_INTEGER);
  634. output(4, "QUERY: " . $statement->getSQL(true));
  635. $statement->execute();
  636. }
  637. }
  638. else{
  639. // Compare all values
  640. if ($r["family"] != $monster->family_id){
  641. $statement = $db->prepare("UPDATE monster SET family = :family WHERE id = :id;");
  642. $statement->bindValue(":family", $monster->family_id, SQLITE3_INTEGER);
  643. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  644. output(4, "QUERY: " . $statement->getSQL(true));
  645. $statement->execute();
  646. }
  647. if ($r["name"] != $monster->name){
  648. $statement = $db->prepare("UPDATE monster SET name = :name WHERE id = :id;");
  649. $statement->bindValue(":name", $monster->name, SQLITE3_TEXT);
  650. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  651. output(4, "QUERY: " . $statement->getSQL(true));
  652. $statement->execute();
  653. }
  654. $element = get_element_id($monster->element);
  655. if ($r["element"] != $element){
  656. $statement = $db->prepare("UPDATE monster SET element = :element WHERE id = :id;");
  657. $statement->bindValue(":element", $element, SQLITE3_TEXT);
  658. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  659. output(4, "QUERY: " . $statement->getSQL(true));
  660. $statement->execute();
  661. }
  662. $archetype = get_archetype_id($monster->archetype);
  663. if ($r["archetype"] != $archetype){
  664. $statement = $db->prepare("UPDATE monster SET archetype = :archetype WHERE id = :id;");
  665. $statement->bindValue(":archetype", $archetype, SQLITE3_TEXT);
  666. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  667. output(4, "QUERY: " . $statement->getSQL(true));
  668. $statement->execute();
  669. }
  670. if ($r["base_stars"] != $monster->base_stars){
  671. $statement = $db->prepare("UPDATE monster SET base_stars = :base_stars WHERE id = :id;");
  672. $statement->bindValue(":base_stars", $monster->base_stars, SQLITE3_INTEGER);
  673. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  674. output(4, "QUERY: " . $statement->getSQL(true));
  675. $statement->execute();
  676. }
  677. if ($r["natural_stars"] != $monster->natural_stars){
  678. $statement = $db->prepare("UPDATE monster SET natural_stars = :natural_stars WHERE id = :id;");
  679. $statement->bindValue(":natural_stars", $monster->natural_stars, SQLITE3_INTEGER);
  680. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  681. output(4, "QUERY: " . $statement->getSQL(true));
  682. $statement->execute();
  683. }
  684. if ($r["obtainable"] != $monster->obtainable){
  685. $statement = $db->prepare("UPDATE monster SET obtainable = :obtainable WHERE id = :id;");
  686. $statement->bindValue(":obtainable", $monster->obtainable, SQLITE3_INTEGER);
  687. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  688. output(4, "QUERY: " . $statement->getSQL(true));
  689. $statement->execute();
  690. }
  691. if ($r["can_awaken"] != $monster->can_awaken){
  692. $statement = $db->prepare("UPDATE monster SET can_awaken = :can_awaken WHERE id = :id;");
  693. $statement->bindValue(":can_awaken", $monster->can_awaken, SQLITE3_INTEGER);
  694. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  695. output(4, "QUERY: " . $statement->getSQL(true));
  696. $statement->execute();
  697. }
  698. if ($r["awaken_bonus"] != $monster->awaken_bonus && $monster->awaken_bonus != 0){
  699. $statement = $db->prepare("UPDATE monster SET awaken_bonus = :awaken_bonus WHERE id = :id;");
  700. $statement->bindValue(":awaken_bonus", $monster->awaken_bonus, SQLITE3_TEXT);
  701. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_TEXT);
  702. output(4, "QUERY: " . $statement->getSQL(true));
  703. $statement->execute();
  704. }
  705. if ($r["skill_ups_to_max"] != $monster->skill_ups_to_max){
  706. $statement = $db->prepare("UPDATE monster SET skill_ups_to_max = :skill_ups_to_max WHERE id = :id;");
  707. $statement->bindValue(":skill_ups_to_max", $monster->skill_ups_to_max, SQLITE3_INTEGER);
  708. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  709. output(4, "QUERY: " . $statement->getSQL(true));
  710. $statement->execute();
  711. }
  712. if (isset($monster->leader_skill->id) && $r["leader_skill"] != $monster->leader_skill->id){
  713. $statement = $db->prepare("UPDATE monster SET leader_skill = :leader_skill WHERE id = :id;");
  714. $statement->bindValue(":leader_skill", $monster->leader_skill->id, SQLITE3_TEXT);
  715. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  716. output(4, "QUERY: " . $statement->getSQL(true));
  717. $statement->execute();
  718. }
  719. if ($r["hp"] != $monster->base_hp){
  720. $statement = $db->prepare("UPDATE monster SET hp = :hp WHERE id = :id;");
  721. $statement->bindValue(":hp", $monster->base_hp, SQLITE3_INTEGER);
  722. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  723. output(4, "QUERY: " . $statement->getSQL(true));
  724. $statement->execute();
  725. }
  726. if ($r["attack"] != $monster->base_attack){
  727. $statement = $db->prepare("UPDATE monster SET attack = :attack WHERE id = :id;");
  728. $statement->bindValue(":attack", $monster->base_attack, SQLITE3_INTEGER);
  729. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  730. output(4, "QUERY: " . $statement->getSQL(true));
  731. $statement->execute();
  732. }
  733. if ($r["defense"] != $monster->base_defense){
  734. $statement = $db->prepare("UPDATE monster SET defense = :defense WHERE id = :id;");
  735. $statement->bindValue(":defense", $monster->base_defense, SQLITE3_INTEGER);
  736. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  737. output(4, "QUERY: " . $statement->getSQL(true));
  738. $statement->execute();
  739. }
  740. if ($r["speed"] != $monster->speed){
  741. $statement = $db->prepare("UPDATE monster SET speed = :speed WHERE id = :id;");
  742. $statement->bindValue(":speed", $monster->speed, SQLITE3_INTEGER);
  743. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  744. output(4, "QUERY: " . $statement->getSQL(true));
  745. $statement->execute();
  746. }
  747. if ($r["crit_rate"] != $monster->crit_rate){
  748. $statement = $db->prepare("UPDATE monster SET crit_rate = :crit_rate WHERE id = :id;");
  749. $statement->bindValue(":crit_rate", $monster->crit_rate, SQLITE3_INTEGER);
  750. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  751. output(4, "QUERY: " . $statement->getSQL(true));
  752. $statement->execute();
  753. }
  754. if ($r["crit_damage"] != $monster->crit_damage){
  755. $statement = $db->prepare("UPDATE monster SET crit_damage = :crit_damage WHERE id = :id;");
  756. $statement->bindValue(":crit_damage", $monster->crit_damage, SQLITE3_INTEGER);
  757. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  758. output(4, "QUERY: " . $statement->getSQL(true));
  759. $statement->execute();
  760. }
  761. if ($r["resistance"] != $monster->resistance){
  762. $statement = $db->prepare("UPDATE monster SET resistance = :resistance WHERE id = :id;");
  763. $statement->bindValue(":resistance", $monster->resistance, SQLITE3_INTEGER);
  764. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  765. output(4, "QUERY: " . $statement->getSQL(true));
  766. $statement->execute();
  767. }
  768. if ($r["accuracy"] != $monster->accuracy){
  769. $statement = $db->prepare("UPDATE monster SET accuracy = :accuracy WHERE id = :id;");
  770. $statement->bindValue(":accuracy", $monster->accuracy, SQLITE3_INTEGER);
  771. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  772. output(4, "QUERY: " . $statement->getSQL(true));
  773. $statement->execute();
  774. }
  775. if ($r["raw_hp"] != $monster->raw_hp){
  776. $statement = $db->prepare("UPDATE monster SET raw_hp = :raw_hp WHERE id = :id;");
  777. $statement->bindValue(":raw_hp", $monster->raw_hp, SQLITE3_INTEGER);
  778. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  779. output(4, "QUERY: " . $statement->getSQL(true));
  780. $statement->execute();
  781. }
  782. if ($r["raw_attack"] != $monster->raw_attack){
  783. $statement = $db->prepare("UPDATE monster SET raw_attack = :raw_attack WHERE id = :id;");
  784. $statement->bindValue(":raw_attack", $monster->raw_attack, SQLITE3_INTEGER);
  785. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  786. output(4, "QUERY: " . $statement->getSQL(true));
  787. $statement->execute();
  788. }
  789. if ($r["raw_defense"] != $monster->raw_defense){
  790. $statement = $db->prepare("UPDATE monster SET raw_defense = :raw_defense WHERE id = :id;");
  791. $statement->bindValue(":raw_defense", $monster->raw_defense, SQLITE3_INTEGER);
  792. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  793. output(4, "QUERY: " . $statement->getSQL(true));
  794. $statement->execute();
  795. }
  796. if ($r["max_lvl_hp"] != $monster->max_lvl_hp){
  797. $statement = $db->prepare("UPDATE monster SET max_lvl_hp = :max_lvl_hp WHERE id = :id;");
  798. $statement->bindValue(":max_lvl_hp", $monster->max_lvl_hp, SQLITE3_INTEGER);
  799. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  800. output(4, "QUERY: " . $statement->getSQL(true));
  801. $statement->execute();
  802. }
  803. if ($r["max_lvl_attack"] != $monster->max_lvl_attack){
  804. $statement = $db->prepare("UPDATE monster SET max_lvl_attack = :max_lvl_attack WHERE id = :id;");
  805. $statement->bindValue(":max_lvl_attack", $monster->max_lvl_attack, SQLITE3_INTEGER);
  806. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  807. output(4, "QUERY: " . $statement->getSQL(true));
  808. $statement->execute();
  809. }
  810. if ($r["max_lvl_defense"] != $monster->max_lvl_defense){
  811. $statement = $db->prepare("UPDATE monster SET max_lvl_defense = :max_lvl_defense WHERE id = :id;");
  812. $statement->bindValue(":max_lvl_defense", $monster->max_lvl_defense, SQLITE3_INTEGER);
  813. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  814. output(4, "QUERY: " . $statement->getSQL(true));
  815. $statement->execute();
  816. }
  817. $com2us_id = get_com2us_id($monster->awakens_from);
  818. if ($r["awakens_from"] != $com2us_id){
  819. $statement = $db->prepare("UPDATE monster SET awakens_from = :awakens_from WHERE id = :id;");
  820. $statement->bindValue(":awakens_from", $com2us_id, SQLITE3_INTEGER);
  821. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  822. output(4, "QUERY: " . $statement->getSQL(true));
  823. $statement->execute();
  824. }
  825. $com2us_id = get_com2us_id($monster->awakens_to);
  826. if ($r["awakens_to"] != $com2us_id){
  827. $statement = $db->prepare("UPDATE monster SET awakens_to = :awakens_to WHERE id = :id;");
  828. $statement->bindValue(":awakens_to", $com2us_id, SQLITE3_INTEGER);
  829. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  830. output(4, "QUERY: " . $statement->getSQL(true));
  831. $statement->execute();
  832. }
  833. if ($r["fusion_food"] != $monster->fusion_food){
  834. $statement = $db->prepare("UPDATE monster SET fusion_food = :fusion_food WHERE id = :id;");
  835. $statement->bindValue(":fusion_food", $monster->fusion_food, SQLITE3_INTEGER);
  836. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  837. output(4, "QUERY: " . $statement->getSQL(true));
  838. $statement->execute();
  839. }
  840. if ($r["homunculus"] != $monster->homunculus){
  841. $statement = $db->prepare("UPDATE monster SET homunculus = :homunculus WHERE id = :id;");
  842. $statement->bindValue(":homunculus", $monster->homunculus, SQLITE3_INTEGER);
  843. $statement->bindValue(":id", $monster->com2us_id, SQLITE3_INTEGER);
  844. output(4, "QUERY: " . $statement->getSQL(true));
  845. $statement->execute();
  846. }
  847. // Loop skills. Only for inserting in skill and monster_skill
  848. $statement = $db->prepare("SELECT count(skill) AS c FROM monster_skill WHERE monster = :monster;");
  849. $statement->bindValue(":monster", $monster->com2us_id, SQLITE3_INTEGER);
  850. $q = $statement->execute();
  851. $r = $q->fetchArray(SQLITE3_ASSOC);
  852. // If some errors happens and the skill list has to be rebuilt,
  853. // force this block to execute (it is slow).
  854. // if ($r["c"] != sizeof($monster->skills))
  855. if ($r["c"] != sizeof($monster->skills) || 1 == 1){
  856. $statement = $db->prepare("DELETE FROM monster_skill WHERE monster = :monster;");
  857. $statement->bindValue(":monster", $monster->com2us_id, SQLITE3_INTEGER);
  858. output(4, "QUERY: " . $statement->getSQL(true));
  859. $statement->execute();
  860. foreach ($monster->skills as $skill){
  861. $statement = $db->prepare("INSERT INTO monster_skill (monster, skill) VALUES (:monster, :skill);");
  862. $statement->bindValue(":monster", $monster->com2us_id, SQLITE3_INTEGER);
  863. $statement->bindValue(":skill", get_com2us_skill_id($skill), SQLITE3_INTEGER);
  864. output(4, "QUERY: " . $statement->getSQL(true));
  865. $statement->execute();
  866. }
  867. }
  868. // Essences to awaken
  869. $statement = $db->prepare("SELECT count(item) AS c FROM monster_essence WHERE monster = :monster;");
  870. $statement->bindValue(":monster", $monster->com2us_id, SQLITE3_INTEGER);
  871. $q = $statement->execute();
  872. $r = $q->fetchArray(SQLITE3_ASSOC);
  873. if ($r["c"] != sizeof($monster->awaken_cost)){
  874. $statement = $db->prepare("DELETE FROM monster_essence WHERE monster = :monster;");
  875. $statement->bindValue(":monster", $monster->com2us_id, SQLITE3_INTEGER);
  876. output(4, "QUERY: " . $statement->getSQL(true));
  877. $statement->execute();
  878. foreach ($monster->awaken_cost as $essence){
  879. $statement = $db->prepare("INSERT INTO monster_essence (monster, item, amount) VALUES (:monster, :item, :amount);");
  880. $statement->bindValue(":monster", $monster->com2us_id, SQLITE3_INTEGER);
  881. $statement->bindValue(":item", $essence->item->com2us_id, SQLITE3_INTEGER);
  882. $statement->bindValue(":amount", $essence->quantity, SQLITE3_INTEGER);
  883. output(4, "QUERY: " . $statement->getSQL(true));
  884. $statement->execute();
  885. }
  886. }
  887. // Unit sources
  888. $statement = $db->prepare("SELECT count(source) AS c FROM monster_source WHERE monster = :monster;");
  889. $statement->bindValue(":monster", $monster->com2us_id, SQLITE3_INTEGER);
  890. $q = $statement->execute();
  891. $r = $q->fetchArray(SQLITE3_ASSOC);
  892. if ($r["c"] != sizeof($monster->source)){
  893. $statement = $db->prepare("DELETE FROM monster_source WHERE monster = :monster;");
  894. $statement->bindValue(":monster", $monster->com2us_id, SQLITE3_INTEGER);
  895. output(4, "QUERY: " . $statement->getSQL(true));
  896. $statement->execute();
  897. foreach ($monster->source as $source){
  898. $statement = $db->prepare("INSERT INTO monster_source (monster, source) VALUES (:monster, :source);");
  899. $statement->bindValue(":monster", $monster->com2us_id, SQLITE3_INTEGER);
  900. $statement->bindValue(":source", $source->id, SQLITE3_INTEGER);
  901. output(4, "QUERY: " . $statement->getSQL(true));
  902. $statement->execute();
  903. }
  904. }
  905. // Image download
  906. $out = PATH . "public/img/unit/" . sprintf('%08d', $monster->com2us_id) . ".png";
  907. $url = 'https://swarfarm.com/static/herders/images/monsters/' . $monster->image_filename;
  908. download($url, $out);
  909. }
  910. }
  911. //echo "NEXTPAGE: " . $next;
  912. }