mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2024-12-24 01:58:18 +01:00
Added MySQL region storage method.
Also added ProtectionDatabaseException, and made use of it across the project Closes #180
This commit is contained in:
parent
2351ade6fe
commit
f45464b0d9
184
region_storage.sql
Executable file
184
region_storage.sql
Executable file
@ -0,0 +1,184 @@
|
|||||||
|
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
||||||
|
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
||||||
|
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `user`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `user` (
|
||||||
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
|
||||||
|
`name` VARCHAR(64) NOT NULL UNIQUE,
|
||||||
|
PRIMARY KEY (`id`))
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `group`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `group` (
|
||||||
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
|
||||||
|
`name` VARCHAR(64) NOT NULL UNIQUE,
|
||||||
|
PRIMARY KEY (`id`))
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `world`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `world` (
|
||||||
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
|
||||||
|
`name` VARCHAR(128) NOT NULL UNIQUE,
|
||||||
|
PRIMARY KEY (`id`))
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `region`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `region` (
|
||||||
|
`id` VARCHAR(128) NOT NULL ,
|
||||||
|
`world_id` INT UNSIGNED NOT NULL ,
|
||||||
|
`type` ENUM('cuboid','poly2d','global') NOT NULL ,
|
||||||
|
`priority` SMALLINT NOT NULL DEFAULT 0 ,
|
||||||
|
`parent` VARCHAR(128) NULL ,
|
||||||
|
PRIMARY KEY (`id`, `world_id`) ,
|
||||||
|
INDEX `parent` (`parent` ASC) ,
|
||||||
|
INDEX `fk_region_world` (`world_id` ASC) ,
|
||||||
|
CONSTRAINT `parent`
|
||||||
|
FOREIGN KEY (`parent` )
|
||||||
|
REFERENCES `region` (`id` )
|
||||||
|
ON DELETE SET NULL
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT `fk_region_world1`
|
||||||
|
FOREIGN KEY (`world_id` )
|
||||||
|
REFERENCES `world` (`id` )
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE)
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `region_flag`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `region_flag` (
|
||||||
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
|
||||||
|
`region_id` VARCHAR(128) NOT NULL ,
|
||||||
|
`flag` VARCHAR(64) NOT NULL ,
|
||||||
|
`value` VARCHAR(256) NOT NULL ,
|
||||||
|
INDEX `fk_flags_region` (`region_id` ASC) ,
|
||||||
|
PRIMARY KEY (`id`) ,
|
||||||
|
CONSTRAINT `fk_flags_region1`
|
||||||
|
FOREIGN KEY (`region_id` )
|
||||||
|
REFERENCES `region` (`id` )
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE)
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `region_cuboid`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `region_cuboid` (
|
||||||
|
`region_id` VARCHAR(128) NOT NULL ,
|
||||||
|
`min_z` BIGINT NOT NULL ,
|
||||||
|
`min_y` BIGINT NOT NULL ,
|
||||||
|
`min_x` BIGINT NOT NULL ,
|
||||||
|
`max_z` BIGINT NOT NULL ,
|
||||||
|
`max_y` BIGINT NOT NULL ,
|
||||||
|
`max_x` BIGINT NOT NULL ,
|
||||||
|
PRIMARY KEY (`region_id`) ,
|
||||||
|
INDEX `fk_region_cuboid_region` (`region_id` ASC) ,
|
||||||
|
CONSTRAINT `fk_region_cuboid_region`
|
||||||
|
FOREIGN KEY (`region_id` )
|
||||||
|
REFERENCES `region` (`id` )
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE)
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `region_poly2d`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `region_poly2d` (
|
||||||
|
`region_id` VARCHAR(128) NOT NULL ,
|
||||||
|
`max_y` INT NOT NULL ,
|
||||||
|
`min_y` INT NOT NULL ,
|
||||||
|
PRIMARY KEY (`region_id`) ,
|
||||||
|
INDEX `fk_region_poly2d_region` (`region_id` ASC) ,
|
||||||
|
CONSTRAINT `fk_region_poly2d_region`
|
||||||
|
FOREIGN KEY (`region_id` )
|
||||||
|
REFERENCES `region` (`id` )
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE)
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `region_players`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `region_players` (
|
||||||
|
`region_id` VARCHAR(128) NOT NULL ,
|
||||||
|
`user_id` INT UNSIGNED NOT NULL ,
|
||||||
|
`owner` TINYINT(1) NOT NULL ,
|
||||||
|
PRIMARY KEY (`region_id`, `user_id`) ,
|
||||||
|
INDEX `fk_region_players_region` (`region_id` ASC) ,
|
||||||
|
INDEX `fk_region_players_user` (`user_id` ASC) ,
|
||||||
|
CONSTRAINT `fk_region_players_region`
|
||||||
|
FOREIGN KEY (`region_id` )
|
||||||
|
REFERENCES `region` (`id` )
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT `fk_region_players_user`
|
||||||
|
FOREIGN KEY (`user_id` )
|
||||||
|
REFERENCES `user` (`id` )
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE)
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `region_groups`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `region_groups` (
|
||||||
|
`region_id` VARCHAR(128) NOT NULL ,
|
||||||
|
`group_id` INT UNSIGNED NOT NULL ,
|
||||||
|
`owner` TINYINT(1) NOT NULL ,
|
||||||
|
PRIMARY KEY (`region_id`, `group_id`) ,
|
||||||
|
INDEX `fk_region_groups_region` (`region_id` ASC) ,
|
||||||
|
INDEX `fk_region_groups_group` (`group_id` ASC) ,
|
||||||
|
CONSTRAINT `fk_region_groups_region`
|
||||||
|
FOREIGN KEY (`region_id` )
|
||||||
|
REFERENCES `region` (`id` )
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT `fk_region_groups_group`
|
||||||
|
FOREIGN KEY (`group_id` )
|
||||||
|
REFERENCES `group` (`id` )
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE)
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `region_poly2d_point`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `region_poly2d_point` (
|
||||||
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT ,
|
||||||
|
`region_id` VARCHAR(128) NOT NULL ,
|
||||||
|
`z` BIGINT NOT NULL ,
|
||||||
|
`x` BIGINT NOT NULL ,
|
||||||
|
PRIMARY KEY (`id`) ,
|
||||||
|
INDEX `fk_region_poly2d_point_region_poly2d` (`region_id` ASC) ,
|
||||||
|
CONSTRAINT `fk_region_poly2d_point_region_poly2d`
|
||||||
|
FOREIGN KEY (`region_id` )
|
||||||
|
REFERENCES `region_poly2d` (`region_id` )
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE)
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SET SQL_MODE=@OLD_SQL_MODE;
|
||||||
|
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||||
|
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
@ -99,6 +99,14 @@ public class ConfigurationManager {
|
|||||||
public boolean autoGodMode;
|
public boolean autoGodMode;
|
||||||
public boolean usePlayerMove;
|
public boolean usePlayerMove;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Region Storage Configuration method, and config values
|
||||||
|
*/
|
||||||
|
public boolean useSqlDatabase = false;
|
||||||
|
public String sqlDsn;
|
||||||
|
public String sqlUsername;
|
||||||
|
public String sqlPassword;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct the object.
|
* Construct the object.
|
||||||
*
|
*
|
||||||
@ -134,6 +142,13 @@ public void load() {
|
|||||||
usePlayerMove = config.getBoolean(
|
usePlayerMove = config.getBoolean(
|
||||||
"use-player-move-event", true);
|
"use-player-move-event", true);
|
||||||
|
|
||||||
|
useSqlDatabase = config.getBoolean(
|
||||||
|
"regions.sql.use", false);
|
||||||
|
|
||||||
|
sqlDsn = config.getString("regions.sql.dsn", "jdbc:mysql://localhost/worldguard");
|
||||||
|
sqlUsername = config.getString("regions.sql.username", "worldguard");
|
||||||
|
sqlPassword = config.getString("regions.sql.password", "worldguard");
|
||||||
|
|
||||||
// Load configurations for each world
|
// Load configurations for each world
|
||||||
for (World world : plugin.getServer().getWorlds()) {
|
for (World world : plugin.getServer().getWorlds()) {
|
||||||
get(world);
|
get(world);
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||||
import com.sk89q.worldguard.protection.databases.CSVDatabase;
|
import com.sk89q.worldguard.protection.databases.CSVDatabase;
|
||||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||||
|
|
||||||
@ -105,8 +106,7 @@ public static void migrateRegions(WorldGuardPlugin plugin) {
|
|||||||
oldDatabase.renameTo(new File(plugin.getDataFolder(), "regions.txt.old"));
|
oldDatabase.renameTo(new File(plugin.getDataFolder(), "regions.txt.old"));
|
||||||
|
|
||||||
logger.info("WorldGuard: Regions database converted!");
|
logger.info("WorldGuard: Regions database converted!");
|
||||||
} catch (FileNotFoundException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
} catch (IOException e) {
|
|
||||||
logger.warning("WorldGuard: Failed to load regions: "
|
logger.warning("WorldGuard: Failed to load regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
|
104
src/main/java/com/sk89q/worldguard/bukkit/commands/RegionCommands.java
Executable file → Normal file
104
src/main/java/com/sk89q/worldguard/bukkit/commands/RegionCommands.java
Executable file → Normal file
@ -19,8 +19,9 @@
|
|||||||
|
|
||||||
package com.sk89q.worldguard.bukkit.commands;
|
package com.sk89q.worldguard.bukkit.commands;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@ -53,11 +54,18 @@
|
|||||||
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
|
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||||
|
import com.sk89q.worldguard.protection.databases.migrators.AbstractDatabaseMigrator;
|
||||||
|
import com.sk89q.worldguard.protection.databases.migrators.MigrationException;
|
||||||
|
import com.sk89q.worldguard.protection.databases.migrators.MigratorKey;
|
||||||
import com.sk89q.worldguard.util.RegionUtil;
|
import com.sk89q.worldguard.util.RegionUtil;
|
||||||
|
|
||||||
public class RegionCommands {
|
public class RegionCommands {
|
||||||
private final WorldGuardPlugin plugin;
|
private final WorldGuardPlugin plugin;
|
||||||
|
|
||||||
|
private MigratorKey migrateDBRequest;
|
||||||
|
private Date migrateDBRequestDate;
|
||||||
|
|
||||||
public RegionCommands(WorldGuardPlugin plugin) {
|
public RegionCommands(WorldGuardPlugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
@ -118,8 +126,8 @@ public void define(CommandContext args, CommandSender sender) throws CommandExce
|
|||||||
try {
|
try {
|
||||||
mgr.save();
|
mgr.save();
|
||||||
sender.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
|
sender.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,8 +200,8 @@ public void redefine(CommandContext args, CommandSender sender) throws CommandEx
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mgr.save();
|
mgr.save();
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -323,8 +331,8 @@ public void claim(CommandContext args, CommandSender sender) throws CommandExcep
|
|||||||
try {
|
try {
|
||||||
mgr.save();
|
mgr.save();
|
||||||
sender.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
|
sender.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -681,8 +689,8 @@ public void flag(CommandContext args, CommandSender sender) throws CommandExcept
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mgr.save();
|
mgr.save();
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -730,8 +738,8 @@ public void setPriority(CommandContext args, CommandSender sender) throws Comman
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mgr.save();
|
mgr.save();
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -801,8 +809,8 @@ public void setParent(CommandContext args, CommandSender sender) throws CommandE
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mgr.save();
|
mgr.save();
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -839,8 +847,8 @@ public void remove(CommandContext args, CommandSender sender) throws CommandExce
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mgr.save();
|
mgr.save();
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -862,8 +870,8 @@ public void load(CommandContext args, CommandSender sender) throws CommandExcept
|
|||||||
mgr.load();
|
mgr.load();
|
||||||
sender.sendMessage(ChatColor.YELLOW
|
sender.sendMessage(ChatColor.YELLOW
|
||||||
+ "Regions for '" + world.getName() + "' load.");
|
+ "Regions for '" + world.getName() + "' load.");
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to read regions file: "
|
throw new CommandException("Failed to read regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -872,8 +880,8 @@ public void load(CommandContext args, CommandSender sender) throws CommandExcept
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mgr.load();
|
mgr.load();
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to read regions file: "
|
throw new CommandException("Failed to read regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -900,8 +908,8 @@ public void save(CommandContext args, CommandSender sender) throws CommandExcept
|
|||||||
mgr.save();
|
mgr.save();
|
||||||
sender.sendMessage(ChatColor.YELLOW
|
sender.sendMessage(ChatColor.YELLOW
|
||||||
+ "Regions for '" + world.getName() + "' saved.");
|
+ "Regions for '" + world.getName() + "' saved.");
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -910,8 +918,8 @@ public void save(CommandContext args, CommandSender sender) throws CommandExcept
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mgr.save();
|
mgr.save();
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -920,4 +928,54 @@ public void save(CommandContext args, CommandSender sender) throws CommandExcept
|
|||||||
+ "Region databases saved.");
|
+ "Region databases saved.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Command(aliases = {"migratedb"}, usage = "<from> <to>",
|
||||||
|
desc = "Migrate from one Protection Database to another.", min = 1)
|
||||||
|
@CommandPermissions({"worldguard.region.migratedb"})
|
||||||
|
public void migratedb(CommandContext args, CommandSender sender) throws CommandException {
|
||||||
|
String from = args.getString(0).toLowerCase().trim();
|
||||||
|
String to = args.getString(1).toLowerCase().trim();
|
||||||
|
|
||||||
|
if (from.equals(to)) {
|
||||||
|
throw new CommandException("Will not migrate with common source and target.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<MigratorKey, Class<? extends AbstractDatabaseMigrator>> migrators = AbstractDatabaseMigrator.getMigrators();
|
||||||
|
MigratorKey key = new MigratorKey(from,to);
|
||||||
|
|
||||||
|
if (!migrators.containsKey(key)) {
|
||||||
|
throw new CommandException("No migrator found for that combination and direction.");
|
||||||
|
}
|
||||||
|
|
||||||
|
long lastRequest = 10000000;
|
||||||
|
if (this.migrateDBRequestDate != null) {
|
||||||
|
lastRequest = new Date().getTime() - this.migrateDBRequestDate.getTime();
|
||||||
|
}
|
||||||
|
if (this.migrateDBRequest == null || lastRequest > 60000) {
|
||||||
|
this.migrateDBRequest = key;
|
||||||
|
this.migrateDBRequestDate = new Date();
|
||||||
|
|
||||||
|
throw new CommandException("This command is potentially dangerous.\n" +
|
||||||
|
"Please ensure you have made a backup of your data, and then re-enter the command exactly to procede.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<? extends AbstractDatabaseMigrator> cls = migrators.get(key);
|
||||||
|
|
||||||
|
try {
|
||||||
|
AbstractDatabaseMigrator migrator = cls.getConstructor(WorldGuardPlugin.class).newInstance(plugin);
|
||||||
|
|
||||||
|
migrator.migrate();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
} catch (MigrationException e) {
|
||||||
|
throw new CommandException("Error migrating database: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(ChatColor.YELLOW + "Regions have been migrated successfuly.\n" +
|
||||||
|
"If you wish to use the destination format as your new backend, please update your config and reload WorldGuard.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
package com.sk89q.worldguard.bukkit.commands;
|
package com.sk89q.worldguard.bukkit.commands;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -35,6 +33,7 @@
|
|||||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||||
import com.sk89q.worldguard.util.RegionUtil;
|
import com.sk89q.worldguard.util.RegionUtil;
|
||||||
|
|
||||||
// @TODO: A lot of code duplication here! Need to fix.
|
// @TODO: A lot of code duplication here! Need to fix.
|
||||||
@ -78,8 +77,8 @@ public void addMember(CommandContext args, CommandSender sender) throws CommandE
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mgr.save();
|
mgr.save();
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,8 +128,8 @@ public void addOwner(CommandContext args, CommandSender sender) throws CommandEx
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mgr.save();
|
mgr.save();
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,8 +166,8 @@ public void removeMember(CommandContext args, CommandSender sender) throws Comma
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mgr.save();
|
mgr.save();
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,8 +205,8 @@ public void removeOwner(CommandContext args,
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mgr.save();
|
mgr.save();
|
||||||
} catch (IOException e) {
|
} catch (ProtectionDatabaseException e) {
|
||||||
throw new CommandException("Failed to write regions file: "
|
throw new CommandException("Failed to write regions: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
|
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -36,7 +34,10 @@
|
|||||||
import com.sk89q.worldguard.bukkit.ConfigurationManager;
|
import com.sk89q.worldguard.bukkit.ConfigurationManager;
|
||||||
import com.sk89q.worldguard.bukkit.WorldConfiguration;
|
import com.sk89q.worldguard.bukkit.WorldConfiguration;
|
||||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||||
import com.sk89q.worldguard.protection.databases.YAMLDatabase;
|
import com.sk89q.worldguard.protection.databases.YAMLDatabase;
|
||||||
|
import com.sk89q.worldguard.protection.databases.MySQLDatabase;
|
||||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||||
import com.sk89q.worldguard.protection.managers.FlatRegionManager;
|
import com.sk89q.worldguard.protection.managers.FlatRegionManager;
|
||||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||||
@ -134,30 +135,44 @@ public void unloadAll() {
|
|||||||
*/
|
*/
|
||||||
public RegionManager load(World world) {
|
public RegionManager load(World world) {
|
||||||
String name = world.getName();
|
String name = world.getName();
|
||||||
File file = getPath(name);
|
ProtectionDatabase database = null;
|
||||||
|
File file = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (!config.useSqlDatabase) {
|
||||||
|
file = getPath(name);
|
||||||
|
database = new YAMLDatabase(file);
|
||||||
|
|
||||||
|
// Store the last modification date so we can track changes
|
||||||
|
lastModified.put(name, file.lastModified());
|
||||||
|
} else {
|
||||||
|
database = new MySQLDatabase(config, name);
|
||||||
|
}
|
||||||
|
|
||||||
// Create a manager
|
// Create a manager
|
||||||
RegionManager manager = new FlatRegionManager(new YAMLDatabase(file));
|
RegionManager manager = new FlatRegionManager(database);
|
||||||
|
|
||||||
managers.put(name, manager);
|
managers.put(name, manager);
|
||||||
manager.load();
|
manager.load();
|
||||||
|
|
||||||
logger.info("WorldGuard: " + manager.getRegions().size()
|
logger.info("WorldGuard: " + manager.getRegions().size()
|
||||||
+ " regions loaded for '" + name + "'");
|
+ " regions loaded for '" + name + "'");
|
||||||
|
|
||||||
// Store the last modification date so we can track changes
|
|
||||||
lastModified.put(name, file.lastModified());
|
|
||||||
|
|
||||||
return manager;
|
return manager;
|
||||||
} catch (FileNotFoundException e) { // this should no longer happen hopefully
|
} catch (ProtectionDatabaseException e) {
|
||||||
logger.info("WorldGuard: Region file for world \""
|
String logStr = "WorldGuard: Failed to load regions from ";
|
||||||
+ name + "\" missing or inaccessible.");
|
if (config.useSqlDatabase) {
|
||||||
} catch (IOException e) {
|
logStr += "SQL Database <" + config.sqlDsn + "> ";
|
||||||
logger.info("WorldGuard: Failed to load regions from file "
|
} else {
|
||||||
+ file.getAbsolutePath() + " : " + e.getMessage());
|
logStr += "file \"" + file + "\" ";
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(logStr + " : " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.info("WorldGuard: Error loading regions for world \""
|
logger.info("WorldGuard: Error loading regions for world \""
|
||||||
+ name + "\":" + e.getMessage());
|
+ name + "\": " + e.toString() + "\n\t" + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO: THIS CREATES PROBLEMS!!one!!1!!eleven!!1!!!
|
// @TODO: THIS CREATES PROBLEMS!!one!!1!!eleven!!1!!!
|
||||||
@ -179,6 +194,8 @@ public void preload() {
|
|||||||
* have changed.
|
* have changed.
|
||||||
*/
|
*/
|
||||||
public void reloadChanged() {
|
public void reloadChanged() {
|
||||||
|
if (config.useSqlDatabase) return;
|
||||||
|
|
||||||
for (String name : managers.keySet()) {
|
for (String name : managers.keySet()) {
|
||||||
File file = getPath(name);
|
File file = getPath(name);
|
||||||
|
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
package com.sk89q.worldguard.protection.databases;
|
package com.sk89q.worldguard.protection.databases;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||||
|
|
||||||
public abstract class AbstractProtectionDatabase implements ProtectionDatabase {
|
public abstract class AbstractProtectionDatabase implements ProtectionDatabase {
|
||||||
@ -28,9 +26,9 @@ public abstract class AbstractProtectionDatabase implements ProtectionDatabase {
|
|||||||
/**
|
/**
|
||||||
* Load the list of regions into a region manager.
|
* Load the list of regions into a region manager.
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws ProtectionDatabaseException
|
||||||
*/
|
*/
|
||||||
public void load(RegionManager manager) throws IOException {
|
public void load(RegionManager manager) throws ProtectionDatabaseException {
|
||||||
load();
|
load();
|
||||||
manager.setRegions(getRegions());
|
manager.setRegions(getRegions());
|
||||||
}
|
}
|
||||||
@ -38,9 +36,9 @@ public void load(RegionManager manager) throws IOException {
|
|||||||
/**
|
/**
|
||||||
* Save the list of regions from a region manager.
|
* Save the list of regions from a region manager.
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws ProtectionDatabaseException
|
||||||
*/
|
*/
|
||||||
public void save(RegionManager manager) throws IOException {
|
public void save(RegionManager manager) throws ProtectionDatabaseException {
|
||||||
setRegions(manager.getRegions());
|
setRegions(manager.getRegions());
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
@ -72,22 +72,23 @@ public CSVDatabase(File file) {
|
|||||||
/**
|
/**
|
||||||
* Saves the database.
|
* Saves the database.
|
||||||
*/
|
*/
|
||||||
public void save() throws IOException {
|
public void save() throws ProtectionDatabaseException {
|
||||||
throw new UnsupportedOperationException("CSV format is no longer implemented");
|
throw new UnsupportedOperationException("CSV format is no longer implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the database from file.
|
* Load the database from file.
|
||||||
*/
|
*/
|
||||||
public void load() throws IOException {
|
public void load() throws ProtectionDatabaseException {
|
||||||
Map<String,ProtectedRegion> regions =
|
Map<String,ProtectedRegion> regions =
|
||||||
new HashMap<String,ProtectedRegion>();
|
new HashMap<String,ProtectedRegion>();
|
||||||
Map<ProtectedRegion,String> parentSets =
|
Map<ProtectedRegion,String> parentSets =
|
||||||
new LinkedHashMap<ProtectedRegion, String>();
|
new LinkedHashMap<ProtectedRegion, String>();
|
||||||
|
|
||||||
CSVReader reader = new CSVReader(new FileReader(file));
|
CSVReader reader = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
reader = new CSVReader(new FileReader(file));
|
||||||
|
|
||||||
String[] line;
|
String[] line;
|
||||||
|
|
||||||
while ((line = reader.readNext()) != null) {
|
while ((line = reader.readNext()) != null) {
|
||||||
@ -162,6 +163,8 @@ public void load() throws IOException {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ProtectionDatabaseException(e);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
reader.close();
|
reader.close();
|
||||||
|
966
src/main/java/com/sk89q/worldguard/protection/databases/MySQLDatabase.java
Executable file
966
src/main/java/com/sk89q/worldguard/protection/databases/MySQLDatabase.java
Executable file
@ -0,0 +1,966 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* MySQL WordGuard Region Database
|
||||||
|
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldguard.protection.databases;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
|
import com.sk89q.worldedit.BlockVector2D;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldguard.bukkit.ConfigurationManager;
|
||||||
|
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||||
|
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||||
|
import com.sk89q.worldguard.protection.flags.Flag;
|
||||||
|
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||||
|
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||||
|
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
|
||||||
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||||
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
|
||||||
|
|
||||||
|
public class MySQLDatabase extends AbstractProtectionDatabase {
|
||||||
|
|
||||||
|
private static Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||||
|
|
||||||
|
private Map<String, ProtectedRegion> regions;
|
||||||
|
|
||||||
|
private Map<String, ProtectedRegion> cuboidRegions;
|
||||||
|
private Map<String, ProtectedRegion> poly2dRegions;
|
||||||
|
private Map<String, ProtectedRegion> globalRegions;
|
||||||
|
private Map<ProtectedRegion, String> parentSets;
|
||||||
|
|
||||||
|
private ConfigurationManager config;
|
||||||
|
|
||||||
|
private Connection conn;
|
||||||
|
private String world;
|
||||||
|
private int worldDbId = -1; // The database will never have an id of -1;
|
||||||
|
|
||||||
|
public MySQLDatabase(ConfigurationManager config, String world) throws ProtectionDatabaseException {
|
||||||
|
this.config = config;
|
||||||
|
this.world = world;
|
||||||
|
|
||||||
|
try {
|
||||||
|
connect();
|
||||||
|
|
||||||
|
PreparedStatement worldStmt = conn.prepareStatement(
|
||||||
|
"SELECT `id` FROM " +
|
||||||
|
"`world` " +
|
||||||
|
"WHERE `name` = ? LIMIT 0,1"
|
||||||
|
);
|
||||||
|
|
||||||
|
worldStmt.setString(1, this.world);
|
||||||
|
ResultSet worldResult = worldStmt.executeQuery();
|
||||||
|
|
||||||
|
if (worldResult.first()) {
|
||||||
|
this.worldDbId = worldResult.getInt("id");
|
||||||
|
} else {
|
||||||
|
PreparedStatement insertWorldStatement = this.conn.prepareStatement(
|
||||||
|
"INSERT INTO " +
|
||||||
|
"`world` " +
|
||||||
|
"(`id`, `name`) VALUES (null, ?)",
|
||||||
|
Statement.RETURN_GENERATED_KEYS
|
||||||
|
);
|
||||||
|
|
||||||
|
insertWorldStatement.setString(1, world);
|
||||||
|
insertWorldStatement.execute();
|
||||||
|
ResultSet generatedKeys = insertWorldStatement.getGeneratedKeys();
|
||||||
|
if (generatedKeys.first()) {
|
||||||
|
this.worldDbId = generatedKeys.getInt(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.SEVERE, ex.getMessage(), ex);
|
||||||
|
// We havn't connected to the databases, or there was an error
|
||||||
|
// initialising the world record, so there is no point continuing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.worldDbId <= 0) {
|
||||||
|
logger.log(Level.SEVERE, "Could not find or create the world");
|
||||||
|
// There was an error initialising the world record, so there is
|
||||||
|
// no point continuing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void connect() throws SQLException {
|
||||||
|
if (conn == null || conn.isClosed()) {
|
||||||
|
conn = DriverManager.getConnection(config.sqlDsn, config.sqlUsername, config.sqlPassword);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadFlags(ProtectedRegion region) {
|
||||||
|
// @TODO: Iterate _ONCE_
|
||||||
|
try {
|
||||||
|
PreparedStatement flagsStatement = this.conn.prepareStatement(
|
||||||
|
"SELECT " +
|
||||||
|
"`region_flag`.`flag`, " +
|
||||||
|
"`region_flag`.`value` " +
|
||||||
|
"FROM `region_flag` " +
|
||||||
|
"WHERE `region_flag`.`region_id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
flagsStatement.setString(1, region.getId().toLowerCase());
|
||||||
|
ResultSet flagsResultSet = flagsStatement.executeQuery();
|
||||||
|
|
||||||
|
Map<String,Object> regionFlags = new HashMap<String,Object>();
|
||||||
|
while (flagsResultSet.next()) {
|
||||||
|
regionFlags.put(
|
||||||
|
flagsResultSet.getString("flag"),
|
||||||
|
flagsResultSet.getObject("value")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @TODO: Make this better
|
||||||
|
for (Flag<?> flag : DefaultFlag.getFlags()) {
|
||||||
|
Object o = regionFlags.get(flag.getName());
|
||||||
|
if (o != null) {
|
||||||
|
setFlag(region, flag, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.warning(
|
||||||
|
"Unable to load flags for region "
|
||||||
|
+ region.getId().toLowerCase() + ": " + ex.getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void setFlag(ProtectedRegion region, Flag<T> flag, Object rawValue) {
|
||||||
|
T val = flag.unmarshal(rawValue);
|
||||||
|
if (val == null) {
|
||||||
|
logger.warning("Failed to parse flag '" + flag.getName()
|
||||||
|
+ "' with value '" + rawValue.toString() + "'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
region.setFlag(flag, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadOwnersAndMembers(ProtectedRegion region) {
|
||||||
|
DefaultDomain owners = new DefaultDomain();
|
||||||
|
DefaultDomain members = new DefaultDomain();
|
||||||
|
|
||||||
|
try {
|
||||||
|
PreparedStatement usersStatement = this.conn.prepareStatement(
|
||||||
|
"SELECT " +
|
||||||
|
"`user`.`name`, " +
|
||||||
|
"`region_players`.`owner` " +
|
||||||
|
"FROM `region_players` " +
|
||||||
|
"LEFT JOIN `user` ON ( " +
|
||||||
|
"`region_players`.`user_id` = " +
|
||||||
|
"`user`.`id`) " +
|
||||||
|
"WHERE `region_players`.`region_id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
usersStatement.setString(1, region.getId().toLowerCase());
|
||||||
|
ResultSet userSet = usersStatement.executeQuery();
|
||||||
|
while(userSet.next()) {
|
||||||
|
if (userSet.getBoolean("owner")) {
|
||||||
|
owners.addPlayer(userSet.getString("name"));
|
||||||
|
} else {
|
||||||
|
members.addPlayer(userSet.getString("name"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.warning("Unable to load users for region " + region.getId().toLowerCase() + ": " + ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
PreparedStatement groupsStatement = this.conn.prepareStatement(
|
||||||
|
"SELECT " +
|
||||||
|
"`group`.`name`, " +
|
||||||
|
"`region_groups`.`owner` " +
|
||||||
|
"FROM `region_groups` " +
|
||||||
|
"LEFT JOIN `group` ON ( " +
|
||||||
|
"`region_groups`.`group_id` = " +
|
||||||
|
"`group`.`id`) " +
|
||||||
|
"WHERE `region_groups`.`region_id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
groupsStatement.setString(1, region.getId().toLowerCase());
|
||||||
|
ResultSet groupSet = groupsStatement.executeQuery();
|
||||||
|
while(groupSet.next()) {
|
||||||
|
if (groupSet.getBoolean("owner")) {
|
||||||
|
owners.addGroup(groupSet.getString("name"));
|
||||||
|
} else {
|
||||||
|
members.addGroup(groupSet.getString("name"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.warning("Unable to load groups for region " + region.getId().toLowerCase() + ": " + ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
region.setOwners(owners);
|
||||||
|
region.setMembers(members);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadGlobal() {
|
||||||
|
Map<String,ProtectedRegion> regions =
|
||||||
|
new HashMap<String,ProtectedRegion>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
PreparedStatement globalRegionStatement = this.conn.prepareStatement(
|
||||||
|
"SELECT " +
|
||||||
|
"`region`.`id`, " +
|
||||||
|
"`region`.`priority`, " +
|
||||||
|
"`parent`.`id` AS `parent` " +
|
||||||
|
"FROM `region` " +
|
||||||
|
"LEFT JOIN `region` AS `parent` " +
|
||||||
|
"ON (`region`.`parent` = `parent`.`id`) " +
|
||||||
|
"WHERE `region`.`type` = 'global' " +
|
||||||
|
"AND `region`.`world_id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
globalRegionStatement.setInt(1, this.worldDbId);
|
||||||
|
ResultSet globalResultSet = globalRegionStatement.executeQuery();
|
||||||
|
|
||||||
|
while (globalResultSet.next()) {
|
||||||
|
ProtectedRegion region = new GlobalProtectedRegion(globalResultSet.getString("id"));
|
||||||
|
|
||||||
|
region.setPriority(globalResultSet.getInt("priority"));
|
||||||
|
|
||||||
|
this.loadFlags(region);
|
||||||
|
this.loadOwnersAndMembers(region);
|
||||||
|
|
||||||
|
regions.put(globalResultSet.getString("id"), region);
|
||||||
|
|
||||||
|
String parentId = globalResultSet.getString("parent");
|
||||||
|
if (parentId != null) {
|
||||||
|
parentSets.put(region, parentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
logger.warning("Unable to load regions from sql database: " + ex.getMessage());
|
||||||
|
Throwable t = ex.getCause();
|
||||||
|
while (t != null) {
|
||||||
|
logger.warning("\t\tCause: " + t.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
globalRegions = regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadCuboid() {
|
||||||
|
Map<String,ProtectedRegion> regions =
|
||||||
|
new HashMap<String,ProtectedRegion>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
PreparedStatement cuboidRegionStatement = this.conn.prepareStatement(
|
||||||
|
"SELECT " +
|
||||||
|
"`region_cuboid`.`min_z`, " +
|
||||||
|
"`region_cuboid`.`min_y`, " +
|
||||||
|
"`region_cuboid`.`min_x`, " +
|
||||||
|
"`region_cuboid`.`max_z`, " +
|
||||||
|
"`region_cuboid`.`max_y`, " +
|
||||||
|
"`region_cuboid`.`max_x`, " +
|
||||||
|
"`region`.`id`, " +
|
||||||
|
"`region`.`priority`, " +
|
||||||
|
"`parent`.`id` AS `parent` " +
|
||||||
|
"FROM `region_cuboid` " +
|
||||||
|
"LEFT JOIN `region` " +
|
||||||
|
"ON (`region_cuboid`.`region_id` = `region`.`id`) " +
|
||||||
|
"LEFT JOIN `region` AS `parent` " +
|
||||||
|
"ON (`region`.`parent` = `parent`.`id`) " +
|
||||||
|
"WHERE `region`.`world_id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
cuboidRegionStatement.setInt(1, this.worldDbId);
|
||||||
|
ResultSet cuboidResultSet = cuboidRegionStatement.executeQuery();
|
||||||
|
|
||||||
|
while (cuboidResultSet.next()) {
|
||||||
|
Vector pt1 = new Vector(
|
||||||
|
cuboidResultSet.getInt("min_x"),
|
||||||
|
cuboidResultSet.getInt("min_y"),
|
||||||
|
cuboidResultSet.getInt("min_z")
|
||||||
|
);
|
||||||
|
Vector pt2 = new Vector(
|
||||||
|
cuboidResultSet.getInt("max_x"),
|
||||||
|
cuboidResultSet.getInt("max_y"),
|
||||||
|
cuboidResultSet.getInt("max_z")
|
||||||
|
);
|
||||||
|
|
||||||
|
BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector();
|
||||||
|
BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector();
|
||||||
|
ProtectedRegion region = new ProtectedCuboidRegion(
|
||||||
|
cuboidResultSet.getString("id"),
|
||||||
|
min,
|
||||||
|
max
|
||||||
|
);
|
||||||
|
|
||||||
|
region.setPriority(cuboidResultSet.getInt("priority"));
|
||||||
|
|
||||||
|
this.loadFlags(region);
|
||||||
|
this.loadOwnersAndMembers(region);
|
||||||
|
|
||||||
|
regions.put(cuboidResultSet.getString("id"), region);
|
||||||
|
|
||||||
|
String parentId = cuboidResultSet.getString("parent");
|
||||||
|
if (parentId != null) {
|
||||||
|
parentSets.put(region, parentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
logger.warning("Unable to load regions from sql database: " + ex.getMessage());
|
||||||
|
Throwable t = ex.getCause();
|
||||||
|
while (t != null) {
|
||||||
|
logger.warning("\t\tCause: " + t.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cuboidRegions = regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadPoly2d() {
|
||||||
|
Map<String,ProtectedRegion> regions =
|
||||||
|
new HashMap<String,ProtectedRegion>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
PreparedStatement poly2dRegionStatement = this.conn.prepareStatement(
|
||||||
|
"SELECT " +
|
||||||
|
"`region_poly2d`.`min_y`, " +
|
||||||
|
"`region_poly2d`.`max_y`, " +
|
||||||
|
"`region`.`id`, " +
|
||||||
|
"`region`.`priority`, " +
|
||||||
|
"`parent`.`id` AS `parent` " +
|
||||||
|
"FROM `region_poly2d` " +
|
||||||
|
"LEFT JOIN `region` " +
|
||||||
|
"ON (`region_poly2d`.`region_id` = `region`.`id`) " +
|
||||||
|
"LEFT JOIN `region` AS `parent` " +
|
||||||
|
"ON (`region`.`parent` = `parent`.`id`) " +
|
||||||
|
"WHERE `region`.`world_id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
poly2dRegionStatement.setInt(1, this.worldDbId);
|
||||||
|
ResultSet poly2dResultSet = poly2dRegionStatement.executeQuery();
|
||||||
|
|
||||||
|
PreparedStatement poly2dVectorStatement = this.conn.prepareStatement(
|
||||||
|
"SELECT " +
|
||||||
|
"`region_poly2d_point`.`x`, " +
|
||||||
|
"`region_poly2d_point`.`z` " +
|
||||||
|
"FROM `region_poly2d_point` " +
|
||||||
|
"WHERE `region_poly2d_point`.`region_id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
while (poly2dResultSet.next()) {
|
||||||
|
String id = poly2dResultSet.getString("id");
|
||||||
|
|
||||||
|
Integer minY = poly2dResultSet.getInt("min_y");
|
||||||
|
Integer maxY = poly2dResultSet.getInt("max_y");
|
||||||
|
List<BlockVector2D> points = new ArrayList<BlockVector2D>();
|
||||||
|
|
||||||
|
poly2dVectorStatement.setString(1, id);
|
||||||
|
ResultSet poly2dVectorResultSet = poly2dVectorStatement.executeQuery();
|
||||||
|
|
||||||
|
while(poly2dVectorResultSet.next()) {
|
||||||
|
points.add(new BlockVector2D(
|
||||||
|
poly2dVectorResultSet.getInt("x"),
|
||||||
|
poly2dVectorResultSet.getInt("z")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
ProtectedRegion region = new ProtectedPolygonalRegion(id, points, minY, maxY);
|
||||||
|
|
||||||
|
region.setPriority(poly2dResultSet.getInt("priority"));
|
||||||
|
|
||||||
|
this.loadFlags(region);
|
||||||
|
this.loadOwnersAndMembers(region);
|
||||||
|
|
||||||
|
regions.put(poly2dResultSet.getString("id"), region);
|
||||||
|
|
||||||
|
String parentId = poly2dResultSet.getString("parent");
|
||||||
|
if (parentId != null) {
|
||||||
|
parentSets.put(region, parentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
logger.warning("Unable to load regions from sql database: " + ex.getMessage());
|
||||||
|
Throwable t = ex.getCause();
|
||||||
|
while (t != null) {
|
||||||
|
logger.warning("\t\tCause: " + t.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
poly2dRegions = regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load() throws ProtectionDatabaseException {
|
||||||
|
try {
|
||||||
|
connect();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
throw new ProtectionDatabaseException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
parentSets = new HashMap<ProtectedRegion,String>();
|
||||||
|
|
||||||
|
// We load the cuboid regions first, as this is likely to be the
|
||||||
|
// largest dataset. This should save time in regards to the putAll()s
|
||||||
|
this.loadCuboid();
|
||||||
|
Map<String,ProtectedRegion> regions = this.cuboidRegions;
|
||||||
|
this.cuboidRegions = null;
|
||||||
|
|
||||||
|
this.loadPoly2d();
|
||||||
|
regions.putAll(this.poly2dRegions);
|
||||||
|
this.poly2dRegions = null;
|
||||||
|
|
||||||
|
this.loadGlobal();
|
||||||
|
regions.putAll(this.globalRegions);
|
||||||
|
this.globalRegions = null;
|
||||||
|
|
||||||
|
// Relink parents // Taken verbatim from YAMLDatabase
|
||||||
|
for (Map.Entry<ProtectedRegion, String> entry : parentSets.entrySet()) {
|
||||||
|
ProtectedRegion parent = regions.get(entry.getValue());
|
||||||
|
if (parent != null) {
|
||||||
|
try {
|
||||||
|
entry.getKey().setParent(parent);
|
||||||
|
} catch (CircularInheritanceException e) {
|
||||||
|
logger.warning("Circular inheritance detect with '"
|
||||||
|
+ entry.getValue() + "' detected as a parent");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.warning("Unknown region parent: " + entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.regions = regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the database id for the user
|
||||||
|
* If it doesn't exits it adds the user and returns the id.
|
||||||
|
*/
|
||||||
|
private Map<String,Integer> getUserIds(String... usernames) {
|
||||||
|
Map<String,Integer> users = new HashMap<String,Integer>();
|
||||||
|
|
||||||
|
if (usernames.length < 1) return users;
|
||||||
|
|
||||||
|
try {
|
||||||
|
PreparedStatement findUsersStatement = this.conn.prepareStatement(
|
||||||
|
String.format(
|
||||||
|
"SELECT " +
|
||||||
|
"`user`.`id`, " +
|
||||||
|
"`user`.`name` " +
|
||||||
|
"FROM `user` " +
|
||||||
|
"WHERE `name` IN (%s)",
|
||||||
|
RegionDBUtil.preparePlaceHolders(usernames.length)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
RegionDBUtil.setValues(findUsersStatement, usernames);
|
||||||
|
|
||||||
|
ResultSet findUsersResults = findUsersStatement.executeQuery();
|
||||||
|
|
||||||
|
while(findUsersResults.next()) {
|
||||||
|
users.put(findUsersResults.getString("name"), findUsersResults.getInt("id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
PreparedStatement insertUserStatement = this.conn.prepareStatement(
|
||||||
|
"INSERT INTO " +
|
||||||
|
"`user` ( " +
|
||||||
|
"`id`, " +
|
||||||
|
"`name`" +
|
||||||
|
") VALUES (null, ?)",
|
||||||
|
Statement.RETURN_GENERATED_KEYS
|
||||||
|
);
|
||||||
|
|
||||||
|
for(int i=0, len=usernames.length; i<len; i++) {
|
||||||
|
if (!users.containsKey(usernames[i])) {
|
||||||
|
insertUserStatement.setString(1, usernames[i]);
|
||||||
|
insertUserStatement.execute();
|
||||||
|
ResultSet generatedKeys = insertUserStatement.getGeneratedKeys();
|
||||||
|
if (generatedKeys.first()) {
|
||||||
|
users.put(usernames[i], generatedKeys.getInt(1));
|
||||||
|
} else {
|
||||||
|
logger.warning("Could not get the database id for user " + usernames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
logger.warning("Could not get the database id for the users " + usernames.toString() + "\n\t" + ex.getMessage());
|
||||||
|
Throwable t = ex.getCause();
|
||||||
|
while (t != null) {
|
||||||
|
logger.warning(t.getMessage());
|
||||||
|
t = t.getCause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the database id for the groups
|
||||||
|
* If it doesn't exits it adds the group and returns the id.
|
||||||
|
*/
|
||||||
|
private Map<String,Integer> getGroupIds(String... groupnames) {
|
||||||
|
Map<String,Integer> groups = new HashMap<String,Integer>();
|
||||||
|
|
||||||
|
if (groupnames.length < 1) return groups;
|
||||||
|
|
||||||
|
try {
|
||||||
|
PreparedStatement findGroupsStatement = this.conn.prepareStatement(
|
||||||
|
String.format(
|
||||||
|
"SELECT " +
|
||||||
|
"`group`.`id`, " +
|
||||||
|
"`group`.`name` " +
|
||||||
|
"FROM `group` " +
|
||||||
|
"WHERE `name` IN (%s)",
|
||||||
|
RegionDBUtil.preparePlaceHolders(groupnames.length)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
RegionDBUtil.setValues(findGroupsStatement, groupnames);
|
||||||
|
|
||||||
|
ResultSet findGroupsResults = findGroupsStatement.executeQuery();
|
||||||
|
|
||||||
|
while(findGroupsResults.next()) {
|
||||||
|
groups.put(findGroupsResults.getString("name"), findGroupsResults.getInt("id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
PreparedStatement insertGroupStatement = this.conn.prepareStatement(
|
||||||
|
"INSERT INTO " +
|
||||||
|
"`group` ( " +
|
||||||
|
"`id`, " +
|
||||||
|
"`name`" +
|
||||||
|
") VALUES (null, ?)",
|
||||||
|
Statement.RETURN_GENERATED_KEYS
|
||||||
|
);
|
||||||
|
|
||||||
|
for(int i=0, len=groupnames.length; i<len; i++) {
|
||||||
|
if (!groups.containsKey(groupnames[i])) {
|
||||||
|
insertGroupStatement.setString(1, groupnames[i]);
|
||||||
|
insertGroupStatement.execute();
|
||||||
|
ResultSet generatedKeys = insertGroupStatement.getGeneratedKeys();
|
||||||
|
if (generatedKeys.first()) {
|
||||||
|
groups.put(groupnames[i], generatedKeys.getInt(1));
|
||||||
|
} else {
|
||||||
|
logger.warning("Could not get the database id for user " + groupnames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.warning("Could not get the database id for the groups " + groupnames.toString() + ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As we don't get notified on the creation/removal of regions:
|
||||||
|
* 1) We get a list of all of the in-database regions
|
||||||
|
* 2) We iterate over all of the in-memory regions
|
||||||
|
* 2a) If the region is in the database, we update the database and
|
||||||
|
* remove the region from the in-database list
|
||||||
|
* b) If the region is not in the database, we insert it
|
||||||
|
* 3) We iterate over what remains of the in-database list and remove
|
||||||
|
* them from the database
|
||||||
|
*
|
||||||
|
* TODO: Look at adding/removing/updating the database when the in
|
||||||
|
* memory region is created/remove/updated
|
||||||
|
*
|
||||||
|
* @see com.sk89q.worldguard.protection.databases.ProtectionDatabase#save()
|
||||||
|
*/
|
||||||
|
public void save() throws ProtectionDatabaseException {
|
||||||
|
try {
|
||||||
|
connect();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
throw new ProtectionDatabaseException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> regionsInDatabase = new ArrayList<String>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
PreparedStatement getAllRegionsStatement = this.conn.prepareStatement(
|
||||||
|
"SELECT `region`.`id` FROM " +
|
||||||
|
"`region` " +
|
||||||
|
"WHERE `world_id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
getAllRegionsStatement.setInt(1, this.worldDbId);
|
||||||
|
ResultSet getAllRegionsResult = getAllRegionsStatement.executeQuery();
|
||||||
|
|
||||||
|
while(getAllRegionsResult.next()) {
|
||||||
|
regionsInDatabase.add(getAllRegionsResult.getString("id"));
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.warning("Could not get region list for save comparison: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
|
||||||
|
String name = entry.getKey();
|
||||||
|
ProtectedRegion region = entry.getValue();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (regionsInDatabase.contains(name)) {
|
||||||
|
regionsInDatabase.remove(name);
|
||||||
|
|
||||||
|
if (region instanceof ProtectedCuboidRegion) {
|
||||||
|
updateRegionCuboid( (ProtectedCuboidRegion) region );
|
||||||
|
} else if (region instanceof ProtectedPolygonalRegion) {
|
||||||
|
updateRegionPoly2D( (ProtectedPolygonalRegion) region );
|
||||||
|
} else if (region instanceof GlobalProtectedRegion) {
|
||||||
|
updateRegionGlobal( (GlobalProtectedRegion) region );
|
||||||
|
} else {
|
||||||
|
this.updateRegion(region, region.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (region instanceof ProtectedCuboidRegion) {
|
||||||
|
insertRegionCuboid( (ProtectedCuboidRegion) region );
|
||||||
|
} else if (region instanceof ProtectedPolygonalRegion) {
|
||||||
|
insertRegionPoly2D( (ProtectedPolygonalRegion) region );
|
||||||
|
} else if (region instanceof GlobalProtectedRegion) {
|
||||||
|
insertRegionGlobal( (GlobalProtectedRegion) region );
|
||||||
|
} else {
|
||||||
|
this.insertRegion(region, region.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.warning("Could not save region " + region.getId().toLowerCase() + ": " + ex.getMessage());
|
||||||
|
throw new ProtectionDatabaseException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
|
||||||
|
try {
|
||||||
|
if (entry.getValue().getParent() == null) continue;
|
||||||
|
|
||||||
|
PreparedStatement setParentStatement = this.conn.prepareStatement(
|
||||||
|
"UPDATE `region` SET " +
|
||||||
|
"`parent` = ? " +
|
||||||
|
"WHERE `id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
setParentStatement.setString(1, entry.getValue().getParent().getId().toLowerCase());
|
||||||
|
setParentStatement.setString(2, entry.getValue().getId().toLowerCase());
|
||||||
|
|
||||||
|
setParentStatement.execute();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.warning("Could not save region parents " + entry.getValue().getId().toLowerCase() + ": " + ex.getMessage());
|
||||||
|
throw new ProtectionDatabaseException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String name : regionsInDatabase) {
|
||||||
|
try {
|
||||||
|
PreparedStatement removeRegion = this.conn.prepareStatement(
|
||||||
|
"DELETE FROM `region` WHERE `id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
removeRegion.setString(1, name);
|
||||||
|
removeRegion.execute();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.warning("Could not remove region from database " + name + ": " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFlags(ProtectedRegion region) throws SQLException {
|
||||||
|
PreparedStatement clearCurrentFlagStatement = this.conn.prepareStatement(
|
||||||
|
"DELETE FROM `region_flag` " +
|
||||||
|
"WHERE `region_id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
clearCurrentFlagStatement.setString(1, region.getId().toLowerCase());
|
||||||
|
clearCurrentFlagStatement.execute();
|
||||||
|
|
||||||
|
for (Map.Entry<Flag<?>, Object> entry : region.getFlags().entrySet()) {
|
||||||
|
if (entry.getValue() == null) continue;
|
||||||
|
|
||||||
|
Object flag = marshalFlag(entry.getKey(), entry.getValue());
|
||||||
|
|
||||||
|
PreparedStatement insertFlagStatement = this.conn.prepareStatement(
|
||||||
|
"INSERT INTO `region_flag` ( " +
|
||||||
|
"`id`, " +
|
||||||
|
"`region_id`, " +
|
||||||
|
"`flag`, " +
|
||||||
|
"`value` " +
|
||||||
|
") VALUES (null, ?, ?, ?)"
|
||||||
|
);
|
||||||
|
|
||||||
|
insertFlagStatement.setString(1, region.getId().toLowerCase());
|
||||||
|
insertFlagStatement.setString(2, entry.getKey().getName());
|
||||||
|
insertFlagStatement.setObject(3, flag);
|
||||||
|
|
||||||
|
insertFlagStatement.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePlayerAndGroups(ProtectedRegion region, Boolean owners) throws SQLException {
|
||||||
|
DefaultDomain domain;
|
||||||
|
|
||||||
|
if (owners) {
|
||||||
|
domain = region.getOwners();
|
||||||
|
} else {
|
||||||
|
domain = region.getMembers();
|
||||||
|
}
|
||||||
|
|
||||||
|
PreparedStatement deleteUsersForRegion = this.conn.prepareStatement(
|
||||||
|
"DELETE FROM `region_players` " +
|
||||||
|
"WHERE `region_id` = ? " +
|
||||||
|
"AND `owner` = ?"
|
||||||
|
);
|
||||||
|
|
||||||
|
deleteUsersForRegion.setString(1, region.getId().toLowerCase());
|
||||||
|
deleteUsersForRegion.setBoolean(2, owners);
|
||||||
|
deleteUsersForRegion.execute();
|
||||||
|
|
||||||
|
PreparedStatement insertUsersForRegion = this.conn.prepareStatement(
|
||||||
|
"INSERT INTO `region_players` " +
|
||||||
|
"(`region_id`, `user_id`, `owner`) VALUES (?, ?, ?)"
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String,Integer> players = getUserIds(domain.getPlayers().toArray(new String[0]));
|
||||||
|
|
||||||
|
for (Integer player : players.values()) {
|
||||||
|
insertUsersForRegion.setString(1, region.getId().toLowerCase());
|
||||||
|
insertUsersForRegion.setInt(2, player);
|
||||||
|
insertUsersForRegion.setBoolean(3, owners);
|
||||||
|
|
||||||
|
insertUsersForRegion.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
PreparedStatement deleteGroupsForRegion = this.conn.prepareStatement(
|
||||||
|
"DELETE FROM `region_groups` " +
|
||||||
|
"WHERE `region_id` = ? " +
|
||||||
|
"AND `owner` = ?"
|
||||||
|
);
|
||||||
|
|
||||||
|
deleteGroupsForRegion.setString(1, region.getId().toLowerCase());
|
||||||
|
deleteGroupsForRegion.setBoolean(2, owners);
|
||||||
|
deleteGroupsForRegion.execute();
|
||||||
|
|
||||||
|
PreparedStatement insertGroupsForRegion = this.conn.prepareStatement(
|
||||||
|
"INSERT INTO `region_groups` " +
|
||||||
|
"(`region_id`, `group_id`, `owner`) VALUES (?, ?, ?)"
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String,Integer> groups = getGroupIds(domain.getGroups().toArray(new String[0]));
|
||||||
|
|
||||||
|
for (Integer group : groups.values()) {
|
||||||
|
insertGroupsForRegion.setString(1, region.getId().toLowerCase());
|
||||||
|
insertGroupsForRegion.setInt(2, group);
|
||||||
|
insertGroupsForRegion.setBoolean(3, owners);
|
||||||
|
|
||||||
|
insertGroupsForRegion.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <V> Object marshalFlag(Flag<V> flag, Object val) {
|
||||||
|
return flag.marshal( (V) val );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertRegion(ProtectedRegion region, String type) throws SQLException {
|
||||||
|
PreparedStatement insertRegionStatement = this.conn.prepareStatement(
|
||||||
|
"INSERT INTO `region` (" +
|
||||||
|
"`id`, " +
|
||||||
|
"`world_id`, " +
|
||||||
|
"`type`, " +
|
||||||
|
"`priority`, " +
|
||||||
|
"`parent` " +
|
||||||
|
") VALUES (?, " + this.worldDbId + ", ?, ?, null)"
|
||||||
|
);
|
||||||
|
|
||||||
|
insertRegionStatement.setString(1, region.getId().toLowerCase());
|
||||||
|
insertRegionStatement.setString(2, type);
|
||||||
|
insertRegionStatement.setInt(3, region.getPriority());
|
||||||
|
|
||||||
|
insertRegionStatement.execute();
|
||||||
|
|
||||||
|
updateFlags(region);
|
||||||
|
|
||||||
|
updatePlayerAndGroups(region, false);
|
||||||
|
updatePlayerAndGroups(region, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertRegionCuboid(ProtectedCuboidRegion region) throws SQLException {
|
||||||
|
insertRegion(region, "cuboid");
|
||||||
|
|
||||||
|
PreparedStatement insertCuboidRegionStatement = this.conn.prepareStatement(
|
||||||
|
"INSERT INTO `region_cuboid` (" +
|
||||||
|
"`region_id`, " +
|
||||||
|
"`min_z`, " +
|
||||||
|
"`min_y`, " +
|
||||||
|
"`min_x`, " +
|
||||||
|
"`max_z`, " +
|
||||||
|
"`max_y`, " +
|
||||||
|
"`max_x` " +
|
||||||
|
") VALUES (?, ?, ?, ?, ?, ?, ?)"
|
||||||
|
);
|
||||||
|
|
||||||
|
BlockVector min = region.getMinimumPoint();
|
||||||
|
BlockVector max = region.getMaximumPoint();
|
||||||
|
|
||||||
|
insertCuboidRegionStatement.setString(1, region.getId().toLowerCase());
|
||||||
|
insertCuboidRegionStatement.setInt(2, min.getBlockZ());
|
||||||
|
insertCuboidRegionStatement.setInt(3, min.getBlockY());
|
||||||
|
insertCuboidRegionStatement.setInt(4, min.getBlockX());
|
||||||
|
insertCuboidRegionStatement.setInt(5, max.getBlockZ());
|
||||||
|
insertCuboidRegionStatement.setInt(6, max.getBlockY());
|
||||||
|
insertCuboidRegionStatement.setInt(7, max.getBlockX());
|
||||||
|
|
||||||
|
insertCuboidRegionStatement.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertRegionPoly2D(ProtectedPolygonalRegion region) throws SQLException {
|
||||||
|
insertRegion(region, "poly2d");
|
||||||
|
|
||||||
|
PreparedStatement insertPoly2dRegionStatement = this.conn.prepareStatement(
|
||||||
|
"INSERT INTO `region_poly2d` (" +
|
||||||
|
"`region_id`, " +
|
||||||
|
"`max_y`, " +
|
||||||
|
"`min_y` " +
|
||||||
|
") VALUES (?, ?, ?)"
|
||||||
|
);
|
||||||
|
|
||||||
|
insertPoly2dRegionStatement.setString(1, region.getId().toLowerCase());
|
||||||
|
insertPoly2dRegionStatement.setInt(2, region.getMaximumPoint().getBlockY());
|
||||||
|
insertPoly2dRegionStatement.setInt(3, region.getMinimumPoint().getBlockY());
|
||||||
|
|
||||||
|
insertPoly2dRegionStatement.execute();
|
||||||
|
|
||||||
|
updatePoly2dPoints(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePoly2dPoints(ProtectedPolygonalRegion region) throws SQLException {
|
||||||
|
PreparedStatement clearPoly2dPointsForRegionStatement = this.conn.prepareStatement(
|
||||||
|
"DELETE FROM `region_poly2d_point` " +
|
||||||
|
"WHERE `region_id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
clearPoly2dPointsForRegionStatement.setString(1, region.getId().toLowerCase());
|
||||||
|
|
||||||
|
clearPoly2dPointsForRegionStatement.execute();
|
||||||
|
|
||||||
|
PreparedStatement insertPoly2dPointStatement = this.conn.prepareStatement(
|
||||||
|
"INSERT INTO `region_poly2d_point` (" +
|
||||||
|
"`id`, " +
|
||||||
|
"`region_id`, " +
|
||||||
|
"`z`, " +
|
||||||
|
"`x` " +
|
||||||
|
") VALUES (null, ?, ?, ?)"
|
||||||
|
);
|
||||||
|
|
||||||
|
for (BlockVector2D point : region.getPoints()) {
|
||||||
|
insertPoly2dPointStatement.setString(1, region.getId().toLowerCase());
|
||||||
|
insertPoly2dPointStatement.setInt(2, point.getBlockZ());
|
||||||
|
insertPoly2dPointStatement.setInt(3, point.getBlockX());
|
||||||
|
|
||||||
|
insertPoly2dPointStatement.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertRegionGlobal(GlobalProtectedRegion region) throws SQLException {
|
||||||
|
insertRegion(region, "global");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRegion(ProtectedRegion region, String type) throws SQLException {
|
||||||
|
PreparedStatement updateRegionStatement = this.conn.prepareStatement(
|
||||||
|
"UPDATE `region` SET " +
|
||||||
|
"`priority` = ? WHERE `id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
updateRegionStatement.setInt(1, region.getPriority());
|
||||||
|
updateRegionStatement.setString(2, region.getId().toLowerCase());
|
||||||
|
|
||||||
|
updateRegionStatement.execute();
|
||||||
|
|
||||||
|
updateFlags(region);
|
||||||
|
|
||||||
|
updatePlayerAndGroups(region, false);
|
||||||
|
updatePlayerAndGroups(region, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRegionCuboid(ProtectedCuboidRegion region) throws SQLException {
|
||||||
|
updateRegion(region, "cuboid");
|
||||||
|
|
||||||
|
PreparedStatement updateCuboidRegionStatement = this.conn.prepareStatement(
|
||||||
|
"UPDATE `region_cuboid` SET " +
|
||||||
|
"`min_z` = ?, " +
|
||||||
|
"`min_y` = ?, " +
|
||||||
|
"`min_x` = ?, " +
|
||||||
|
"`max_z` = ?, " +
|
||||||
|
"`max_y` = ?, " +
|
||||||
|
"`max_x` = ? " +
|
||||||
|
"WHERE `region_id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
BlockVector min = region.getMinimumPoint();
|
||||||
|
BlockVector max = region.getMaximumPoint();
|
||||||
|
|
||||||
|
updateCuboidRegionStatement.setInt(1, min.getBlockZ());
|
||||||
|
updateCuboidRegionStatement.setInt(2, min.getBlockY());
|
||||||
|
updateCuboidRegionStatement.setInt(3, min.getBlockX());
|
||||||
|
updateCuboidRegionStatement.setInt(4, max.getBlockZ());
|
||||||
|
updateCuboidRegionStatement.setInt(5, max.getBlockY());
|
||||||
|
updateCuboidRegionStatement.setInt(6, max.getBlockX());
|
||||||
|
updateCuboidRegionStatement.setString(7, region.getId().toLowerCase());
|
||||||
|
|
||||||
|
updateCuboidRegionStatement.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRegionPoly2D(ProtectedPolygonalRegion region) throws SQLException {
|
||||||
|
updateRegion(region, "poly2d");
|
||||||
|
|
||||||
|
PreparedStatement updatePoly2dRegionStatement = this.conn.prepareStatement(
|
||||||
|
"UPDATE `region_poly2d` SET " +
|
||||||
|
"`max_y` = ?, " +
|
||||||
|
"`min_y` = ? " +
|
||||||
|
"WHERE `region_id` = ? "
|
||||||
|
);
|
||||||
|
|
||||||
|
updatePoly2dRegionStatement.setInt(1, region.getMaximumPoint().getBlockY());
|
||||||
|
updatePoly2dRegionStatement.setInt(2, region.getMinimumPoint().getBlockY());
|
||||||
|
updatePoly2dRegionStatement.setString(3, region.getId().toLowerCase());
|
||||||
|
|
||||||
|
updatePoly2dRegionStatement.execute();
|
||||||
|
|
||||||
|
updatePoly2dPoints(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRegionGlobal(GlobalProtectedRegion region) throws SQLException {
|
||||||
|
updateRegion(region, "global");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ProtectedRegion> getRegions() {
|
||||||
|
return regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegions(Map<String, ProtectedRegion> regions) {
|
||||||
|
this.regions = regions;
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package com.sk89q.worldguard.protection.databases;
|
package com.sk89q.worldguard.protection.databases;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||||
@ -35,29 +34,29 @@ public interface ProtectionDatabase {
|
|||||||
* Load the list of regions. The method should not modify the list returned
|
* Load the list of regions. The method should not modify the list returned
|
||||||
* by getRegions() unless the load finishes successfully.
|
* by getRegions() unless the load finishes successfully.
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws ProtectionDatabaseException
|
||||||
*/
|
*/
|
||||||
public void load() throws IOException;
|
public void load() throws ProtectionDatabaseException;
|
||||||
/**
|
/**
|
||||||
* Save the list of regions.
|
* Save the list of regions.
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws ProtectionDatabaseException
|
||||||
*/
|
*/
|
||||||
public void save() throws IOException;
|
public void save() throws ProtectionDatabaseException;
|
||||||
/**
|
/**
|
||||||
* Load the list of regions into a region manager.
|
* Load the list of regions into a region manager.
|
||||||
*
|
*
|
||||||
* @param manager
|
* @param manager
|
||||||
* @throws IOException
|
* @throws ProtectionDatabaseException
|
||||||
*/
|
*/
|
||||||
public void load(RegionManager manager) throws IOException;
|
public void load(RegionManager manager) throws ProtectionDatabaseException;
|
||||||
/**
|
/**
|
||||||
* Save the list of regions from a region manager.
|
* Save the list of regions from a region manager.
|
||||||
*
|
*
|
||||||
* @param manager
|
* @param manager
|
||||||
* @throws IOException
|
* @throws ProtectionDatabaseException
|
||||||
*/
|
*/
|
||||||
public void save(RegionManager manager) throws IOException;
|
public void save(RegionManager manager) throws ProtectionDatabaseException;
|
||||||
/**
|
/**
|
||||||
* Get a list of regions.
|
* Get a list of regions.
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldGuard ProtectionDatabaseException
|
||||||
|
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldguard.protection.databases;
|
||||||
|
|
||||||
|
import java.lang.Exception;
|
||||||
|
|
||||||
|
public class ProtectionDatabaseException extends Exception {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public ProtectionDatabaseException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProtectionDatabaseException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProtectionDatabaseException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProtectionDatabaseException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
package com.sk89q.worldguard.protection.databases;
|
package com.sk89q.worldguard.protection.databases;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@ -98,4 +100,34 @@ public static DefaultDomain parseDomainString(String[] split, int startIndex) {
|
|||||||
|
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a comma separated list of PreparedStatement place holders
|
||||||
|
*
|
||||||
|
* @param length
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String preparePlaceHolders(int length) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (int i = 0; i < length;) {
|
||||||
|
builder.append("?");
|
||||||
|
if (++i < length) {
|
||||||
|
builder.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds all of the parsed values to the PreparedStatement
|
||||||
|
*
|
||||||
|
* @param preparedStatement
|
||||||
|
* @param values
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public static void setValues(PreparedStatement preparedStatement, String... values) throws SQLException {
|
||||||
|
for (int i = 0; i < values.length; i++) {
|
||||||
|
preparedStatement.setString(i + 1, values[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@ -51,18 +52,23 @@ public class YAMLDatabase extends AbstractProtectionDatabase {
|
|||||||
private YAMLProcessor config;
|
private YAMLProcessor config;
|
||||||
private Map<String, ProtectedRegion> regions;
|
private Map<String, ProtectedRegion> regions;
|
||||||
|
|
||||||
public YAMLDatabase(File file) {
|
public YAMLDatabase(File file) throws ProtectionDatabaseException, FileNotFoundException {
|
||||||
if (!file.exists()) { // shouldn't be necessary, but check anyways
|
if (!file.exists()) { // shouldn't be necessary, but check anyways
|
||||||
try {
|
try {
|
||||||
file.createNewFile();
|
file.createNewFile();
|
||||||
} catch (IOException e) {}
|
} catch (IOException e) {
|
||||||
// if this is thrown, we can't do anything (caught elsewhere anyway)
|
throw new FileNotFoundException(file.getAbsolutePath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
config = new YAMLProcessor(file, false, YAMLFormat.COMPACT);
|
config = new YAMLProcessor(file, false, YAMLFormat.COMPACT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load() throws IOException {
|
public void load() throws ProtectionDatabaseException {
|
||||||
|
try {
|
||||||
config.load();
|
config.load();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ProtectionDatabaseException(e);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, YAMLNode> regionData = config.getNodes("regions");
|
Map<String, YAMLNode> regionData = config.getNodes("regions");
|
||||||
|
|
||||||
@ -190,7 +196,7 @@ private DefaultDomain parseDomain(YAMLNode node) {
|
|||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() throws IOException {
|
public void save() throws ProtectionDatabaseException {
|
||||||
config.clear();
|
config.clear();
|
||||||
|
|
||||||
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
|
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* MySQL WordGuard Region Database
|
||||||
|
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldguard.protection.databases.migrators;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||||
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||||
|
|
||||||
|
public abstract class AbstractDatabaseMigrator implements DatabaseMigrator {
|
||||||
|
|
||||||
|
private static HashMap<MigratorKey, Class<? extends AbstractDatabaseMigrator>> migrators =
|
||||||
|
new HashMap<MigratorKey, Class<? extends AbstractDatabaseMigrator>>();
|
||||||
|
|
||||||
|
public static Map<MigratorKey, Class<? extends AbstractDatabaseMigrator>> getMigrators() {
|
||||||
|
if (!migrators.isEmpty()) return migrators;
|
||||||
|
|
||||||
|
AbstractDatabaseMigrator.migrators.put(new MigratorKey("mysql", "yaml"), MySQLToYAMLMigrator.class);
|
||||||
|
AbstractDatabaseMigrator.migrators.put(new MigratorKey("yaml", "mysql"), YAMLToMySQLMigrator.class);
|
||||||
|
|
||||||
|
return migrators;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Set<String> getWorldsFromOld() throws MigrationException;
|
||||||
|
|
||||||
|
protected abstract Map<String, ProtectedRegion> getRegionsForWorldFromOld(String world) throws MigrationException;
|
||||||
|
|
||||||
|
protected abstract ProtectionDatabase getNewWorldStorage(String world) throws MigrationException;
|
||||||
|
|
||||||
|
public void migrate() throws MigrationException {
|
||||||
|
for (String world : this.getWorldsFromOld()) {
|
||||||
|
ProtectionDatabase database = this.getNewWorldStorage(world);
|
||||||
|
database.setRegions(this.getRegionsForWorldFromOld(world));
|
||||||
|
|
||||||
|
try {
|
||||||
|
database.save();
|
||||||
|
} catch (ProtectionDatabaseException e) {
|
||||||
|
throw new MigrationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* MySQL WordGuard Region Database
|
||||||
|
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldguard.protection.databases.migrators;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a method of converting from one database to another.
|
||||||
|
*
|
||||||
|
* @author Nicholas Steicke
|
||||||
|
*/
|
||||||
|
public interface DatabaseMigrator {
|
||||||
|
|
||||||
|
public void migrate() throws MigrationException;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* MySQL WordGuard Region Database
|
||||||
|
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldguard.protection.databases.migrators;
|
||||||
|
|
||||||
|
public class MigrationException extends Exception {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public MigrationException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MigrationException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MigrationException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MigrationException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* MySQL WordGuard Region Database
|
||||||
|
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldguard.protection.databases.migrators;
|
||||||
|
|
||||||
|
public class MigratorKey {
|
||||||
|
public final String from;
|
||||||
|
public final String to;
|
||||||
|
|
||||||
|
public MigratorKey(String from, String to) {
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
MigratorKey other = (MigratorKey) o;
|
||||||
|
|
||||||
|
return other.from.equals(this.from) && other.to.equals(this.to);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 17;
|
||||||
|
hash = hash * 31 + this.from.hashCode();
|
||||||
|
hash = hash * 31 + this.to.hashCode();
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* MySQL WordGuard Region Database
|
||||||
|
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldguard.protection.databases.migrators;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.sk89q.worldguard.bukkit.ConfigurationManager;
|
||||||
|
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||||
|
import com.sk89q.worldguard.protection.databases.MySQLDatabase;
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||||
|
import com.sk89q.worldguard.protection.databases.YAMLDatabase;
|
||||||
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||||
|
|
||||||
|
public class MySQLToYAMLMigrator extends AbstractDatabaseMigrator {
|
||||||
|
|
||||||
|
private WorldGuardPlugin plugin;
|
||||||
|
private Set<String> worlds;
|
||||||
|
|
||||||
|
public MySQLToYAMLMigrator(WorldGuardPlugin plugin) throws MigrationException {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.worlds = new HashSet<String>();
|
||||||
|
|
||||||
|
ConfigurationManager config = plugin.getGlobalStateManager();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Connection conn = DriverManager.getConnection(config.sqlDsn, config.sqlUsername, config.sqlPassword);
|
||||||
|
|
||||||
|
ResultSet worlds = conn.prepareStatement("SELECT `name` FROM `world`;").executeQuery();
|
||||||
|
|
||||||
|
while(worlds.next()) {
|
||||||
|
this.worlds.add(worlds.getString(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new MigrationException((Exception) e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Set<String> getWorldsFromOld() {
|
||||||
|
return this.worlds;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Map<String, ProtectedRegion> getRegionsForWorldFromOld(String world) throws MigrationException {
|
||||||
|
ProtectionDatabase oldDatabase;
|
||||||
|
try {
|
||||||
|
oldDatabase = new MySQLDatabase(plugin.getGlobalStateManager(), world);
|
||||||
|
oldDatabase.load();
|
||||||
|
} catch (ProtectionDatabaseException e) {
|
||||||
|
throw new MigrationException((Exception) e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldDatabase.getRegions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ProtectionDatabase getNewWorldStorage(String world) throws MigrationException {
|
||||||
|
try {
|
||||||
|
File file = new File(plugin.getDataFolder(),
|
||||||
|
"worlds" + File.separator + world + File.separator + "regions.yml");
|
||||||
|
|
||||||
|
return new YAMLDatabase(file);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new MigrationException((Exception) e);
|
||||||
|
} catch (ProtectionDatabaseException e) {
|
||||||
|
throw new MigrationException((Exception) e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* MySQL WordGuard Region Database
|
||||||
|
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldguard.protection.databases.migrators;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||||
|
import com.sk89q.worldguard.protection.databases.MySQLDatabase;
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||||
|
import com.sk89q.worldguard.protection.databases.YAMLDatabase;
|
||||||
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||||
|
|
||||||
|
public class YAMLToMySQLMigrator extends AbstractDatabaseMigrator {
|
||||||
|
|
||||||
|
private WorldGuardPlugin plugin;
|
||||||
|
private HashMap<String,File> regionYamlFiles;
|
||||||
|
|
||||||
|
public YAMLToMySQLMigrator(WorldGuardPlugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
this.regionYamlFiles = new HashMap<String,File>();
|
||||||
|
|
||||||
|
File files[] = new File(plugin.getDataFolder(), "worlds" + File.separator).listFiles();
|
||||||
|
for (File item : files) {
|
||||||
|
if (item.isDirectory()) {
|
||||||
|
for (File subItem : item.listFiles()) {
|
||||||
|
if (subItem.getName().equals("regions.yml")) {
|
||||||
|
this.regionYamlFiles.put(item.getName(), subItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Set<String> getWorldsFromOld() {
|
||||||
|
return this.regionYamlFiles.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Map<String, ProtectedRegion> getRegionsForWorldFromOld(String world) throws MigrationException {
|
||||||
|
ProtectionDatabase oldDatabase;
|
||||||
|
try {
|
||||||
|
oldDatabase = new YAMLDatabase(this.regionYamlFiles.get(world));
|
||||||
|
oldDatabase.load();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new MigrationException((Exception) e);
|
||||||
|
} catch (ProtectionDatabaseException e) {
|
||||||
|
throw new MigrationException((Exception) e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldDatabase.getRegions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ProtectionDatabase getNewWorldStorage(String world) throws MigrationException {
|
||||||
|
try {
|
||||||
|
return new MySQLDatabase(plugin.getGlobalStateManager(), world);
|
||||||
|
} catch (ProtectionDatabaseException e) {
|
||||||
|
throw new MigrationException((Exception) e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -32,6 +32,7 @@
|
|||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldguard.LocalPlayer;
|
import com.sk89q.worldguard.LocalPlayer;
|
||||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedRegionMBRConverter;
|
import com.sk89q.worldguard.protection.regions.ProtectedRegionMBRConverter;
|
||||||
@ -58,7 +59,7 @@ public class PRTreeRegionManager extends RegionManager {
|
|||||||
* @param regionloader
|
* @param regionloader
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public PRTreeRegionManager(ProtectionDatabase regionloader) throws IOException {
|
public PRTreeRegionManager(ProtectionDatabase regionloader) throws ProtectionDatabaseException {
|
||||||
super(regionloader);
|
super(regionloader);
|
||||||
regions = new TreeMap<String, ProtectedRegion>();
|
regions = new TreeMap<String, ProtectedRegion>();
|
||||||
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
|
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldguard.LocalPlayer;
|
import com.sk89q.worldguard.LocalPlayer;
|
||||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||||
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ public RegionManager(ProtectionDatabase loader) {
|
|||||||
*
|
*
|
||||||
* @throws IOException thrown on load error
|
* @throws IOException thrown on load error
|
||||||
*/
|
*/
|
||||||
public void load() throws IOException {
|
public void load() throws ProtectionDatabaseException {
|
||||||
loader.load(this);
|
loader.load(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +66,7 @@ public void load() throws IOException {
|
|||||||
*
|
*
|
||||||
* @throws IOException thrown on save eIf checking multiple flags for a single locationror
|
* @throws IOException thrown on save eIf checking multiple flags for a single locationror
|
||||||
*/
|
*/
|
||||||
public void save() throws IOException {
|
public void save() throws ProtectionDatabaseException {
|
||||||
loader.save(this);
|
loader.save(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user