PageRenderTime 133ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/worldguard-legacy/src/main/java/com/sk89q/worldguard/protection/managers/storage/sql/DataLoader.java

https://gitlab.com/igserfurtmcschulserver/CustomWorldGuard
Java | 339 lines | 257 code | 59 blank | 23 comment | 28 complexity | b78516766a94483d9d5ba1e863c8137d MD5 | raw file
  1. /*
  2. * WorldGuard, a suite of tools for Minecraft
  3. * Copyright (C) sk89q <http://www.sk89q.com>
  4. * Copyright (C) WorldGuard team and contributors
  5. *
  6. * This program is free software: you can redistribute it and/or modify it
  7. * under the terms of the GNU Lesser General Public License as published by the
  8. * Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
  14. * for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.sk89q.worldguard.protection.managers.storage.sql;
  20. import com.google.common.collect.ArrayListMultimap;
  21. import com.google.common.collect.HashBasedTable;
  22. import com.google.common.collect.ListMultimap;
  23. import com.google.common.collect.Table;
  24. import com.sk89q.worldedit.BlockVector;
  25. import com.sk89q.worldedit.BlockVector2D;
  26. import com.sk89q.worldedit.Vector;
  27. import com.sk89q.worldguard.domains.DefaultDomain;
  28. import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
  29. import com.sk89q.worldguard.protection.managers.storage.RegionDatabaseUtils;
  30. import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
  31. import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
  32. import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
  33. import com.sk89q.worldguard.protection.regions.ProtectedRegion;
  34. import com.sk89q.worldguard.util.io.Closer;
  35. import com.sk89q.worldguard.util.sql.DataSourceConfig;
  36. import org.yaml.snakeyaml.Yaml;
  37. import org.yaml.snakeyaml.error.YAMLException;
  38. import java.sql.Connection;
  39. import java.sql.PreparedStatement;
  40. import java.sql.ResultSet;
  41. import java.sql.SQLException;
  42. import java.util.HashMap;
  43. import java.util.HashSet;
  44. import java.util.List;
  45. import java.util.Map;
  46. import java.util.Map.Entry;
  47. import java.util.Set;
  48. import java.util.UUID;
  49. import java.util.logging.Level;
  50. import java.util.logging.Logger;
  51. import static com.google.common.base.Preconditions.checkNotNull;
  52. class DataLoader {
  53. private static final Logger log = Logger.getLogger(DataLoader.class.getCanonicalName());
  54. final Connection conn;
  55. final DataSourceConfig config;
  56. final int worldId;
  57. final FlagRegistry flagRegistry;
  58. private final Map<String, ProtectedRegion> loaded = new HashMap<String, ProtectedRegion>();
  59. private final Map<ProtectedRegion, String> parentSets = new HashMap<ProtectedRegion, String>();
  60. private final Yaml yaml = SQLRegionDatabase.createYaml();
  61. DataLoader(SQLRegionDatabase regionStore, Connection conn, FlagRegistry flagRegistry) throws SQLException {
  62. checkNotNull(regionStore);
  63. this.conn = conn;
  64. this.config = regionStore.getDataSourceConfig();
  65. this.worldId = regionStore.getWorldId();
  66. this.flagRegistry = flagRegistry;
  67. }
  68. public Set<ProtectedRegion> load() throws SQLException {
  69. loadCuboids();
  70. loadPolygons();
  71. loadGlobals();
  72. loadFlags();
  73. loadDomainUsers();
  74. loadDomainGroups();
  75. RegionDatabaseUtils.relinkParents(loaded, parentSets);
  76. return new HashSet<ProtectedRegion>(loaded.values());
  77. }
  78. private void loadCuboids() throws SQLException {
  79. Closer closer = Closer.create();
  80. try {
  81. PreparedStatement stmt = closer.register(conn.prepareStatement(
  82. "SELECT g.min_z, g.min_y, g.min_x, " +
  83. " g.max_z, g.max_y, g.max_x, " +
  84. " r.id, r.priority, p.id AS parent " +
  85. "FROM " + config.getTablePrefix() + "region_cuboid AS g " +
  86. "LEFT JOIN " + config.getTablePrefix() + "region AS r " +
  87. " ON (g.region_id = r.id AND g.world_id = r.world_id) " +
  88. "LEFT JOIN " + config.getTablePrefix() + "region AS p " +
  89. " ON (r.parent = p.id AND r.world_id = p.world_id) " +
  90. "WHERE r.world_id = " + worldId));
  91. ResultSet rs = closer.register(stmt.executeQuery());
  92. while (rs.next()) {
  93. Vector pt1 = new Vector(rs.getInt("min_x"), rs.getInt("min_y"), rs.getInt("min_z"));
  94. Vector pt2 = new Vector(rs.getInt("max_x"), rs.getInt("max_y"), rs.getInt("max_z"));
  95. BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector();
  96. BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector();
  97. ProtectedRegion region = new ProtectedCuboidRegion(rs.getString("id"), min, max);
  98. region.setPriority(rs.getInt("priority"));
  99. loaded.put(rs.getString("id"), region);
  100. String parentId = rs.getString("parent");
  101. if (parentId != null) {
  102. parentSets.put(region, parentId);
  103. }
  104. }
  105. } finally {
  106. closer.closeQuietly();
  107. }
  108. }
  109. private void loadGlobals() throws SQLException {
  110. Closer closer = Closer.create();
  111. try {
  112. PreparedStatement stmt = closer.register(conn.prepareStatement(
  113. "SELECT r.id, r.priority, p.id AS parent " +
  114. "FROM " + config.getTablePrefix() + "region AS r " +
  115. "LEFT JOIN " + config.getTablePrefix() + "region AS p " +
  116. " ON (r.parent = p.id AND r.world_id = p.world_id) " +
  117. "WHERE r.type = 'global' AND r.world_id = " + worldId));
  118. ResultSet rs = closer.register(stmt.executeQuery());
  119. while (rs.next()) {
  120. ProtectedRegion region = new GlobalProtectedRegion(rs.getString("id"));
  121. region.setPriority(rs.getInt("priority"));
  122. loaded.put(rs.getString("id"), region);
  123. String parentId = rs.getString("parent");
  124. if (parentId != null) {
  125. parentSets.put(region, parentId);
  126. }
  127. }
  128. } finally {
  129. closer.closeQuietly();
  130. }
  131. }
  132. private void loadPolygons() throws SQLException {
  133. ListMultimap<String, BlockVector2D> pointsCache = ArrayListMultimap.create();
  134. // First get all the vertices and store them in memory
  135. Closer closer = Closer.create();
  136. try {
  137. PreparedStatement stmt = closer.register(conn.prepareStatement(
  138. "SELECT region_id, x, z " +
  139. "FROM " + config.getTablePrefix() + "region_poly2d_point " +
  140. "WHERE world_id = " + worldId));
  141. ResultSet rs = closer.register(stmt.executeQuery());
  142. while (rs.next()) {
  143. pointsCache.put(rs.getString("region_id"), new BlockVector2D(rs.getInt("x"), rs.getInt("z")));
  144. }
  145. } finally {
  146. closer.closeQuietly();
  147. }
  148. // Now we pull the regions themselves
  149. closer = Closer.create();
  150. try {
  151. PreparedStatement stmt = closer.register(conn.prepareStatement(
  152. "SELECT g.min_y, g.max_y, r.id, r.priority, p.id AS parent " +
  153. "FROM " + config.getTablePrefix() + "region_poly2d AS g " +
  154. "LEFT JOIN " + config.getTablePrefix() + "region AS r " +
  155. " ON (g.region_id = r.id AND g.world_id = r.world_id) " +
  156. "LEFT JOIN " + config.getTablePrefix() + "region AS p " +
  157. " ON (r.parent = p.id AND r.world_id = p.world_id) " +
  158. "WHERE r.world_id = " + worldId
  159. ));
  160. ResultSet rs = closer.register(stmt.executeQuery());
  161. while (rs.next()) {
  162. String id = rs.getString("id");
  163. // Get the points from the cache
  164. List<BlockVector2D> points = pointsCache.get(id);
  165. if (points.size() < 3) {
  166. log.log(Level.WARNING, "Invalid polygonal region '" + id + "': region has " + points.size() + " point(s) (less than the required 3). Skipping this region.");
  167. continue;
  168. }
  169. Integer minY = rs.getInt("min_y");
  170. Integer maxY = rs.getInt("max_y");
  171. ProtectedRegion region = new ProtectedPolygonalRegion(id, points, minY, maxY);
  172. region.setPriority(rs.getInt("priority"));
  173. loaded.put(id, region);
  174. String parentId = rs.getString("parent");
  175. if (parentId != null) {
  176. parentSets.put(region, parentId);
  177. }
  178. }
  179. } finally {
  180. closer.closeQuietly();
  181. }
  182. }
  183. private void loadFlags() throws SQLException {
  184. Closer closer = Closer.create();
  185. try {
  186. PreparedStatement stmt = closer.register(conn.prepareStatement(
  187. "SELECT region_id, flag, value " +
  188. "FROM " + config.getTablePrefix() + "region_flag " +
  189. "WHERE world_id = " + worldId +
  190. " AND region_id IN " +
  191. "(SELECT id FROM " +
  192. config.getTablePrefix() + "region " +
  193. "WHERE world_id = " + worldId + ")"));
  194. ResultSet rs = closer.register(stmt.executeQuery());
  195. Table<String, String, Object> data = HashBasedTable.create();
  196. while (rs.next()) {
  197. data.put(
  198. rs.getString("region_id"),
  199. rs.getString("flag"),
  200. unmarshalFlagValue(rs.getString("value")));
  201. }
  202. for (Entry<String, Map<String, Object>> entry : data.rowMap().entrySet()) {
  203. ProtectedRegion region = loaded.get(entry.getKey());
  204. region.setFlags(flagRegistry.unmarshal(entry.getValue(), true));
  205. }
  206. } finally {
  207. closer.closeQuietly();
  208. }
  209. }
  210. private void loadDomainUsers() throws SQLException {
  211. Closer closer = Closer.create();
  212. try {
  213. PreparedStatement stmt = closer.register(conn.prepareStatement(
  214. "SELECT p.region_id, u.name, u.uuid, p.owner " +
  215. "FROM " + config.getTablePrefix() + "region_players AS p " +
  216. "LEFT JOIN " + config.getTablePrefix() + "user AS u " +
  217. " ON (p.user_id = u.id) " +
  218. "WHERE p.world_id = " + worldId));
  219. ResultSet rs = closer.register(stmt.executeQuery());
  220. while (rs.next()) {
  221. ProtectedRegion region = loaded.get(rs.getString("region_id"));
  222. if (region != null) {
  223. DefaultDomain domain;
  224. if (rs.getBoolean("owner")) {
  225. domain = region.getOwners();
  226. } else {
  227. domain = region.getMembers();
  228. }
  229. String name = rs.getString("name");
  230. String uuid = rs.getString("uuid");
  231. if (name != null) {
  232. //noinspection deprecation
  233. domain.addPlayer(name);
  234. } else if (uuid != null) {
  235. try {
  236. domain.addPlayer(UUID.fromString(uuid));
  237. } catch (IllegalArgumentException e) {
  238. log.warning("Invalid UUID '" + uuid + "' for region '" + region.getId() + "'");
  239. }
  240. }
  241. }
  242. }
  243. } finally {
  244. closer.closeQuietly();
  245. }
  246. }
  247. private void loadDomainGroups() throws SQLException {
  248. Closer closer = Closer.create();
  249. try {
  250. PreparedStatement stmt = closer.register(conn.prepareStatement(
  251. "SELECT rg.region_id, g.name, rg.owner " +
  252. "FROM `" + config.getTablePrefix() + "region_groups` AS rg " +
  253. "INNER JOIN `" + config.getTablePrefix() + "group` AS g ON (rg.group_id = g.id) " +
  254. // LEFT JOIN is returning NULLS for reasons unknown
  255. "AND rg.world_id = " + this.worldId));
  256. ResultSet rs = closer.register(stmt.executeQuery());
  257. while (rs.next()) {
  258. ProtectedRegion region = loaded.get(rs.getString("region_id"));
  259. if (region != null) {
  260. DefaultDomain domain;
  261. if (rs.getBoolean("owner")) {
  262. domain = region.getOwners();
  263. } else {
  264. domain = region.getMembers();
  265. }
  266. domain.addGroup(rs.getString("name"));
  267. }
  268. }
  269. } finally {
  270. closer.closeQuietly();
  271. }
  272. }
  273. private Object unmarshalFlagValue(String rawValue) {
  274. try {
  275. return yaml.load(rawValue);
  276. } catch (YAMLException e) {
  277. return String.valueOf(rawValue);
  278. }
  279. }
  280. }