/SkyBlockPE/SkyBlockPE-master/src/thebigsmileXD/SkyBlock/provider/SQLiteDataProvider.php

https://gitlab.com/Skull3x/WorkingInProgress-Plugins-Sourcecode-For-Dev · PHP · 211 lines · 193 code · 14 blank · 4 comment · 34 complexity · 7faf4c824b48202a09f94dc633572320 MD5 · raw file

  1. <?php
  2. namespace thebigsmileXD\SkyBlock\provider;
  3. use thebigsmileXD\SkyBlock\Plot;
  4. use SQLite3;
  5. use SQLite3Stmt;
  6. use thebigsmileXD\SkyBlock\SkyBlock;
  7. class SQLiteDataProvider extends DataProvider
  8. {
  9. /** @var SQLite3 */
  10. private $db;
  11. /** @var SQLite3Stmt */
  12. private $sqlGetPlot, $sqlSavePlot, $sqlSavePlotById, $sqlRemovePlot,
  13. $sqlRemovePlotById, $sqlGetPlotsByOwner, $sqlGetPlotsByOwnerAndLevel,
  14. $sqlGetExistingXZ;
  15. public function __construct(SkyBlock $plugin, $cacheSize = 0) {
  16. parent::__construct($plugin, $cacheSize);
  17. $this->db = new SQLite3($this->plugin->getDataFolder() . "plots.db");
  18. $this->db->exec(
  19. "CREATE TABLE IF NOT EXISTS plots
  20. (id INTEGER PRIMARY KEY AUTOINCREMENT, level TEXT, X INTEGER, Z INTEGER, name TEXT,
  21. owner TEXT, helpers TEXT, biome TEXT)"
  22. );
  23. $this->sqlGetPlot = $this->db->prepare(
  24. "SELECT id, name, owner, helpers, biome FROM plots WHERE level = :level AND X = :X AND Z = :Z"
  25. );
  26. $this->sqlSavePlot = $this->db->prepare(
  27. "INSERT OR REPLACE INTO plots (id, level, X, Z, name, owner, helpers, biome) VALUES
  28. ((select id from plots where level = :level AND X = :X AND Z = :Z),
  29. :level, :X, :Z, :name, :owner, :helpers, :biome);"
  30. );
  31. $this->sqlSavePlotById = $this->db->prepare(
  32. "UPDATE plots SET name = :name, owner = :owner, helpers = :helpers, biome = :biome WHERE id = :id"
  33. );
  34. $this->sqlRemovePlot = $this->db->prepare(
  35. "DELETE FROM plots WHERE level = :level AND X = :X AND Z = :Z"
  36. );
  37. $this->sqlRemovePlotById = $this->db->prepare("DELETE FROM plots WHERE id = :id");
  38. $this->sqlGetPlotsByOwner = $this->db->prepare("SELECT * FROM plots WHERE owner = :owner");
  39. $this->sqlGetPlotsByOwnerAndLevel = $this->db->prepare(
  40. "SELECT * FROM plots WHERE owner = :owner AND level = :level"
  41. );
  42. $this->sqlGetExistingXZ = $this->db->prepare(
  43. "SELECT X, Z FROM plots WHERE (
  44. level = :level
  45. AND (
  46. (abs(X) == :number AND abs(Z) <= :number) OR
  47. (abs(Z) == :number AND abs(X) <= :number)
  48. )
  49. )"
  50. );
  51. }
  52. public function close() {
  53. $this->db->close();
  54. }
  55. public function savePlot(Plot $plot) {
  56. $helpers = implode(",", $plot->helpers);
  57. if ($plot->id >= 0) {
  58. $stmt = $this->sqlSavePlotById;
  59. $stmt->bindValue(":id", $plot->id, SQLITE3_INTEGER);
  60. } else {
  61. $stmt = $this->sqlSavePlot;
  62. $stmt->bindValue(":level", $plot->levelName, SQLITE3_TEXT);
  63. $stmt->bindValue(":X", $plot->X, SQLITE3_INTEGER);
  64. $stmt->bindValue(":Z", $plot->Z, SQLITE3_INTEGER);
  65. }
  66. $stmt->bindValue(":name", $plot->name, SQLITE3_TEXT);
  67. $stmt->bindValue(":owner", $plot->owner, SQLITE3_TEXT);
  68. $stmt->bindValue(":helpers", $helpers, SQLITE3_TEXT);
  69. $stmt->bindValue(":biome", $plot->biome, SQLITE3_TEXT);
  70. $stmt->reset();
  71. $result = $stmt->execute();
  72. if ($result === false) {
  73. return false;
  74. }
  75. $this->cachePlot($plot);
  76. return true;
  77. }
  78. public function deletePlot(Plot $plot) {
  79. if ($plot->id >= 0) {
  80. $stmt = $this->sqlRemovePlotById;
  81. $stmt->bindValue(":id", $plot->id, SQLITE3_INTEGER);
  82. } else {
  83. $stmt = $this->sqlRemovePlot;
  84. $stmt->bindValue(":level", $plot->levelName, SQLITE3_TEXT);
  85. $stmt->bindValue(":X", $plot->X, SQLITE3_INTEGER);
  86. $stmt->bindValue(":Z", $plot->Z, SQLITE3_INTEGER);
  87. }
  88. $stmt->reset();
  89. $result = $stmt->execute();
  90. if ($result === false) {
  91. return false;
  92. }
  93. $plot = new Plot($plot->levelName, $plot->X, $plot->Z);
  94. $this->cachePlot($plot);
  95. return true;
  96. }
  97. public function getPlot($levelName, $X, $Z) {
  98. if ($plot = $this->getPlotFromCache($levelName, $X, $Z)) {
  99. return $plot;
  100. }
  101. $this->sqlGetPlot->bindValue(":level", $levelName, SQLITE3_TEXT);
  102. $this->sqlGetPlot->bindValue(":X", $X, SQLITE3_INTEGER);
  103. $this->sqlGetPlot->bindValue(":Z", $Z, SQLITE3_INTEGER);
  104. $this->sqlGetPlot->reset();
  105. $result = $this->sqlGetPlot->execute();
  106. if ($val = $result->fetchArray(SQLITE3_ASSOC)) {
  107. if ($val["helpers"] === null or $val["helpers"] === "") {
  108. $helpers = [];
  109. } else {
  110. $helpers = explode(",", (string)$val["helpers"]);
  111. }
  112. $plot = new Plot($levelName, $X, $Z, (string)$val["name"], (string)$val["owner"],
  113. $helpers, (string)$val["biome"], (int)$val["id"]);
  114. } else {
  115. $plot = new Plot($levelName, $X, $Z);
  116. }
  117. $this->cachePlot($plot);
  118. return $plot;
  119. }
  120. public function getPlotsByOwner($owner, $levelName = "") {
  121. if ($levelName === "") {
  122. $stmt = $this->sqlGetPlotsByOwner;
  123. } else {
  124. $stmt = $this->sqlGetPlotsByOwnerAndLevel;
  125. $stmt->bindValue(":level", $levelName, SQLITE3_TEXT);
  126. }
  127. $stmt->bindValue(":owner", $owner, SQLITE3_TEXT);
  128. $plots = [];
  129. $stmt->reset();
  130. $result = $stmt->execute();
  131. while ($val = $result->fetchArray(SQLITE3_ASSOC)) {
  132. $helpers = explode(",", (string)$val["helpers"]);
  133. $plots[] = new Plot((string)$val["level"], (int)$val["X"], (int)$val["Z"], (string)$val["name"],
  134. (string)$val["owner"], $helpers, (string)$val["biome"], (int)$val["id"]);
  135. }
  136. usort($plots, function ($plot1, $plot2) {
  137. /** @var Plot $plot1 */
  138. /** @var Plot $plot2 */
  139. return strcmp($plot1->levelName, $plot2->levelName);
  140. });
  141. return $plots;
  142. }
  143. public function getNextFreePlot($levelName, $limitXZ = 20) {
  144. $this->sqlGetExistingXZ->bindValue(":level", $levelName, SQLITE3_TEXT);
  145. $i = 0;
  146. $this->sqlGetExistingXZ->bindParam(":number", $i, SQLITE3_INTEGER);
  147. for (; $i < $limitXZ; $i++) {
  148. $this->sqlGetExistingXZ->reset();
  149. $result = $this->sqlGetExistingXZ->execute();
  150. $plots = [];
  151. while ($val = $result->fetchArray(SQLITE3_NUM)) {
  152. $plots[$val[0]][$val[1]] = true;
  153. }
  154. if (count($plots) === max(1, 8 * $i)) {
  155. continue;
  156. }
  157. if ($ret = self::findEmptyPlotSquared(0, $i, $plots)) {
  158. list($X, $Z) = $ret;
  159. $plot = new Plot($levelName, $X, $Z);
  160. $this->cachePlot($plot);
  161. return $plot;
  162. }
  163. for ($a = 1; $a < $i; $a++) {
  164. if ($ret = self::findEmptyPlotSquared($a, $i, $plots)) {
  165. list($X, $Z) = $ret;
  166. $plot = new Plot($levelName, $X, $Z);
  167. $this->cachePlot($plot);
  168. return $plot;
  169. }
  170. }
  171. if ($ret = self::findEmptyPlotSquared($i, $i, $plots)) {
  172. list($X, $Z) = $ret;
  173. $plot = new Plot($levelName, $X, $Z);
  174. $this->cachePlot($plot);
  175. return $plot;
  176. }
  177. }
  178. return null;
  179. }
  180. private static function findEmptyPlotSquared($a, $b, &$plots) {
  181. if (!isset($plots[$a][$b])) return array($a, $b);
  182. if (!isset($plots[$b][$a])) return array($b, $a);
  183. if ($a !== 0) {
  184. if (!isset($plots[-$a][$b])) return array(-$a, $b);
  185. if (!isset($plots[$b][-$a])) return array($b, -$a);
  186. }
  187. if ($b !== 0) {
  188. if (!isset($plots[-$b][$a])) return array(-$b, $a);
  189. if (!isset($plots[$a][-$b])) return array($a, -$b);
  190. }
  191. if ($a | $b === 0) {
  192. if (!isset($plots[-$a][-$b])) return array(-$a, -$b);
  193. if (!isset($plots[-$b][-$a])) return array(-$b, -$a);
  194. }
  195. return null;
  196. }
  197. }