BlockState Migration-Command
This commit is contained in:
parent
0a05ac75a4
commit
6db1664a7e
6 changed files with 318 additions and 26 deletions
|
@ -26,6 +26,7 @@ public class MainCommand extends BukkitCommand implements IHelpDescribed, IMetho
|
||||||
public MainCommand() {
|
public MainCommand() {
|
||||||
}
|
}
|
||||||
public MainCommand(LimitedCreative plugin) {
|
public MainCommand(LimitedCreative plugin) {
|
||||||
|
super(plugin);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package de.jaschastarke.minecraft.limitedcreative.blockstate;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
@ -12,6 +13,7 @@ import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.bukkit.selections.Selection;
|
import com.sk89q.worldedit.bukkit.selections.Selection;
|
||||||
|
|
||||||
import de.jaschastarke.LocaleString;
|
import de.jaschastarke.LocaleString;
|
||||||
|
import de.jaschastarke.bukkit.lib.chat.ChatFormattings;
|
||||||
import de.jaschastarke.bukkit.lib.commands.BukkitCommand;
|
import de.jaschastarke.bukkit.lib.commands.BukkitCommand;
|
||||||
import de.jaschastarke.bukkit.lib.commands.CommandContext;
|
import de.jaschastarke.bukkit.lib.commands.CommandContext;
|
||||||
import de.jaschastarke.bukkit.lib.commands.CommandException;
|
import de.jaschastarke.bukkit.lib.commands.CommandException;
|
||||||
|
@ -20,6 +22,10 @@ import de.jaschastarke.bukkit.lib.commands.IHelpDescribed;
|
||||||
import de.jaschastarke.bukkit.lib.commands.MissingPermissionCommandException;
|
import de.jaschastarke.bukkit.lib.commands.MissingPermissionCommandException;
|
||||||
import de.jaschastarke.bukkit.lib.commands.annotations.IsCommand;
|
import de.jaschastarke.bukkit.lib.commands.annotations.IsCommand;
|
||||||
import de.jaschastarke.bukkit.lib.commands.annotations.Usages;
|
import de.jaschastarke.bukkit.lib.commands.annotations.Usages;
|
||||||
|
import de.jaschastarke.bukkit.lib.commands.parser.DefinedParameterParser;
|
||||||
|
import de.jaschastarke.bukkit.lib.database.DBHelper;
|
||||||
|
import de.jaschastarke.database.DatabaseConfigurationException;
|
||||||
|
import de.jaschastarke.database.db.Database;
|
||||||
import de.jaschastarke.maven.ArchiveDocComments;
|
import de.jaschastarke.maven.ArchiveDocComments;
|
||||||
import de.jaschastarke.maven.PluginCommand;
|
import de.jaschastarke.maven.PluginCommand;
|
||||||
import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission;
|
import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission;
|
||||||
|
@ -27,6 +33,7 @@ import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
|
||||||
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source;
|
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source;
|
||||||
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.Cuboid;
|
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.Cuboid;
|
||||||
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.DBTransaction;
|
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.DBTransaction;
|
||||||
|
import de.jaschastarke.modularize.ModuleEntry.ModuleState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LimitedCreative-BlockState-Command: modify blockstate database to prevent drops of selected blocks (requires WorldEdit)
|
* LimitedCreative-BlockState-Command: modify blockstate database to prevent drops of selected blocks (requires WorldEdit)
|
||||||
|
@ -43,7 +50,8 @@ public class BlockStateCommand extends BukkitCommand implements IHelpDescribed {
|
||||||
this.help = this.getDefaultHelpCommand();
|
this.help = this.getDefaultHelpCommand();
|
||||||
}
|
}
|
||||||
public BlockStateCommand(ModBlockStates mod) {
|
public BlockStateCommand(ModBlockStates mod) {
|
||||||
this();
|
super(mod.getPlugin());
|
||||||
|
this.help = this.getDefaultHelpCommand();
|
||||||
this.mod = mod;
|
this.mod = mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +76,7 @@ public class BlockStateCommand extends BukkitCommand implements IHelpDescribed {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharSequence[] getUsages() {
|
public CharSequence[] getUsages() {
|
||||||
return null;
|
return new String[]{"..."};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -80,6 +88,12 @@ public class BlockStateCommand extends BukkitCommand implements IHelpDescribed {
|
||||||
public CharSequence getPackageName() {
|
public CharSequence getPackageName() {
|
||||||
return mod.getPlugin().getName() + " - " + mod.getName();
|
return mod.getPlugin().getName() + " - " + mod.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean execute(final CommandContext context, final String[] args) throws MissingPermissionCommandException, CommandException {
|
||||||
|
if (mod.getModuleEntry().getState() != ModuleState.ENABLED)
|
||||||
|
throw new CommandException("Module " + mod.getName() + " is disabled");
|
||||||
|
return super.execute(context, args);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifies the Block-GameMode-Database and sets all blocks in the selection to the provided gamemode. Set it
|
* Modifies the Block-GameMode-Database and sets all blocks in the selection to the provided gamemode. Set it
|
||||||
|
@ -89,7 +103,6 @@ public class BlockStateCommand extends BukkitCommand implements IHelpDescribed {
|
||||||
* @throws MissingPermissionCommandException
|
* @throws MissingPermissionCommandException
|
||||||
*/
|
*/
|
||||||
@IsCommand("set")
|
@IsCommand("set")
|
||||||
//@NeedsPermission("region")
|
|
||||||
@Usages("<gamemode>")
|
@Usages("<gamemode>")
|
||||||
public boolean setGameMode(final CommandContext context, String... args) throws CommandException, MissingPermissionCommandException {
|
public boolean setGameMode(final CommandContext context, String... args) throws CommandException, MissingPermissionCommandException {
|
||||||
if (!mod.getPlugin().getServer().getPluginManager().isPluginEnabled("WorldEdit")) {
|
if (!mod.getPlugin().getServer().getPluginManager().isPluginEnabled("WorldEdit")) {
|
||||||
|
@ -169,6 +182,60 @@ public class BlockStateCommand extends BukkitCommand implements IHelpDescribed {
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports BlockState Data from a given Database to the current active Database.
|
||||||
|
* A Server-Restart is needed after migration!
|
||||||
|
* Parameters:
|
||||||
|
* -u --update Don't delete existing records / only overwrite if newer
|
||||||
|
*/
|
||||||
|
@IsCommand("migrate")
|
||||||
|
@Usages("-u <dsn> [username] [password]")
|
||||||
|
public boolean migrateDatabase(final CommandContext context, String... args) throws CommandException, MissingPermissionCommandException {
|
||||||
|
DefinedParameterParser params = new DefinedParameterParser(args, new String[]{"debug", "d", "update", "u", "confirm"});
|
||||||
|
if (params.getArgumentCount() < 1) {// doesn't count parameters
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Bukkit.getServer().getOnlinePlayers().length > (context.isPlayer() ? 1 : 0)) {
|
||||||
|
context.responseFormatted(ChatFormattings.ERROR, L("command.blockstate.migrate_useronline_error"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Database source;
|
||||||
|
Database target;
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (params.getArgumentCount() < 2)
|
||||||
|
source = DBHelper.createConnection(params.getArgument(0));
|
||||||
|
else if (params.getArgumentCount() < 3)
|
||||||
|
source = DBHelper.createConnection(params.getArgument(0), params.getArgument(1), null);
|
||||||
|
else
|
||||||
|
source = DBHelper.createConnection(params.getArgument(0), params.getArgument(1), params.getArgument(2));
|
||||||
|
|
||||||
|
target = mod.getPlugin().getDatabaseConnection();
|
||||||
|
} catch (DatabaseConfigurationException e) {
|
||||||
|
context.responseFormatted(ChatFormattings.ERROR, L("command.blockstate.migrate_connect_error", e.getMessage()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!params.getFlags().contains("confirm")) {
|
||||||
|
context.responseFormatted(ChatFormattings.INFO, L("command.blockstate.migrate_confirm", "--confirm"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod.getModuleEntry().disable();
|
||||||
|
DatabaseMigrationThread thread = new DatabaseMigrationThread(mod, context, source, target);
|
||||||
|
if (params.getFlags().contains("update") || params.getFlags().contains("u")) {
|
||||||
|
thread.setMode(DatabaseMigrationThread.Mode.UPDATE);
|
||||||
|
}
|
||||||
|
if (params.getFlags().contains("debug") || params.getFlags().contains("d")) {
|
||||||
|
thread.setDebug(true);
|
||||||
|
}
|
||||||
|
thread.start();
|
||||||
|
context.response(L("command.blockstate.migrate_started", source.getType(), target.getType()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private String L(String msg, Object... args) {
|
private String L(String msg, Object... args) {
|
||||||
return mod.getPlugin().getLocale().trans(msg, args);
|
return mod.getPlugin().getLocale().trans(msg, args);
|
||||||
|
|
|
@ -10,23 +10,24 @@ import java.util.List;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
import de.jaschastarke.bukkit.lib.database.ResultIterator;
|
||||||
import de.jaschastarke.database.Type;
|
import de.jaschastarke.database.Type;
|
||||||
import de.jaschastarke.database.db.Database;
|
import de.jaschastarke.database.db.Database;
|
||||||
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
|
|
||||||
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source;
|
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source;
|
||||||
|
import de.jaschastarke.utils.IDebugLogHolder;
|
||||||
|
|
||||||
public class DBQueries {
|
public class DBQueries {
|
||||||
private Database db;
|
private Database db;
|
||||||
private ModBlockStates mod;
|
private IDebugLogHolder dbg;
|
||||||
public DBQueries(ModBlockStates mod, Database db) {
|
public DBQueries(IDebugLogHolder mod, Database db) {
|
||||||
this.mod = mod;
|
this.dbg = mod;
|
||||||
this.db = db;
|
this.db = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PreparedStatement find = null;
|
private PreparedStatement find = null;
|
||||||
public BlockState find(Location loc) throws SQLException {
|
public BlockState find(Location loc) throws SQLException {
|
||||||
if (mod.isDebug())
|
if (dbg.isDebug())
|
||||||
mod.getLog().debug("DBQuery: find: " + loc.toString());
|
dbg.getLog().debug("DBQuery: find: " + loc.toString());
|
||||||
if (find == null) {
|
if (find == null) {
|
||||||
find = db.prepare("SELECT * FROM lc_block_state WHERE x = ? AND y = ? AND z = ? AND world = ?");
|
find = db.prepare("SELECT * FROM lc_block_state WHERE x = ? AND y = ? AND z = ? AND world = ?");
|
||||||
}
|
}
|
||||||
|
@ -42,15 +43,17 @@ public class DBQueries {
|
||||||
bs.setGameMode(getGameMode(rs));
|
bs.setGameMode(getGameMode(rs));
|
||||||
bs.setPlayerName(rs.getString("player"));
|
bs.setPlayerName(rs.getString("player"));
|
||||||
bs.setSource(getSource(rs));
|
bs.setSource(getSource(rs));
|
||||||
|
rs.close();
|
||||||
return bs;
|
return bs;
|
||||||
}
|
}
|
||||||
|
rs.close();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PreparedStatement findall = null;
|
private PreparedStatement findall = null;
|
||||||
public List<BlockState> findAllIn(DBModel.Cuboid c) throws SQLException {
|
public List<BlockState> findAllIn(DBModel.Cuboid c) throws SQLException {
|
||||||
if (mod.isDebug())
|
if (dbg.isDebug())
|
||||||
mod.getLog().debug("DBQuery: findAllIn: " + c.toString());
|
dbg.getLog().debug("DBQuery: findAllIn: " + c.toString());
|
||||||
List<BlockState> blocks = new ArrayList<BlockState>();
|
List<BlockState> blocks = new ArrayList<BlockState>();
|
||||||
if (findall == null) {
|
if (findall == null) {
|
||||||
findall = db.prepare("SELECT * FROM lc_block_state WHERE x >= ? AND x <= ? AND y >= ? AND y <= ? AND z >= ? AND z <= ? AND world = ?");
|
findall = db.prepare("SELECT * FROM lc_block_state WHERE x >= ? AND x <= ? AND y >= ? AND y <= ? AND z >= ? AND z <= ? AND world = ?");
|
||||||
|
@ -72,16 +75,44 @@ public class DBQueries {
|
||||||
bs.setSource(getSource(rs));
|
bs.setSource(getSource(rs));
|
||||||
blocks.add(bs);
|
blocks.add(bs);
|
||||||
}
|
}
|
||||||
|
rs.close();
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
public Iterable<BlockState> iterateAllIn(final DBModel.Cuboid c) throws SQLException {
|
||||||
|
if (dbg.isDebug())
|
||||||
|
dbg.getLog().debug("DBQuery: iterateAllIn: " + c.toString());
|
||||||
|
if (findall == null) {
|
||||||
|
findall = db.prepare("SELECT * FROM lc_block_state WHERE x >= ? AND x <= ? AND y >= ? AND y <= ? AND z >= ? AND z <= ? AND world = ?");
|
||||||
|
}
|
||||||
|
findall.setInt(1, c.getMinX());
|
||||||
|
findall.setInt(2, c.getMaxX());
|
||||||
|
findall.setInt(3, c.getMinY());
|
||||||
|
findall.setInt(4, c.getMaxY());
|
||||||
|
findall.setInt(5, c.getMinZ());
|
||||||
|
findall.setInt(6, c.getMaxZ());
|
||||||
|
findall.setString(7, c.getWorld().getUID().toString());
|
||||||
|
ResultSet rs = findall.executeQuery();
|
||||||
|
return new ResultIterator<BlockState>(rs) {
|
||||||
|
@Override
|
||||||
|
protected BlockState fetch(ResultSet rs) throws SQLException {
|
||||||
|
BlockState bs = new BlockState();
|
||||||
|
bs.setLocation(new Location(c.getWorld(), rs.getInt("x"), rs.getInt("y"), rs.getInt("z")));
|
||||||
|
bs.setDate(rs.getTimestamp("cdate"));
|
||||||
|
bs.setGameMode(getGameMode(rs));
|
||||||
|
bs.setPlayerName(rs.getString("player"));
|
||||||
|
bs.setSource(getSource(rs));
|
||||||
|
return bs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private PreparedStatement delete = null;
|
private PreparedStatement delete = null;
|
||||||
public boolean delete(BlockState s) throws SQLException {
|
public boolean delete(BlockState s) throws SQLException {
|
||||||
return delete(s.getLocation());
|
return delete(s.getLocation());
|
||||||
}
|
}
|
||||||
public boolean delete(Location loc) throws SQLException {
|
public boolean delete(Location loc) throws SQLException {
|
||||||
if (mod.isDebug())
|
if (dbg.isDebug())
|
||||||
mod.getLog().debug("DBQuery: delete: " + loc.toString());
|
dbg.getLog().debug("DBQuery: delete: " + loc.toString());
|
||||||
if (delete == null) {
|
if (delete == null) {
|
||||||
delete = db.prepare("DELETE FROM lc_block_state WHERE x = ? AND y = ? AND z = ? AND world = ?");
|
delete = db.prepare("DELETE FROM lc_block_state WHERE x = ? AND y = ? AND z = ? AND world = ?");
|
||||||
}
|
}
|
||||||
|
@ -94,8 +125,8 @@ public class DBQueries {
|
||||||
|
|
||||||
private PreparedStatement update = null;
|
private PreparedStatement update = null;
|
||||||
public boolean update(BlockState s) throws SQLException {
|
public boolean update(BlockState s) throws SQLException {
|
||||||
if (mod.isDebug())
|
if (dbg.isDebug())
|
||||||
mod.getLog().debug("DBQuery: update: " + s.toString());
|
dbg.getLog().debug("DBQuery: update: " + s.toString());
|
||||||
if (update == null) {
|
if (update == null) {
|
||||||
update = db.prepare("UPDATE lc_block_state SET gm = ?, player = ?, cdate = ?, source = ?"+
|
update = db.prepare("UPDATE lc_block_state SET gm = ?, player = ?, cdate = ?, source = ?"+
|
||||||
"WHERE x = ? AND y = ? AND z = ? AND world = ? ");
|
"WHERE x = ? AND y = ? AND z = ? AND world = ? ");
|
||||||
|
@ -128,8 +159,8 @@ public class DBQueries {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean move(Location oldLoc, Location newLoc) throws SQLException {
|
public boolean move(Location oldLoc, Location newLoc) throws SQLException {
|
||||||
if (mod.isDebug())
|
if (dbg.isDebug())
|
||||||
mod.getLog().debug("DBQuery: move: " + oldLoc.toString() + ", " + newLoc.toString());
|
dbg.getLog().debug("DBQuery: move: " + oldLoc.toString() + ", " + newLoc.toString());
|
||||||
if (move == null) {
|
if (move == null) {
|
||||||
move = db.prepare("UPDATE lc_block_state SET x = ?, y = ?, z = ? "+
|
move = db.prepare("UPDATE lc_block_state SET x = ?, y = ?, z = ? "+
|
||||||
"WHERE x = ? AND y = ? AND z = ? AND world = ?");
|
"WHERE x = ? AND y = ? AND z = ? AND world = ?");
|
||||||
|
@ -156,8 +187,8 @@ public class DBQueries {
|
||||||
}*/
|
}*/
|
||||||
private PreparedStatement insert = null;
|
private PreparedStatement insert = null;
|
||||||
public boolean insert(BlockState s) throws SQLException {
|
public boolean insert(BlockState s) throws SQLException {
|
||||||
if (mod.isDebug())
|
if (dbg.isDebug())
|
||||||
mod.getLog().debug("DBQuery: insert: " + s.toString());
|
dbg.getLog().debug("DBQuery: insert: " + s.toString());
|
||||||
if (insert == null) {
|
if (insert == null) {
|
||||||
insert = db.prepare("INSERT INTO lc_block_state (x, y, z, world, gm, player, cdate, source)"+
|
insert = db.prepare("INSERT INTO lc_block_state (x, y, z, world, gm, player, cdate, source)"+
|
||||||
" VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
" VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||||
|
@ -220,8 +251,8 @@ public class DBQueries {
|
||||||
switch (db.getType()) {
|
switch (db.getType()) {
|
||||||
case SQLite:
|
case SQLite:
|
||||||
if (!db.getDDL().tableExists("lc_block_state")) {
|
if (!db.getDDL().tableExists("lc_block_state")) {
|
||||||
if (mod.isDebug())
|
if (dbg.isDebug())
|
||||||
mod.getLog().debug("DBQuery: initTable SQLite: lc_block_state");
|
dbg.getLog().debug("DBQuery: initTable SQLite: lc_block_state");
|
||||||
db.execute(
|
db.execute(
|
||||||
"CREATE TABLE lc_block_state ("+
|
"CREATE TABLE lc_block_state ("+
|
||||||
"x integer,"+
|
"x integer,"+
|
||||||
|
@ -236,14 +267,14 @@ public class DBQueries {
|
||||||
"constraint ck_lc_block_state_gm check (gm in (0,1,2)),"+
|
"constraint ck_lc_block_state_gm check (gm in (0,1,2)),"+
|
||||||
"constraint ck_lc_block_state_source check (source in (0,1,2,3,4))"+
|
"constraint ck_lc_block_state_source check (source in (0,1,2,3,4))"+
|
||||||
")"
|
")"
|
||||||
);
|
).close();
|
||||||
db.getLogger().info("Created SQLite-Table: lc_block_state");
|
db.getLogger().info("Created SQLite-Table: lc_block_state");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MySQL:
|
case MySQL:
|
||||||
if (!db.getDDL().tableExists("lc_block_state")) {
|
if (!db.getDDL().tableExists("lc_block_state")) {
|
||||||
if (mod.isDebug())
|
if (dbg.isDebug())
|
||||||
mod.getLog().debug("DBQuery: initTable MySQL: lc_block_state");
|
dbg.getLog().debug("DBQuery: initTable MySQL: lc_block_state");
|
||||||
db.execute(
|
db.execute(
|
||||||
"CREATE TABLE IF NOT EXISTS lc_block_state ("+
|
"CREATE TABLE IF NOT EXISTS lc_block_state ("+
|
||||||
"x INT NOT NULL,"+
|
"x INT NOT NULL,"+
|
||||||
|
@ -256,7 +287,7 @@ public class DBQueries {
|
||||||
"source ENUM('SEED','PLAYER','EDIT','COMMAND','UNKNOWN') NOT NULL,"+
|
"source ENUM('SEED','PLAYER','EDIT','COMMAND','UNKNOWN') NOT NULL,"+
|
||||||
"PRIMARY KEY (x, y, z, world)"+
|
"PRIMARY KEY (x, y, z, world)"+
|
||||||
")"
|
")"
|
||||||
);
|
).close();
|
||||||
db.getLogger().info("Created MySQL-Table: lc_block_state");
|
db.getLogger().info("Created MySQL-Table: lc_block_state");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
package de.jaschastarke.minecraft.limitedcreative.blockstate;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import de.jaschastarke.bukkit.lib.chat.ChatFormattings;
|
||||||
|
import de.jaschastarke.bukkit.lib.commands.CommandContext;
|
||||||
|
import de.jaschastarke.database.db.Database;
|
||||||
|
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
|
||||||
|
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.Cuboid;
|
||||||
|
import de.jaschastarke.utils.IDebugLogHolder;
|
||||||
|
import de.jaschastarke.utils.ISimpleLogger;
|
||||||
|
|
||||||
|
public class DatabaseMigrationThread extends Thread implements IDebugLogHolder {
|
||||||
|
private static final int CHUNK_SIZE = 512;
|
||||||
|
private ModBlockStates mod;
|
||||||
|
private CommandContext context;
|
||||||
|
private Database source;
|
||||||
|
private Database target;
|
||||||
|
private Mode mode = Mode.REPLACE;
|
||||||
|
private boolean debug = false;
|
||||||
|
|
||||||
|
public static enum Mode {
|
||||||
|
REPLACE,
|
||||||
|
UPDATE
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseMigrationThread(ModBlockStates mod, CommandContext context, Database source, Database target) {
|
||||||
|
this.mod = mod;
|
||||||
|
this.context = context;
|
||||||
|
this.source = source;
|
||||||
|
this.target = target;
|
||||||
|
setName("LC BlockState Database-Migration");
|
||||||
|
setPriority(MIN_PRIORITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mode getMode() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
public void setMode(Mode mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
}
|
||||||
|
public void setDebug(boolean debug) {
|
||||||
|
this.debug = debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDebug() {
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ISimpleLogger getLog() {
|
||||||
|
return mod.getLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
if (!target.isInTransaction())
|
||||||
|
target.startTransaction();
|
||||||
|
|
||||||
|
int rowCount = 0;
|
||||||
|
Connection sourceConnection = source.getConnection();
|
||||||
|
Connection targetConnection = target.getConnection();
|
||||||
|
|
||||||
|
if (mode == Mode.REPLACE) {
|
||||||
|
targetConnection.createStatement().execute("DELETE FROM lc_block_state");
|
||||||
|
}
|
||||||
|
|
||||||
|
DBQueries sourceDB = new DBQueries(this, source);
|
||||||
|
DBQueries targetDB = new DBQueries(this, target);
|
||||||
|
|
||||||
|
List<WorldSize> worldBounds = new ArrayList<WorldSize>();
|
||||||
|
ResultSet fetchBounds = sourceConnection.createStatement().executeQuery("SELECT world, MIN(x), MIN(z), MAX(x), MAX(z) FROM lc_block_state GROUP BY world");
|
||||||
|
while (fetchBounds.next()) {
|
||||||
|
worldBounds.add(new WorldSize(fetchBounds.getString("world"),
|
||||||
|
fetchBounds.getInt(2),
|
||||||
|
fetchBounds.getInt(3),
|
||||||
|
fetchBounds.getInt(4),
|
||||||
|
fetchBounds.getInt(5)));
|
||||||
|
}
|
||||||
|
fetchBounds.close();
|
||||||
|
|
||||||
|
for (WorldSize bounds : worldBounds) {
|
||||||
|
World world = mod.getPlugin().getServer().getWorld(bounds.getWorld());
|
||||||
|
if (world != null) {
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
int itCount = 0;
|
||||||
|
if (mod.isDebug())
|
||||||
|
mod.getLog().debug("Processing world " + world.getName() + " with bounds: " + bounds);
|
||||||
|
|
||||||
|
for (int x = bounds.getMinX(); x <= bounds.getMaxX(); x += CHUNK_SIZE + 1) {
|
||||||
|
for (int z = bounds.getMinZ(); z <= bounds.getMaxZ(); z += CHUNK_SIZE + 1) {
|
||||||
|
Cuboid c = new Cuboid();
|
||||||
|
c.add(new Location(world, x, 0, z));
|
||||||
|
c.add(new Location(world, x + CHUNK_SIZE, world.getMaxHeight(), z + CHUNK_SIZE));
|
||||||
|
System.out.println("Fetching Cuboid: " + c.toString());
|
||||||
|
|
||||||
|
for (BlockState bs : sourceDB.iterateAllIn(c)) {
|
||||||
|
if (mode == Mode.UPDATE) {
|
||||||
|
BlockState xs = targetDB.find(bs.getLocation());
|
||||||
|
if (xs == null) {
|
||||||
|
targetDB.insert(bs);
|
||||||
|
} else if (xs.getDate().before(bs.getDate())) {
|
||||||
|
targetDB.update(bs);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
targetDB.insert(bs);
|
||||||
|
}
|
||||||
|
rowCount++;
|
||||||
|
itCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String region = "Region{world = " + world.getName() + ", x = [" + bounds.getMinX() + "; " + (bounds.getMinX() + CHUNK_SIZE) + "], z = [" + bounds.getMinZ() + "; " + (bounds.getMinZ() + CHUNK_SIZE) + "]}";
|
||||||
|
mod.getLog().info("Migration processed " + itCount + " BlockStates in " + region + " within " + ((System.currentTimeMillis() - time) / 1000.0) + " seconds");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target.endTransaction();
|
||||||
|
context.responseFormatted(ChatFormattings.SUCCESS, L("command.blockstate.migration_finished", rowCount) + " " +
|
||||||
|
context.getFormatter().formatString(ChatFormattings.ERROR, L("command.blockstate.migration_finished_restart")));
|
||||||
|
} catch (SQLException e) {
|
||||||
|
try {
|
||||||
|
target.revertTransaction();
|
||||||
|
} catch (SQLException e1) {}
|
||||||
|
context.responseFormatted(ChatFormattings.ERROR, L("command.blockstate.migration_error", e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String L(String msg, Object... args) {
|
||||||
|
return mod.getPlugin().getLocale().trans(msg, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class WorldSize {
|
||||||
|
UUID w;
|
||||||
|
int minX, minZ, maxX, maxZ;
|
||||||
|
|
||||||
|
public WorldSize(String w, int minX, int minZ, int maxX, int maxZ) {
|
||||||
|
this.w = UUID.fromString(w);
|
||||||
|
this.minX = minX;
|
||||||
|
this.minZ = minZ;
|
||||||
|
this.maxX = maxX;
|
||||||
|
this.maxZ = maxZ;
|
||||||
|
}
|
||||||
|
public String toString() {
|
||||||
|
World world = Bukkit.getServer().getWorld(w);
|
||||||
|
String wn = world == null ? w.toString() : world.getName();
|
||||||
|
return getClass().getSimpleName() + "{world = " + wn + ", minX = " + minX + ", minZ = " + minZ + ", maxX = " + maxX + ", maxZ = " + maxZ + "}";
|
||||||
|
}
|
||||||
|
public UUID getWorld() {
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
public int getMinX() {
|
||||||
|
return minX;
|
||||||
|
}
|
||||||
|
public int getMinZ() {
|
||||||
|
return minZ;
|
||||||
|
}
|
||||||
|
public int getMaxX() {
|
||||||
|
return maxX;
|
||||||
|
}
|
||||||
|
public int getMaxZ() {
|
||||||
|
return maxZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ import de.jaschastarke.minecraft.limitedcreative.ModRegions;
|
||||||
import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.FlagList;
|
import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.FlagList;
|
||||||
import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.FlagValue;
|
import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.FlagValue;
|
||||||
import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.Region;
|
import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.Region;
|
||||||
|
import de.jaschastarke.modularize.ModuleEntry.ModuleState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LimitedCreative-Region-Command: configure creative regions
|
* LimitedCreative-Region-Command: configure creative regions
|
||||||
|
@ -48,7 +49,8 @@ public class RegionsCommand extends BukkitCommand implements IHelpDescribed {
|
||||||
this.help = this.getDefaultHelpCommand();
|
this.help = this.getDefaultHelpCommand();
|
||||||
}
|
}
|
||||||
public RegionsCommand(ModRegions mod) {
|
public RegionsCommand(ModRegions mod) {
|
||||||
this();
|
super(mod.getPlugin());
|
||||||
|
this.help = this.getDefaultHelpCommand();
|
||||||
this.mod = mod;
|
this.mod = mod;
|
||||||
this.wg = (WorldGuardPlugin) mod.getPlugin().getServer().getPluginManager().getPlugin(WorldGuardIntegration.PLUGIN_NAME);
|
this.wg = (WorldGuardPlugin) mod.getPlugin().getServer().getPluginManager().getPlugin(WorldGuardIntegration.PLUGIN_NAME);
|
||||||
}
|
}
|
||||||
|
@ -62,6 +64,12 @@ public class RegionsCommand extends BukkitCommand implements IHelpDescribed {
|
||||||
public String[] getAliases() {
|
public String[] getAliases() {
|
||||||
return new String[]{"/region"};
|
return new String[]{"/region"};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean execute(final CommandContext context, final String[] args) throws MissingPermissionCommandException, CommandException {
|
||||||
|
if (mod.getModuleEntry().getState() != ModuleState.ENABLED)
|
||||||
|
throw new CommandException("Module " + mod.getName() + " is disabled");
|
||||||
|
return super.execute(context, args);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal has no effect, as not tested by any command handler
|
* @internal has no effect, as not tested by any command handler
|
||||||
|
|
|
@ -30,6 +30,13 @@ command.blockstate.requires_worldedit: This command requires WorldEdit-Plugin
|
||||||
command.blockstate.worledit_selection_empty: Select a region with WorldEdit first
|
command.blockstate.worledit_selection_empty: Select a region with WorldEdit first
|
||||||
command.blockstate.command_updated: Successfully updated {0} blocks.
|
command.blockstate.command_updated: Successfully updated {0} blocks.
|
||||||
command.blockstate.command_failed: Failed to update blocks. See server.log for details.
|
command.blockstate.command_failed: Failed to update blocks. See server.log for details.
|
||||||
|
command.blockstate.migrate_started: Database migration from {0} to {1} started...
|
||||||
|
command.blockstate.migrate_connect_error: Connection to database failed with error: {0}
|
||||||
|
command.blockstate.migration_finished: Database migration of {0} records successful.
|
||||||
|
command.blockstate.migration_finished_restart: A Server-Restart is required!
|
||||||
|
command.blockstate.migration_error: Migration failed with error: {0}
|
||||||
|
command.blockstate.migrate_useronline_error: There are players on the Server. The migration shouldn't be run with active players.
|
||||||
|
command.blockstate.migrate_confirm: Are you sure you want to start the Migration? It may take a very long time and much CPU. To confirm execution run the command with the following added: {0}
|
||||||
|
|
||||||
cmdblock.blocked: This command is blocked while in creative mode.
|
cmdblock.blocked: This command is blocked while in creative mode.
|
||||||
cmdblock.blocked.requires_worldedit: WorlEdit is required to use this command
|
cmdblock.blocked.requires_worldedit: WorlEdit is required to use this command
|
||||||
|
|
Loading…
Reference in a new issue