From fe62c8d0c50ab16d08db7c5f7f246f8a7e0e9145 Mon Sep 17 00:00:00 2001 From: Nicholas Steicke Date: Sun, 4 Mar 2012 15:29:53 +1030 Subject: [PATCH] Fixed regions with same name in different worlds not behaving correctly Fixed database connection timing out Added an error to be thrown explictly when the DB needs updating Added a generic exception for Fatal errors when loading configuration Exit the server when we encounter a fatal configuration exception --- region_storage.sql | 255 ++++++++++-------- region_storage_update_20110325.sql | 106 ++++++++ .../worldguard/bukkit/WorldGuardPlugin.java | 12 +- .../protection/GlobalRegionManager.java | 9 +- .../InvalidTableFormatException.java | 20 ++ .../protection/databases/MySQLDatabase.java | 96 +++++-- .../FatalConfigurationLoadingException.java | 6 + 7 files changed, 363 insertions(+), 141 deletions(-) mode change 100755 => 100644 region_storage.sql create mode 100644 region_storage_update_20110325.sql create mode 100644 src/main/java/com/sk89q/worldguard/protection/databases/InvalidTableFormatException.java create mode 100644 src/main/java/com/sk89q/worldguard/util/FatalConfigurationLoadingException.java diff --git a/region_storage.sql b/region_storage.sql old mode 100755 new mode 100644 index a958740c..76124f4a --- a/region_storage.sql +++ b/region_storage.sql @@ -2,180 +2,213 @@ 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; + `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT , + `name` VARCHAR(64) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + PRIMARY KEY (`id`) , + UNIQUE INDEX `name` (`name` ASC) ) +ENGINE = InnoDB +AUTO_INCREMENT = 5 +DEFAULT CHARACTER SET = utf8 +COLLATE = utf8_bin; -- ----------------------------------------------------- -- 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; + `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT , + `name` VARCHAR(128) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + PRIMARY KEY (`id`) , + UNIQUE INDEX `name` (`name` ASC) ) +ENGINE = InnoDB +AUTO_INCREMENT = 9 +DEFAULT CHARACTER SET = utf8 +COLLATE = utf8_bin; -- ----------------------------------------------------- -- 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 , + `id` VARCHAR(128) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + `world_id` INT(10) UNSIGNED NOT NULL , + `type` ENUM('cuboid','poly2d','global') CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + `priority` SMALLINT(6) NOT NULL DEFAULT '0' , + `parent` VARCHAR(128) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NULL DEFAULT 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, + INDEX `parent` (`parent` ASC) , 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` ) + ON UPDATE CASCADE, + CONSTRAINT `parent` + FOREIGN KEY (`parent` ) REFERENCES `region` (`id` ) - ON DELETE CASCADE + ON DELETE SET NULL ON UPDATE CASCADE) -ENGINE = InnoDB; +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8 +COLLATE = utf8_bin; -- ----------------------------------------------------- -- 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`) , + `region_id` VARCHAR(128) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + `world_id` INT(10) UNSIGNED NOT NULL , + `min_x` BIGINT(20) NOT NULL , + `min_y` BIGINT(20) NOT NULL , + `min_z` BIGINT(20) NOT NULL , + `max_x` BIGINT(20) NOT NULL , + `max_y` BIGINT(20) NOT NULL , + `max_z` BIGINT(20) NOT NULL , + PRIMARY KEY (`region_id`, `world_id`) , INDEX `fk_region_cuboid_region` (`region_id` ASC) , CONSTRAINT `fk_region_cuboid_region` - FOREIGN KEY (`region_id` ) - REFERENCES `region` (`id` ) + FOREIGN KEY (`region_id` , `world_id` ) + REFERENCES `region` (`id` , `world_id` ) ON DELETE CASCADE ON UPDATE CASCADE) -ENGINE = InnoDB; +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8 +COLLATE = utf8_bin; -- ----------------------------------------------------- --- Table `region_poly2d` +-- Table `region_flag` -- ----------------------------------------------------- -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` ) +CREATE TABLE IF NOT EXISTS `region_flag` ( + `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT , + `region_id` VARCHAR(128) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + `world_id` INT(10) UNSIGNED NOT NULL , + `flag` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + `value` VARCHAR(256) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + PRIMARY KEY (`id`) , + INDEX `fk_flags_region` (`region_id` ASC, `world_id` ASC) , + CONSTRAINT `fk_flags_region` + FOREIGN KEY (`region_id` , `world_id` ) + REFERENCES `region` (`id` , `world_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; +ENGINE = InnoDB +AUTO_INCREMENT = 3246 +DEFAULT CHARACTER SET = utf8 +COLLATE = utf8_bin; -- ----------------------------------------------------- -- 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`) , + `region_id` VARCHAR(128) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + `world_id` INT(10) UNSIGNED NOT NULL , + `group_id` INT(10) UNSIGNED NOT NULL , + `owner` TINYINT(1) NOT NULL , + PRIMARY KEY (`region_id`, `world_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, + CONSTRAINT `fk_region_groups_region` + FOREIGN KEY (`region_id` , `world_id` ) + REFERENCES `region` (`id` , `world_id` ) + ON DELETE CASCADE ON UPDATE CASCADE) -ENGINE = InnoDB; +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8 +COLLATE = utf8_bin; + + +-- ----------------------------------------------------- +-- Table `user` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `user` ( + `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT , + `name` VARCHAR(64) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + PRIMARY KEY (`id`) , + UNIQUE INDEX `name` (`name` ASC) ) +ENGINE = InnoDB +AUTO_INCREMENT = 82 +DEFAULT CHARACTER SET = utf8 +COLLATE = utf8_bin; + + +-- ----------------------------------------------------- +-- Table `region_players` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `region_players` ( + `region_id` VARCHAR(128) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + `world_id` INT(10) UNSIGNED NOT NULL , + `user_id` INT(10) UNSIGNED NOT NULL , + `owner` TINYINT(1) NOT NULL , + PRIMARY KEY (`region_id`, `world_id`, `user_id`) , + INDEX `fk_region_players_region` (`region_id` ASC) , + INDEX `fk_region_users_user` (`user_id` ASC) , + CONSTRAINT `fk_region_users_region` + FOREIGN KEY (`region_id` , `world_id` ) + REFERENCES `region` (`id` , `world_id` ) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT `fk_region_users_user` + FOREIGN KEY (`user_id` ) + REFERENCES `user` (`id` ) + ON DELETE CASCADE + ON UPDATE CASCADE) +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8 +COLLATE = utf8_bin; + + +-- ----------------------------------------------------- +-- Table `region_poly2d` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `region_poly2d` ( + `region_id` VARCHAR(128) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + `world_id` INT(10) UNSIGNED NOT NULL , + `min_y` INT(11) NOT NULL , + `max_y` INT(11) NOT NULL , + PRIMARY KEY (`region_id`, `world_id`) , + INDEX `fk_region_poly2d_region` (`region_id` ASC) , + CONSTRAINT `fk_region_poly2d_region` + FOREIGN KEY (`region_id` , `world_id` ) + REFERENCES `region` (`id` , `world_id` ) + ON DELETE CASCADE + ON UPDATE CASCADE) +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8 +COLLATE = utf8_bin; -- ----------------------------------------------------- -- 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 , + `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT , + `region_id` VARCHAR(128) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + `world_id` INT(10) UNSIGNED NOT NULL , + `x` BIGINT(20) NOT NULL , + `z` BIGINT(20) NOT NULL , PRIMARY KEY (`id`) , - INDEX `fk_region_poly2d_point_region_poly2d` (`region_id` ASC) , + INDEX `fk_region_poly2d_point_region_poly2d` (`region_id` ASC, `world_id` ASC) , CONSTRAINT `fk_region_poly2d_point_region_poly2d` - FOREIGN KEY (`region_id` ) - REFERENCES `region_poly2d` (`region_id` ) + FOREIGN KEY (`region_id` , `world_id` ) + REFERENCES `region_poly2d` (`region_id` , `world_id` ) ON DELETE CASCADE ON UPDATE CASCADE) -ENGINE = InnoDB; +ENGINE = InnoDB +AUTO_INCREMENT = 15 +DEFAULT CHARACTER SET = utf8 +COLLATE = utf8_bin; diff --git a/region_storage_update_20110325.sql b/region_storage_update_20110325.sql new file mode 100644 index 00000000..bca8beca --- /dev/null +++ b/region_storage_update_20110325.sql @@ -0,0 +1,106 @@ +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'; + +ALTER TABLE `region_cuboid` DROP FOREIGN KEY `fk_region_cuboid_region` ; + +ALTER TABLE `region_flag` DROP FOREIGN KEY `fk_flags_region1` ; + +ALTER TABLE `region_groups` DROP FOREIGN KEY `fk_region_groups_region` ; + +ALTER TABLE `region_players` DROP FOREIGN KEY `fk_region_players_user` , DROP FOREIGN KEY `fk_region_players_region` ; + +ALTER TABLE `region_poly2d` DROP FOREIGN KEY `fk_region_poly2d_region` ; + +ALTER TABLE `region_poly2d_point` DROP FOREIGN KEY `fk_region_poly2d_point_region_poly2d` ; + +ALTER TABLE `group` COLLATE = utf8_bin ; + +ALTER TABLE `region_cuboid` COLLATE = utf8_bin , ADD COLUMN `world_id` INT(10) UNSIGNED NOT NULL AFTER `region_id` , CHANGE COLUMN `min_x` `min_x` BIGINT(20) NOT NULL AFTER `world_id` , CHANGE COLUMN `min_y` `min_y` BIGINT(20) NOT NULL AFTER `min_x` , CHANGE COLUMN `max_x` `max_x` BIGINT(20) NOT NULL AFTER `min_z` , CHANGE COLUMN `max_y` `max_y` BIGINT(20) NOT NULL AFTER `max_x` , + ADD CONSTRAINT `fk_region_cuboid_region` + FOREIGN KEY (`region_id` , `world_id` ) + REFERENCES `region` (`id` , `world_id` ) + ON DELETE CASCADE + ON UPDATE CASCADE +, DROP PRIMARY KEY +, ADD PRIMARY KEY (`region_id`, `world_id`) ; + +ALTER TABLE `region_flag` COLLATE = utf8_bin , ADD COLUMN `world_id` INT(10) UNSIGNED NOT NULL AFTER `region_id` , CHANGE COLUMN `flag` `flag` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL , + ADD CONSTRAINT `fk_flags_region` + FOREIGN KEY (`region_id` , `world_id` ) + REFERENCES `region` (`id` , `world_id` ) + ON DELETE CASCADE + ON UPDATE CASCADE +, DROP INDEX `fk_flags_region` +, ADD INDEX `fk_flags_region` (`region_id` ASC, `world_id` ASC) ; + +ALTER TABLE `region_groups` COLLATE = utf8_bin , ADD COLUMN `world_id` INT(10) UNSIGNED NOT NULL AFTER `region_id` , DROP FOREIGN KEY `fk_region_groups_group` ; + +ALTER TABLE `region_groups` + ADD CONSTRAINT `fk_region_groups_group` + FOREIGN KEY (`group_id` ) + REFERENCES `group` (`id` ) + ON DELETE CASCADE + ON UPDATE CASCADE, + ADD CONSTRAINT `fk_region_groups_region` + FOREIGN KEY (`region_id` , `world_id` ) + REFERENCES `region` (`id` , `world_id` ) + ON DELETE CASCADE + ON UPDATE CASCADE +, DROP PRIMARY KEY +, ADD PRIMARY KEY (`region_id`, `world_id`, `group_id`) ; + +ALTER TABLE `region_players` COLLATE = utf8_bin , ADD COLUMN `world_id` INT(10) UNSIGNED NOT NULL AFTER `region_id` , + ADD CONSTRAINT `fk_region_users_region` + FOREIGN KEY (`region_id` , `world_id` ) + REFERENCES `region` (`id` , `world_id` ) + ON DELETE CASCADE + ON UPDATE CASCADE, + ADD CONSTRAINT `fk_region_users_user` + FOREIGN KEY (`user_id` ) + REFERENCES `user` (`id` ) + ON DELETE CASCADE + ON UPDATE CASCADE +, DROP PRIMARY KEY +, ADD PRIMARY KEY (`region_id`, `world_id`, `user_id`) +, ADD INDEX `fk_region_users_user` (`user_id` ASC) +, DROP INDEX `fk_region_players_user` ; + +ALTER TABLE `region_poly2d` COLLATE = utf8_bin , ADD COLUMN `world_id` INT(10) UNSIGNED NOT NULL AFTER `region_id` , CHANGE COLUMN `min_y` `min_y` INT(11) NOT NULL AFTER `world_id` , + ADD CONSTRAINT `fk_region_poly2d_region` + FOREIGN KEY (`region_id` , `world_id` ) + REFERENCES `region` (`id` , `world_id` ) + ON DELETE CASCADE + ON UPDATE CASCADE +, DROP PRIMARY KEY +, ADD PRIMARY KEY (`region_id`, `world_id`) ; + +ALTER TABLE `region_poly2d_point` COLLATE = utf8_bin , ADD COLUMN `world_id` INT(10) UNSIGNED NOT NULL AFTER `region_id` , CHANGE COLUMN `x` `x` BIGINT(20) NOT NULL AFTER `world_id` , + ADD CONSTRAINT `fk_region_poly2d_point_region_poly2d` + FOREIGN KEY (`region_id` , `world_id` ) + REFERENCES `region_poly2d` (`region_id` , `world_id` ) + ON DELETE CASCADE + ON UPDATE CASCADE +, DROP INDEX `fk_region_poly2d_point_region_poly2d` +, ADD INDEX `fk_region_poly2d_point_region_poly2d` (`region_id` ASC, `world_id` ASC) ; + +ALTER TABLE `user` COLLATE = utf8_bin ; + +ALTER TABLE `world` COLLATE = utf8_bin ; + + +UPDATE `region_cuboid` AS c SET c.`world_id` = (SELECT p.`world_id` FROM `region` AS p WHERE p.`id` = c.`region_id`); + +UPDATE `region_flag` AS c SET c.`world_id` = (SELECT p.`world_id` FROM `region` AS p WHERE p.`id` = c.`region_id`); + +UPDATE `region_groups` AS c SET c.`world_id` = (SELECT p.`world_id` FROM `region` AS p WHERE p.`id` = c.`region_id`); + +UPDATE `region_players` AS c SET c.`world_id` = (SELECT p.`world_id` FROM `region` AS p WHERE p.`id` = c.`region_id`); + +UPDATE `region_poly2d` AS c SET c.`world_id` = (SELECT p.`world_id` FROM `region` AS p WHERE p.`id` = c.`region_id`); + +UPDATE `region_poly2d_point` AS c SET c.`world_id` = (SELECT p.`world_id` FROM `region` AS p WHERE p.`id` = c.`region_id`); + +SET SQL_MODE=@OLD_SQL_MODE; +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; +SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java index f1587b17..62cfc61c 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java @@ -55,6 +55,7 @@ import com.sk89q.worldguard.bukkit.commands.ToggleCommands; import com.sk89q.worldguard.protection.GlobalRegionManager; import com.sk89q.worldguard.protection.managers.RegionManager; +import com.sk89q.worldguard.util.FatalConfigurationLoadingException; /** * The main class for WorldGuard as a Bukkit plugin. @@ -133,9 +134,14 @@ public void run() { // This must be done before configuration is loaded LegacyWorldGuardMigration.migrateBlacklist(this); - // Load the configuration - configuration.load(); - globalRegionManager.preload(); + try { + // Load the configuration + configuration.load(); + globalRegionManager.preload(); + } catch (FatalConfigurationLoadingException e) { + e.printStackTrace(); + getServer().shutdown(); + } // Migrate regions after the regions were loaded because // the migration code reuses the loaded region managers diff --git a/src/main/java/com/sk89q/worldguard/protection/GlobalRegionManager.java b/src/main/java/com/sk89q/worldguard/protection/GlobalRegionManager.java index 4cfd8718..fb78725c 100644 --- a/src/main/java/com/sk89q/worldguard/protection/GlobalRegionManager.java +++ b/src/main/java/com/sk89q/worldguard/protection/GlobalRegionManager.java @@ -21,7 +21,10 @@ import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector; import java.io.File; +import java.io.FileNotFoundException; import java.util.HashMap; +import java.util.logging.Level; + import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Block; @@ -162,10 +165,10 @@ public RegionManager load(World world) { logStr += "file \"" + file + "\" "; } - plugin.getLogger().info(logStr + " : " + e.getMessage()); + plugin.getLogger().log(Level.SEVERE, logStr + " : " + e.getMessage()); e.printStackTrace(); - } catch (Exception e) { - plugin.getLogger().info("Error loading regions for world \"" + } catch (FileNotFoundException e) { + plugin.getLogger().log(Level.SEVERE, "Error loading regions for world \"" + name + "\": " + e.toString() + "\n\t" + e.getMessage()); e.printStackTrace(); } diff --git a/src/main/java/com/sk89q/worldguard/protection/databases/InvalidTableFormatException.java b/src/main/java/com/sk89q/worldguard/protection/databases/InvalidTableFormatException.java new file mode 100644 index 00000000..a7092abe --- /dev/null +++ b/src/main/java/com/sk89q/worldguard/protection/databases/InvalidTableFormatException.java @@ -0,0 +1,20 @@ +package com.sk89q.worldguard.protection.databases; + +import com.sk89q.worldguard.util.FatalConfigurationLoadingException; + +public class InvalidTableFormatException extends FatalConfigurationLoadingException { + private static final long serialVersionUID = 1L; + + protected String updateFile; + + public InvalidTableFormatException(String updateFile) { + super(); + + this.updateFile = updateFile; + } + + public String toString() { + return "You need to update your database to the latest version.\n" + + "\t\tPlease see " + this.updateFile; + } +} diff --git a/src/main/java/com/sk89q/worldguard/protection/databases/MySQLDatabase.java b/src/main/java/com/sk89q/worldguard/protection/databases/MySQLDatabase.java index 37d42381..4f05aa45 100755 --- a/src/main/java/com/sk89q/worldguard/protection/databases/MySQLDatabase.java +++ b/src/main/java/com/sk89q/worldguard/protection/databases/MySQLDatabase.java @@ -70,6 +70,18 @@ public MySQLDatabase(ConfigurationManager config, String world, Logger logger) t try { connect(); + + try { + // Test if the database is up to date, if not throw a critical error + PreparedStatement verTest = this.conn.prepareStatement( + "SELECT `world_id` FROM `region_cuboid` LIMIT 0,1;" + ); + verTest.execute(); + } catch (SQLException ex) { + throw new InvalidTableFormatException( + "region_storage_update_20110325.sql" + ); + } PreparedStatement worldStmt = conn.prepareStatement( "SELECT `id` FROM " + @@ -113,6 +125,20 @@ public MySQLDatabase(ConfigurationManager config, String world, Logger logger) t } private void connect() throws SQLException { + if (conn != null) { + // Make a dummy query to check the connnection is alive. + try { + conn.prepareStatement("SELECT 1;").execute(); + } catch (SQLException ex) { + // Test if the dummy query failed because the connection is dead, + // and if it is mark the connection as closed (the MySQL Driver + // does not ensure that the connection is marked as closed unless + // the close() method has been called. + if ("08S01".equals(ex.getSQLState())) { + conn.close(); + } + } + } if (conn == null || conn.isClosed()) { conn = DriverManager.getConnection(config.sqlDsn, config.sqlUsername, config.sqlPassword); } @@ -126,7 +152,8 @@ private void loadFlags(ProtectedRegion region) { "`region_flag`.`flag`, " + "`region_flag`.`value` " + "FROM `region_flag` " + - "WHERE `region_flag`.`region_id` = ? " + "WHERE `region_flag`.`region_id` = ? " + + "AND `region_flag`.`world_id` = " + this.worldDbId ); flagsStatement.setString(1, region.getId().toLowerCase()); @@ -178,7 +205,8 @@ private void loadOwnersAndMembers(ProtectedRegion region) { "LEFT JOIN `user` ON ( " + "`region_players`.`user_id` = " + "`user`.`id`) " + - "WHERE `region_players`.`region_id` = ? " + "WHERE `region_players`.`region_id` = ? " + + "AND `region_players`.`world_id` = " + this.worldDbId ); usersStatement.setString(1, region.getId().toLowerCase()); @@ -203,7 +231,8 @@ private void loadOwnersAndMembers(ProtectedRegion region) { "LEFT JOIN `group` ON ( " + "`region_groups`.`group_id` = " + "`group`.`id`) " + - "WHERE `region_groups`.`region_id` = ? " + "WHERE `region_groups`.`region_id` = ? " + + "AND `region_groups`.`world_id` = " + this.worldDbId ); groupsStatement.setString(1, region.getId().toLowerCase()); @@ -235,7 +264,8 @@ private void loadGlobal() { "`parent`.`id` AS `parent` " + "FROM `region` " + "LEFT JOIN `region` AS `parent` " + - "ON (`region`.`parent` = `parent`.`id`) " + + "ON (`region`.`parent` = `parent`.`id` " + + "AND `region`.`world_id` = `parent`.`world_id`) " + "WHERE `region`.`type` = 'global' " + "AND `region`.`world_id` = ? " ); @@ -289,9 +319,11 @@ private void loadCuboid() { "`parent`.`id` AS `parent` " + "FROM `region_cuboid` " + "LEFT JOIN `region` " + - "ON (`region_cuboid`.`region_id` = `region`.`id`) " + + "ON (`region_cuboid`.`region_id` = `region`.`id` " + + "AND `region_cuboid`.`world_id` = `region`.`world_id`) " + "LEFT JOIN `region` AS `parent` " + - "ON (`region`.`parent` = `parent`.`id`) " + + "ON (`region`.`parent` = `parent`.`id` " + + "AND `region`.`world_id` = `parent`.`world_id`) " + "WHERE `region`.`world_id` = ? " ); @@ -358,9 +390,11 @@ private void loadPoly2d() { "`parent`.`id` AS `parent` " + "FROM `region_poly2d` " + "LEFT JOIN `region` " + - "ON (`region_poly2d`.`region_id` = `region`.`id`) " + + "ON (`region_poly2d`.`region_id` = `region`.`id` " + + "AND `region_poly2d`.`world_id` = `region`.`world_id`) " + "LEFT JOIN `region` AS `parent` " + - "ON (`region`.`parent` = `parent`.`id`) " + + "ON (`region`.`parent` = `parent`.`id` " + + "AND `region`.`world_id` = `parent`.`world_id`) " + "WHERE `region`.`world_id` = ? " ); @@ -372,7 +406,8 @@ private void loadPoly2d() { "`region_poly2d_point`.`x`, " + "`region_poly2d_point`.`z` " + "FROM `region_poly2d_point` " + - "WHERE `region_poly2d_point`.`region_id` = ? " + "WHERE `region_poly2d_point`.`region_id` = ? " + + "AND `region_poly2d_point`.`world_id` = " + this.worldDbId ); while (poly2dResultSet.next()) { @@ -663,7 +698,7 @@ public void save() throws ProtectionDatabaseException { PreparedStatement setParentStatement = this.conn.prepareStatement( "UPDATE `region` SET " + "`parent` = ? " + - "WHERE `id` = ? " + "WHERE `id` = ? AND `world_id` = " + this.worldDbId ); setParentStatement.setString(1, entry.getValue().getParent().getId().toLowerCase()); @@ -694,7 +729,8 @@ public void save() throws ProtectionDatabaseException { private void updateFlags(ProtectedRegion region) throws SQLException { PreparedStatement clearCurrentFlagStatement = this.conn.prepareStatement( "DELETE FROM `region_flag` " + - "WHERE `region_id` = ? " + "WHERE `region_id` = ? " + + "AND `world_id` = " + this.worldDbId ); clearCurrentFlagStatement.setString(1, region.getId().toLowerCase()); @@ -709,9 +745,10 @@ private void updateFlags(ProtectedRegion region) throws SQLException { "INSERT INTO `region_flag` ( " + "`id`, " + "`region_id`, " + + "`world_id`, " + "`flag`, " + "`value` " + - ") VALUES (null, ?, ?, ?)" + ") VALUES (null, ?, " + this.worldDbId + ", ?, ?)" ); insertFlagStatement.setString(1, region.getId().toLowerCase()); @@ -734,6 +771,7 @@ private void updatePlayerAndGroups(ProtectedRegion region, Boolean owners) throw PreparedStatement deleteUsersForRegion = this.conn.prepareStatement( "DELETE FROM `region_players` " + "WHERE `region_id` = ? " + + "AND `world_id` = " + this.worldDbId + " " + "AND `owner` = ?" ); @@ -743,7 +781,8 @@ private void updatePlayerAndGroups(ProtectedRegion region, Boolean owners) throw PreparedStatement insertUsersForRegion = this.conn.prepareStatement( "INSERT INTO `region_players` " + - "(`region_id`, `user_id`, `owner`) VALUES (?, ?, ?)" + "(`region_id`, `world_id`, `user_id`, `owner`) " + + "VALUES (?, " + this.worldDbId + ", ?, ?)" ); Map players = getUserIds(domain.getPlayers().toArray(new String[0])); @@ -759,6 +798,7 @@ private void updatePlayerAndGroups(ProtectedRegion region, Boolean owners) throw PreparedStatement deleteGroupsForRegion = this.conn.prepareStatement( "DELETE FROM `region_groups` " + "WHERE `region_id` = ? " + + "AND `world_id` = " + this.worldDbId + " " + "AND `owner` = ?" ); @@ -768,7 +808,8 @@ private void updatePlayerAndGroups(ProtectedRegion region, Boolean owners) throw PreparedStatement insertGroupsForRegion = this.conn.prepareStatement( "INSERT INTO `region_groups` " + - "(`region_id`, `group_id`, `owner`) VALUES (?, ?, ?)" + "(`region_id`, `world_id`, `group_id`, `owner`) " + + "VALUES (?, " + this.worldDbId + ", ?, ?)" ); Map groups = getGroupIds(domain.getGroups().toArray(new String[0])); @@ -795,12 +836,13 @@ private void insertRegion(ProtectedRegion region, String type) throws SQLExcepti "`type`, " + "`priority`, " + "`parent` " + - ") VALUES (?, " + this.worldDbId + ", ?, ?, null)" + ") VALUES (?, ?, ?, ?, null)" ); insertRegionStatement.setString(1, region.getId().toLowerCase()); - insertRegionStatement.setString(2, type); - insertRegionStatement.setInt(3, region.getPriority()); + insertRegionStatement.setInt(2, this.worldDbId); + insertRegionStatement.setString(3, type); + insertRegionStatement.setInt(4, region.getPriority()); insertRegionStatement.execute(); @@ -816,13 +858,14 @@ private void insertRegionCuboid(ProtectedCuboidRegion region) throws SQLExceptio PreparedStatement insertCuboidRegionStatement = this.conn.prepareStatement( "INSERT INTO `region_cuboid` (" + "`region_id`, " + + "`world_id`, " + "`min_z`, " + "`min_y`, " + "`min_x`, " + "`max_z`, " + "`max_y`, " + "`max_x` " + - ") VALUES (?, ?, ?, ?, ?, ?, ?)" + ") VALUES (?, " + this.worldDbId + ", ?, ?, ?, ?, ?, ?)" ); BlockVector min = region.getMinimumPoint(); @@ -845,9 +888,10 @@ private void insertRegionPoly2D(ProtectedPolygonalRegion region) throws SQLExcep PreparedStatement insertPoly2dRegionStatement = this.conn.prepareStatement( "INSERT INTO `region_poly2d` (" + "`region_id`, " + + "`world_id`, " + "`max_y`, " + "`min_y` " + - ") VALUES (?, ?, ?)" + ") VALUES (?, " + this.worldDbId + ", ?, ?)" ); insertPoly2dRegionStatement.setString(1, region.getId().toLowerCase()); @@ -862,7 +906,8 @@ private void insertRegionPoly2D(ProtectedPolygonalRegion region) throws SQLExcep private void updatePoly2dPoints(ProtectedPolygonalRegion region) throws SQLException { PreparedStatement clearPoly2dPointsForRegionStatement = this.conn.prepareStatement( "DELETE FROM `region_poly2d_point` " + - "WHERE `region_id` = ? " + "WHERE `region_id` = ? " + + "AND `world_id` = " + this.worldDbId ); clearPoly2dPointsForRegionStatement.setString(1, region.getId().toLowerCase()); @@ -873,9 +918,10 @@ private void updatePoly2dPoints(ProtectedPolygonalRegion region) throws SQLExcep "INSERT INTO `region_poly2d_point` (" + "`id`, " + "`region_id`, " + + "`world_id`, " + "`z`, " + "`x` " + - ") VALUES (null, ?, ?, ?)" + ") VALUES (null, ?, " + this.worldDbId + ", ?, ?)" ); for (BlockVector2D point : region.getPoints()) { @@ -894,7 +940,7 @@ private void insertRegionGlobal(GlobalProtectedRegion region) throws SQLExceptio private void updateRegion(ProtectedRegion region, String type) throws SQLException { PreparedStatement updateRegionStatement = this.conn.prepareStatement( "UPDATE `region` SET " + - "`priority` = ? WHERE `id` = ? " + "`priority` = ? WHERE `id` = ? AND `world_id` = " + this.worldDbId ); updateRegionStatement.setInt(1, region.getPriority()); @@ -919,7 +965,8 @@ private void updateRegionCuboid(ProtectedCuboidRegion region) throws SQLExceptio "`max_z` = ?, " + "`max_y` = ?, " + "`max_x` = ? " + - "WHERE `region_id` = ? " + "WHERE `region_id` = ? " + + "AND `world_id` = " + this.worldDbId ); BlockVector min = region.getMinimumPoint(); @@ -943,7 +990,8 @@ private void updateRegionPoly2D(ProtectedPolygonalRegion region) throws SQLExcep "UPDATE `region_poly2d` SET " + "`max_y` = ?, " + "`min_y` = ? " + - "WHERE `region_id` = ? " + "WHERE `region_id` = ? " + + "AND `world_id` = " + this.worldDbId ); updatePoly2dRegionStatement.setInt(1, region.getMaximumPoint().getBlockY()); diff --git a/src/main/java/com/sk89q/worldguard/util/FatalConfigurationLoadingException.java b/src/main/java/com/sk89q/worldguard/util/FatalConfigurationLoadingException.java new file mode 100644 index 00000000..6c10cc9d --- /dev/null +++ b/src/main/java/com/sk89q/worldguard/util/FatalConfigurationLoadingException.java @@ -0,0 +1,6 @@ +package com.sk89q.worldguard.util; + +public class FatalConfigurationLoadingException extends RuntimeException { + private static final long serialVersionUID = 1L; + +}