Don't resave cells on stopping creation, fixes #74

We was saving everything again when the players stop creating anything,
this was causing issues with duplicate cells when using any storage with
SQL (due to insert and no primary key).

Also, added a hasChanged to the cell class which will prevent resaving
things in sql if it hasn't changed.
This commit is contained in:
graywolf336 2015-05-26 14:57:38 -05:00
parent fd52be6972
commit 12f35a01bf
7 changed files with 75 additions and 12 deletions

View File

@ -449,8 +449,16 @@ public class JailIO {
c.addSign(new SimpleLocation(co[0], co[1], co[2], co[3])); c.addSign(new SimpleLocation(co[0], co[1], co[2], co[3]));
} }
} }
//Since we're loading the data, the cell hasn't officially changed
c.setChanged(false);
j.addCell(c, false); //Try to add the cell to the jail, if one
if(!j.addCell(c, false)) {
int id = set.getInt("cellid");
cellsToRemove.add(id);
pl.debug("The cell, " + c.getName() + " (" + id + "), is already in jail " + j.getName() + " so we're removing it.");
}
}else { }else {
pl.getLogger().warning("The cell, " + set.getString("name") + ", in " + j.getName() + " is located in a world that is not loaded."); pl.getLogger().warning("The cell, " + set.getString("name") + ", in " + j.getName() + " is located in a world that is not loaded.");
} }
@ -471,24 +479,24 @@ public class JailIO {
//Remove the invalid prisoners //Remove the invalid prisoners
if(cellsToRemove.size() != 0) { if(cellsToRemove.size() != 0) {
String names = ""; StringBuilder ids = new StringBuilder();
for(int c : cellsToRemove) { for(int c : cellsToRemove) {
if(names.isEmpty()) names = "'" + c + "'"; if(ids.length() == 0) ids.append("'" + c + "'");
else names += "," + "'" + c + "'"; else ids.append("," + "'" + c + "'");
} }
try { try {
PreparedStatement cds = getConnection().prepareStatement("delete from " + prefix + "cells where cellid in (" + names + ");"); PreparedStatement cds = getConnection().prepareStatement("delete from " + prefix + "cells where cellid in (" + ids.toString() + ");");
pl.debug("Deleting old cells: 'delete from " + prefix + "cells where cellid in (" + names + ");'"); pl.debug("Deleting old cells: `delete from " + prefix + "cells where cellid in (" + ids.toString() + ");`");
int count = cds.executeUpdate(); int count = cds.executeUpdate();
pl.getLogger().info("Deleted " + count + " old cells which referenced a jail no longer valid: " + names); pl.getLogger().info("Deleted " + count + " cells which were invalid, they either referenced a jail which are no longer valid or were duplicates.");
cds.close(); cds.close();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
pl.getLogger().severe("---------- Jail Error!!! ----------"); pl.getLogger().severe("---------- Jail Error!!! ----------");
pl.getLogger().severe("Error while deleting the old cells which don't have a valid jail, please check the error and fix what is wrong."); pl.getLogger().severe("Error while deleting the old cells which were invalid (they either referenced a jail which are no longer valid or were duplicates), please check the error and fix what is wrong.");
} }
} }
@ -521,6 +529,7 @@ public class JailIO {
j.addPrisoner(p); j.addPrisoner(p);
}else if(c != null) { }else if(c != null) {
c.setPrisoner(p); c.setPrisoner(p);
c.setChanged(false);
}else { }else {
//the prisoner is assigned to a cell which doesn't exist, so just put them into the jail //the prisoner is assigned to a cell which doesn't exist, so just put them into the jail
j.addPrisoner(p); j.addPrisoner(p);
@ -664,6 +673,7 @@ public class JailIO {
c.setPrisoner(p); c.setPrisoner(p);
} }
c.setChanged(false);
j.addCell(c, false); j.addCell(c, false);
} }
} }
@ -904,6 +914,8 @@ public class JailIO {
if(p.getPreviousGameMode() != null) if(p.getPreviousGameMode() != null)
flat.set(cNode + "prisoner.previousGameMode", p.getPreviousGameMode().toString()); flat.set(cNode + "prisoner.previousGameMode", p.getPreviousGameMode().toString());
} }
c.setChanged(false);
} }
//Null all the prisoners out before we save them again, this way no prisoners are left behind //Null all the prisoners out before we save them again, this way no prisoners are left behind
@ -939,10 +951,14 @@ public class JailIO {
} }
public void saveCell(Jail j, Cell c) { public void saveCell(Jail j, Cell c) {
//if the cell hasn't changed, no need to save it again
if(!c.hasChanged()) return;
switch(storage) { switch(storage) {
case 1: case 1:
case 2: case 2:
try { try {
pl.debug("Saving the cell " + c.getName());
PreparedStatement cPS = getConnection().prepareStatement("INSERT INTO `" + prefix + "cells` (`name`, `jail`, `tp.x`, `tp.y`, `tp.z`, `tp.yaw`," PreparedStatement cPS = getConnection().prepareStatement("INSERT INTO `" + prefix + "cells` (`name`, `jail`, `tp.x`, `tp.y`, `tp.z`, `tp.yaw`,"
+ "`tp.pitch`, `chest.x`, `chest.y`, `chest.z`, `signs`) VALUES (?,?,?,?,?,?,?,?,?,?,?)"); + "`tp.pitch`, `chest.x`, `chest.y`, `chest.z`, `signs`) VALUES (?,?,?,?,?,?,?,?,?,?,?)");
@ -1002,6 +1018,8 @@ public class JailIO {
this.saveJail(j); this.saveJail(j);
break; break;
} }
c.setChanged(false);
} }
/** /**

View File

@ -71,4 +71,12 @@ public class AnyCell implements ICell {
public boolean hasChest() { public boolean hasChest() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public boolean setChanged(boolean changed) {
throw new UnsupportedOperationException();
}
public boolean hasChanged() {
throw new UnsupportedOperationException();
}
} }

View File

@ -20,6 +20,7 @@ public class Cell implements ICell {
private Prisoner p; private Prisoner p;
private HashSet<SimpleLocation> signs; private HashSet<SimpleLocation> signs;
private SimpleLocation teleport, chest; private SimpleLocation teleport, chest;
private boolean changed;
/** Creates a new Cell with the given name /** Creates a new Cell with the given name
* *
@ -28,6 +29,7 @@ public class Cell implements ICell {
public Cell(String name) { public Cell(String name) {
this.name = name; this.name = name;
this.signs = new HashSet<SimpleLocation>(); this.signs = new HashSet<SimpleLocation>();
this.changed = false;
} }
public String getName() { public String getName() {
@ -36,6 +38,7 @@ public class Cell implements ICell {
public void setPrisoner(Prisoner prisoner) { public void setPrisoner(Prisoner prisoner) {
this.p = prisoner; this.p = prisoner;
this.changed = true;
} }
public Prisoner getPrisoner() { public Prisoner getPrisoner() {
@ -44,6 +47,7 @@ public class Cell implements ICell {
public void removePrisoner() { public void removePrisoner() {
this.p = null; this.p = null;
this.changed = true;
} }
public boolean hasPrisoner() { public boolean hasPrisoner() {
@ -52,10 +56,12 @@ public class Cell implements ICell {
public void addAllSigns(HashSet<SimpleLocation> signs) { public void addAllSigns(HashSet<SimpleLocation> signs) {
this.signs.addAll(signs); this.signs.addAll(signs);
this.changed = true;
} }
public void addSign(SimpleLocation sign) { public void addSign(SimpleLocation sign) {
this.signs.add(sign); this.signs.add(sign);
this.changed = true;
} }
public HashSet<SimpleLocation> getSigns() { public HashSet<SimpleLocation> getSigns() {
@ -82,6 +88,7 @@ public class Cell implements ICell {
public void setTeleport(SimpleLocation location) { public void setTeleport(SimpleLocation location) {
this.teleport = location; this.teleport = location;
this.changed = true;
} }
public Location getTeleport() { public Location getTeleport() {
@ -90,6 +97,7 @@ public class Cell implements ICell {
public void setChestLocation(SimpleLocation simpleLocation) { public void setChestLocation(SimpleLocation simpleLocation) {
this.chest = simpleLocation; this.chest = simpleLocation;
this.changed = true;
} }
public Location getChestLocation() { public Location getChestLocation() {
@ -115,4 +123,12 @@ public class Cell implements ICell {
}else }else
return false; return false;
} }
public boolean setChanged(boolean changed) {
return this.changed = changed;
}
public boolean hasChanged() {
return this.changed;
}
} }

View File

@ -160,9 +160,13 @@ public class Jail {
} }
/** Adds a cell to the Jail. */ /** Adds a cell to the Jail. */
public void addCell(Cell cell, boolean save) { public boolean addCell(Cell cell, boolean save) {
if(save) plugin.getJailIO().saveCell(this, cell); if(save) plugin.getJailIO().saveCell(this, cell);
this.cells.put(cell.getName(), cell);
//Check if it already exists or not
if(this.cells.containsKey(cell.getName())) return false;
else this.cells.put(cell.getName(), cell);
return true;
} }
/** Gets the cell with the given name. */ /** Gets the cell with the given name. */

View File

@ -71,4 +71,12 @@ public class NoCell implements ICell {
public boolean hasChest() { public boolean hasChest() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public boolean setChanged(boolean changed) {
throw new UnsupportedOperationException();
}
public boolean hasChanged() {
throw new UnsupportedOperationException();
}
} }

View File

@ -33,8 +33,6 @@ public class JailStopCommand implements Command {
if(nothing) { if(nothing) {
sender.sendMessage(ChatColor.RED + "You've stopped creating....nothing."); sender.sendMessage(ChatColor.RED + "You've stopped creating....nothing.");
}else {
jm.getPlugin().getJailIO().saveEverything();
} }
return true; return true;

View File

@ -68,4 +68,15 @@ public interface ICell {
* @return true if there is a chest, false if there isn't. * @return true if there is a chest, false if there isn't.
*/ */
public boolean hasChest(); public boolean hasChest();
/**
* Sets whether this cell has been changed or not.
*
* @param changed true if we've changed it, mostly use if you want to force an update
* @return the resulting change, whether it is changed or not
*/
public boolean setChanged(boolean changed);
/** Gets whether the Cell has changed from the last save or not. */
public boolean hasChanged();
} }