This commit is contained in:
Jesse Boyd 2017-03-17 16:40:29 +11:00
parent 478ad9670b
commit a628c5927f
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
9 changed files with 622 additions and 304 deletions

View File

@ -28,6 +28,8 @@ import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RegionWrapper; import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.object.RunnableVal; import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.object.StringWrapper; import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.object.worlds.DefaultPlotAreaManager;
import com.intellectualcrafters.plot.object.worlds.PlotAreaManager;
import com.intellectualcrafters.plot.util.AbstractTitle; import com.intellectualcrafters.plot.util.AbstractTitle;
import com.intellectualcrafters.plot.util.ChatManager; import com.intellectualcrafters.plot.util.ChatManager;
import com.intellectualcrafters.plot.util.ChunkManager; import com.intellectualcrafters.plot.util.ChunkManager;
@ -44,7 +46,6 @@ import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler; import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.WorldUtil; import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.util.area.QuadMap;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue; import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.intellectualcrafters.plot.util.expiry.ExpireManager; import com.intellectualcrafters.plot.util.expiry.ExpireManager;
import com.intellectualcrafters.plot.util.expiry.ExpiryTask; import com.intellectualcrafters.plot.util.expiry.ExpiryTask;
@ -114,15 +115,8 @@ public class PS {
// Temporary hold the plots/clusters before the worlds load // Temporary hold the plots/clusters before the worlds load
public HashMap<String, Set<PlotCluster>> clusters_tmp; public HashMap<String, Set<PlotCluster>> clusters_tmp;
public HashMap<String, HashMap<PlotId, Plot>> plots_tmp; public HashMap<String, HashMap<PlotId, Plot>> plots_tmp;
// All plot areas
private PlotArea[] plotAreas = new PlotArea[0]; private PlotAreaManager manager;
// All plot areas mapped by world
private final HashMap<String, PlotArea[]> plotAreaMap = new HashMap<>();
// All plot areas mapped by position
private final HashMap<String, QuadMap<PlotArea>> plotAreaGrid = new HashMap<>();
// Optimization if there are no hash collisions
private boolean plotAreaHasCollision = false;
private final HashSet<Integer> plotAreaHashCheck = new HashSet<>();
/** /**
* Initialize PlotSquared with the desired Implementation class. * Initialize PlotSquared with the desired Implementation class.
@ -131,6 +125,7 @@ public class PS {
*/ */
public PS(IPlotMain iPlotMain, String platform) { public PS(IPlotMain iPlotMain, String platform) {
PS.instance = this; PS.instance = this;
this.manager = new DefaultPlotAreaManager();
this.thread = Thread.currentThread(); this.thread = Thread.currentThread();
this.IMP = iPlotMain; this.IMP = iPlotMain;
this.logger = iPlotMain; this.logger = iPlotMain;
@ -466,203 +461,6 @@ public class PS {
return this.platform; return this.platform;
} }
/**
* Get the relevant plot area for a specified location.
* <ul>
* <li>If there is only one plot area globally that will be returned.
* <li>If there is only one plot area in the world, it will return that.
* <li>If the plot area for a location cannot be unambiguously
* resolved, null will be returned.
* </ul>
* Note: An applicable plot area may not include the location i.e. clusters
* @param location the location
* @return
*/
public PlotArea getApplicablePlotArea(Location location) {
switch (this.plotAreas.length) {
case 0:
return null;
case 1:
return this.plotAreas[0];
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
String world = location.getWorld();
int hash = world.hashCode();
for (PlotArea area : this.plotAreas) {
if (hash == area.worldhash) {
if (area.contains(location.getX(), location.getZ()) && (!this.plotAreaHasCollision || world.equals(area.worldname))) {
return area;
}
}
}
return null;
default:
PlotArea[] areas = this.plotAreaMap.get(location.getWorld());
if (areas == null) {
return null;
}
int y;
int x;
switch (areas.length) {
case 1:
return areas[0];
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
x = location.getX();
y = location.getY();
for (PlotArea area : areas) {
if (area.contains(x, y)) {
return area;
}
}
return null;
default:
QuadMap<PlotArea> search = this.plotAreaGrid.get(location.getWorld());
return search.get(location.getX(), location.getZ());
}
}
}
public PlotArea getPlotArea(String world, String id) {
PlotArea[] areas = this.plotAreaMap.get(world);
if (areas == null) {
return null;
}
if (areas.length == 1) {
return areas[0];
} else if (id == null) {
return null;
}
for (PlotArea area : areas) {
if (StringMan.isEqual(id, area.id)) {
return area;
}
}
return null;
}
public PlotArea getPlotAreaAbs(String world, String id) {
PlotArea[] areas = this.plotAreaMap.get(world);
if (areas == null) {
return null;
}
for (PlotArea area : areas) {
if (StringMan.isEqual(id, area.id)) {
return area;
}
}
return null;
}
/**
* Get the {@code PlotArea} which contains a location.
* <ul>
* <li>If the plot area does not contain a location, null
* will be returned.
* </ul>
*
* @param location the location
* @return the {@link PlotArea} in the location, null if non existent
*/
public PlotArea getPlotAreaAbs(Location location) {
switch (this.plotAreas.length) {
case 0:
return null;
case 1:
PlotArea pa = this.plotAreas[0];
return pa.contains(location) ? pa : null;
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
String world = location.getWorld();
int hash = world.hashCode();
for (PlotArea area : this.plotAreas) {
if (hash == area.worldhash) {
if (area.contains(location.getX(), location.getZ()) && (!this.plotAreaHasCollision || world.equals(area.worldname))) {
return area;
}
}
}
return null;
default:
PlotArea[] areas = this.plotAreaMap.get(location.getWorld());
if (areas == null) {
return null;
}
int x;
int y;
switch (areas.length) {
case 0:
PlotArea a = areas[0];
return a.contains(location.getX(), location.getZ()) ? a : null;
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
x = location.getX();
y = location.getY();
for (PlotArea area : areas) {
if (area.contains(x, y)) {
return area;
}
}
return null;
default:
QuadMap<PlotArea> search = this.plotAreaGrid.get(location.getWorld());
return search.get(location.getX(), location.getZ());
}
}
}
public PlotArea getPlotAreaByString(String search) {
String[] split = search.split(";|,");
PlotArea[] areas = this.plotAreaMap.get(split[0]);
if (areas == null) {
for (PlotArea area : this.plotAreas) {
if (area.worldname.equalsIgnoreCase(split[0])) {
if (area.id == null || split.length == 2 && area.id.equalsIgnoreCase(split[1])) {
return area;
}
}
}
return null;
}
if (areas.length == 1) {
return areas[0];
} else if (split.length == 1) {
return null;
} else {
for (PlotArea area : areas) {
if (StringMan.isEqual(split[1], area.id)) {
return area;
}
}
return null;
}
}
public Set<PlotArea> getPlotAreas(String world, RegionWrapper region) {
QuadMap<PlotArea> areas = this.plotAreaGrid.get(world);
return areas != null ? areas.get(region) : new HashSet<PlotArea>();
}
public PlotManager getPlotManager(Plot plot) { public PlotManager getPlotManager(Plot plot) {
return plot.getArea().manager; return plot.getArea().manager;
} }
@ -720,23 +518,7 @@ public class PS {
cluster.setArea(plotArea); cluster.setArea(plotArea);
} }
} }
Set<PlotArea> localAreas = getPlotAreas(plotArea.worldname); manager.addPlotArea(plotArea);
Set<PlotArea> globalAreas = getPlotAreas();
localAreas.add(plotArea);
globalAreas.add(plotArea);
this.plotAreas = globalAreas.toArray(new PlotArea[globalAreas.size()]);
this.plotAreaMap.put(plotArea.worldname, localAreas.toArray(new PlotArea[localAreas.size()]));
QuadMap<PlotArea> map = this.plotAreaGrid.get(plotArea.worldname);
if (map == null) {
map = new QuadMap<PlotArea>(Integer.MAX_VALUE, 0, 0) {
@Override
public RegionWrapper getRegion(PlotArea value) {
return value.getRegion();
}
};
this.plotAreaGrid.put(plotArea.worldname, map);
}
map.add(plotArea);
plotArea.setupBorder(); plotArea.setupBorder();
} }
@ -746,16 +528,7 @@ public class PS {
* @param area the {@code PlotArea} to remove * @param area the {@code PlotArea} to remove
*/ */
public void removePlotArea(PlotArea area) { public void removePlotArea(PlotArea area) {
Set<PlotArea> areas = getPlotAreas(); manager.removePlotArea(area);
areas.remove(area);
this.plotAreas = areas.toArray(new PlotArea[areas.size()]);
if (areas.isEmpty()) {
this.plotAreaMap.remove(area.worldname);
this.plotAreaGrid.remove(area.worldname);
} else {
this.plotAreaMap.put(area.worldname, areas.toArray(new PlotArea[areas.size()]));
this.plotAreaGrid.get(area.worldname).remove(area);
}
setPlotsTmp(area); setPlotsTmp(area);
} }
@ -1027,11 +800,11 @@ public class PS {
HashMap<PlotArea, Collection<Plot>> map = new HashMap<>(); HashMap<PlotArea, Collection<Plot>> map = new HashMap<>();
int totalSize = getPlotCount(); int totalSize = getPlotCount();
if (plots.size() == totalSize) { if (plots.size() == totalSize) {
for (PlotArea area : this.plotAreas) { for (PlotArea area : manager.getAllPlotAreas()) {
map.put(area, area.getPlots()); map.put(area, area.getPlots());
} }
} else { } else {
for (PlotArea area : this.plotAreas) { for (PlotArea area : manager.getAllPlotAreas()) {
map.put(area, new ArrayList<Plot>(0)); map.put(area, new ArrayList<Plot>(0));
} }
Collection<Plot> lastList = null; Collection<Plot> lastList = null;
@ -1046,7 +819,7 @@ public class PS {
} }
} }
} }
List<PlotArea> areas = Arrays.asList(this.plotAreas); List<PlotArea> areas = Arrays.asList(manager.getAllPlotAreas());
Collections.sort(areas, new Comparator<PlotArea>() { Collections.sort(areas, new Comparator<PlotArea>() {
@Override @Override
public int compare(PlotArea a, PlotArea b) { public int compare(PlotArea a, PlotArea b) {
@ -1235,7 +1008,7 @@ public class PS {
*/ */
@Deprecated @Deprecated
public boolean isPlotWorld(String world) { public boolean isPlotWorld(String world) {
return this.plotAreaMap.containsKey(world); return hasPlotArea(world);
} }
/** /**
@ -1245,29 +1018,7 @@ public class PS {
* @return if a plot world is registered * @return if a plot world is registered
*/ */
public boolean hasPlotArea(String world) { public boolean hasPlotArea(String world) {
switch (this.plotAreas.length) { return manager.getPlotAreas(world, null).length != 0;
case 0:
return false;
case 1:
PlotArea a = this.plotAreas[0];
return world.hashCode() == a.worldhash && (!this.plotAreaHasCollision || a.worldname.equals(world));
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
int hash = world.hashCode();
for (PlotArea area : this.plotAreas) {
if (area.worldhash == hash && (!this.plotAreaHasCollision || area.worldname.equals(world))) {
return true;
}
}
return false;
default:
return this.plotAreaMap.containsKey(world);
}
} }
public Collection<Plot> getPlots(String world) { public Collection<Plot> getPlots(String world) {
@ -1397,9 +1148,7 @@ public class PS {
if (world.equals("CheckingPlotSquaredGenerator")) { if (world.equals("CheckingPlotSquaredGenerator")) {
return; return;
} }
if (!this.plotAreaHasCollision && !this.plotAreaHashCheck.add(world.hashCode())) { this.manager.addWorld(world);
this.plotAreaHasCollision = true;
}
Set<String> worlds; Set<String> worlds;
if (this.worlds.contains("worlds")) { if (this.worlds.contains("worlds")) {
worlds = this.worlds.getConfigurationSection("worlds").getKeys(false); worlds = this.worlds.getConfigurationSection("worlds").getKeys(false);
@ -1415,7 +1164,7 @@ public class PS {
type = 0; type = 0;
} }
if (type == 0) { if (type == 0) {
if (this.plotAreaMap.containsKey(world)) { if (manager.getPlotAreas(world, null).length != 0) {
debug("World possibly already loaded: " + world); debug("World possibly already loaded: " + world);
return; return;
} }
@ -1466,7 +1215,7 @@ public class PS {
} }
ConfigurationSection areasSection = worldSection.getConfigurationSection("areas"); ConfigurationSection areasSection = worldSection.getConfigurationSection("areas");
if (areasSection == null) { if (areasSection == null) {
if (this.plotAreaMap.containsKey(world)) { if (manager.getPlotAreas(world, null).length != 0) {
debug("World possibly already loaded: " + world); debug("World possibly already loaded: " + world);
return; return;
} }
@ -1547,7 +1296,8 @@ public class PS {
if (pos1 == null || pos2 == null || name.isEmpty()) { if (pos1 == null || pos2 == null || name.isEmpty()) {
throw new IllegalArgumentException("Invalid Area identifier: " + areaId + ". Expected form `<name>-<x1;z1>-<x2;z2>`"); throw new IllegalArgumentException("Invalid Area identifier: " + areaId + ". Expected form `<name>-<x1;z1>-<x2;z2>`");
} }
if (getPlotAreaAbs(world, name) != null) { PlotArea existing = getPlotArea(world, name);
if (existing != null && name.equals(existing.id)) {
continue; continue;
} }
ConfigurationSection section = areasSection.getConfigurationSection(areaId); ConfigurationSection section = areasSection.getConfigurationSection(areaId);
@ -1789,7 +1539,7 @@ public class PS {
private Map<String, Map<PlotId, Plot>> getPlotsRaw() { private Map<String, Map<PlotId, Plot>> getPlotsRaw() {
HashMap<String, Map<PlotId, Plot>> map = new HashMap<>(); HashMap<String, Map<PlotId, Plot>> map = new HashMap<>();
for (PlotArea area : this.plotAreas) { for (PlotArea area : this.manager.getAllPlotAreas()) {
Map<PlotId, Plot> map2 = map.get(area.toString()); Map<PlotId, Plot> map2 = map.get(area.toString());
if (map2 == null) { if (map2 == null) {
map.put(area.toString(), area.getPlotsRaw()); map.put(area.toString(), area.getPlotsRaw());
@ -2013,13 +1763,13 @@ public class PS {
} }
public void foreachPlotArea(RunnableVal<PlotArea> runnable) { public void foreachPlotArea(RunnableVal<PlotArea> runnable) {
for (PlotArea area : this.plotAreas) { for (PlotArea area : this.manager.getAllPlotAreas()) {
runnable.run(area); runnable.run(area);
} }
} }
public void foreachPlotArea(String world, RunnableVal<PlotArea> runnable) { public void foreachPlotArea(String world, RunnableVal<PlotArea> runnable) {
PlotArea[] array = this.plotAreaMap.get(world); PlotArea[] array = this.manager.getPlotAreas(world, null);
if (array == null) { if (array == null) {
return; return;
} }
@ -2029,7 +1779,7 @@ public class PS {
} }
public void foreachPlot(RunnableVal<Plot> runnable) { public void foreachPlot(RunnableVal<Plot> runnable) {
for (PlotArea area : this.plotAreas) { for (PlotArea area : this.manager.getAllPlotAreas()) {
for (Plot plot : area.getPlots()) { for (Plot plot : area.getPlots()) {
runnable.run(plot); runnable.run(plot);
} }
@ -2037,7 +1787,7 @@ public class PS {
} }
public void foreachPlotRaw(RunnableVal<Plot> runnable) { public void foreachPlotRaw(RunnableVal<Plot> runnable) {
for (PlotArea area : this.plotAreas) { for (PlotArea area : this.manager.getAllPlotAreas()) {
for (Plot plot : area.getPlots()) { for (Plot plot : area.getPlots()) {
runnable.run(plot); runnable.run(plot);
} }
@ -2052,30 +1802,31 @@ public class PS {
} }
public void foreachBasePlot(RunnableVal<Plot> run) { public void foreachBasePlot(RunnableVal<Plot> run) {
for (PlotArea area : this.plotAreas) { for (PlotArea area : this.manager.getAllPlotAreas()) {
area.foreachBasePlot(run); area.foreachBasePlot(run);
} }
} }
public PlotArea getFirstPlotArea() { public PlotArea getFirstPlotArea() {
return this.plotAreas.length > 0 ? this.plotAreas[0] : null; PlotArea[] areas = manager.getAllPlotAreas();
return areas.length > 0 ? areas[0] : null;
} }
public int getPlotAreaCount() { public int getPlotAreaCount() {
return this.plotAreas.length; return this.manager.getAllPlotAreas().length;
} }
public int getPlotCount() { public int getPlotCount() {
int count = 0; int count = 0;
for (PlotArea area : this.plotAreas) { for (PlotArea area : this.manager.getAllPlotAreas()) {
count += area.getPlotCount(); count += area.getPlotCount();
} }
return count; return count;
} }
public Set<PlotArea> getPlotAreas() { public Set<PlotArea> getPlotAreas() {
HashSet<PlotArea> set = new HashSet<>(this.plotAreas.length); HashSet<PlotArea> set = new HashSet<>();
Collections.addAll(set, this.plotAreas); Collections.addAll(set, manager.getAllPlotAreas());
return set; return set;
} }
@ -2085,15 +1836,17 @@ public class PS {
*/ */
@Deprecated @Deprecated
public Set<String> getPlotWorldStrings() { public Set<String> getPlotWorldStrings() {
HashSet<String> set = new HashSet<>(this.plotAreaMap.size()); HashSet<String> set = new HashSet<>(manager.getAllPlotAreas().length);
for (String entry : this.plotAreaMap.keySet()) { for (String world : manager.getAllWorlds()) {
set.add(entry); if (manager.getPlotAreas(world, null).length != 0) {
set.add(world);
}
} }
return set; return set;
} }
public boolean isAugmented(String world) { public boolean isAugmented(String world) {
PlotArea[] areas = this.plotAreaMap.get(world); PlotArea[] areas = manager.getPlotAreas(world, null);
if (areas == null) { if (areas == null) {
return false; return false;
} }
@ -2109,11 +1862,75 @@ public class PS {
* @return Collection of PlotArea objects * @return Collection of PlotArea objects
*/ */
public Set<PlotArea> getPlotAreas(String world) { public Set<PlotArea> getPlotAreas(String world) {
PlotArea[] areas = this.plotAreaMap.get(world); Set<PlotArea> set = new HashSet<>();
if (areas == null) { Collections.addAll(set, manager.getPlotAreas(world, null));
return new HashSet<>(0); return set;
} }
HashSet<PlotArea> set = new HashSet<>(areas.length);
/**
* Get the relevant plot area for a specified location.
* <ul>
* <li>If there is only one plot area globally that will be returned.
* <li>If there is only one plot area in the world, it will return that.
* <li>If the plot area for a location cannot be unambiguously
* resolved, null will be returned.
* </ul>
* Note: An applicable plot area may not include the location i.e. clusters
* @param location the location
* @return
*/
public PlotArea getApplicablePlotArea(Location location) {
return manager.getApplicablePlotArea(location);
}
public PlotArea getPlotArea(String world, String id) {
return manager.getPlotArea(world, id);
}
/**
* Get the {@code PlotArea} which contains a location.
* <ul>
* <li>If the plot area does not contain a location, null
* will be returned.
* </ul>
*
* @param location the location
* @return the {@link PlotArea} in the location, null if non existent
*/
public PlotArea getPlotAreaAbs(Location location) {
return manager.getPlotArea(location);
}
public PlotArea getPlotAreaByString(String search) {
String[] split = search.split(";|,");
PlotArea[] areas = manager.getPlotAreas(split[0], null);
if (areas == null) {
for (PlotArea area : manager.getAllPlotAreas()) {
if (area.worldname.equalsIgnoreCase(split[0])) {
if (area.id == null || split.length == 2 && area.id.equalsIgnoreCase(split[1])) {
return area;
}
}
}
return null;
}
if (areas.length == 1) {
return areas[0];
} else if (split.length == 1) {
return null;
} else {
for (PlotArea area : areas) {
if (StringMan.isEqual(split[1], area.id)) {
return area;
}
}
return null;
}
}
public Set<PlotArea> getPlotAreas(String world, RegionWrapper region) {
PlotArea[] areas = manager.getPlotAreas(world, region);
Set<PlotArea> set = new HashSet<>();
Collections.addAll(set, areas); Collections.addAll(set, areas);
return set; return set;
} }

View File

@ -1034,11 +1034,9 @@ public class SQLManager implements AbstractDB {
@Override @Override
public void createPlotAndSettings(final Plot plot, Runnable whenDone) { public void createPlotAndSettings(final Plot plot, Runnable whenDone) {
System.out.println("Create plot!");
addPlotTask(plot, new UniqueStatement("createPlotAndSettings_" + plot.hashCode()) { addPlotTask(plot, new UniqueStatement("createPlotAndSettings_" + plot.hashCode()) {
@Override @Override
public void set(PreparedStatement stmt) throws SQLException { public void set(PreparedStatement stmt) throws SQLException {
System.out.println("Set and run!");
stmt.setInt(1, plot.getId().x); stmt.setInt(1, plot.getId().x);
stmt.setInt(2, plot.getId().y); stmt.setInt(2, plot.getId().y);
stmt.setString(3, plot.owner.toString()); stmt.setString(3, plot.owner.toString());

View File

@ -0,0 +1,243 @@
package com.intellectualcrafters.plot.object.worlds;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.area.QuadMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class DefaultPlotAreaManager implements PlotAreaManager {
// All plot areas
private PlotArea[] plotAreas = new PlotArea[0];
// All plot areas mapped by world
private final HashMap<String, PlotArea[]> plotAreaMap = new HashMap<>();
// All plot areas mapped by position
private final HashMap<String, QuadMap<PlotArea>> plotAreaGrid = new HashMap<>();
// Optimization if there are no hash collisions
private boolean plotAreaHasCollision = false;
private final HashSet<Integer> plotAreaHashCheck = new HashSet<>();
private final PlotArea[] noPlotAreas = new PlotArea[0];
private String[] worlds = new String[0];
@Override
public PlotArea[] getAllPlotAreas() {
return plotAreas;
}
@Override
public PlotArea getApplicablePlotArea(Location location) {
switch (this.plotAreas.length) {
case 0:
return null;
case 1:
return this.plotAreas[0];
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
String world = location.getWorld();
int hash = world.hashCode();
for (PlotArea area : this.plotAreas) {
if (hash == area.worldhash) {
if (area.contains(location.getX(), location.getZ()) && (!this.plotAreaHasCollision || world.equals(area.worldname))) {
return area;
}
}
}
return null;
default:
PlotArea[] areas = this.plotAreaMap.get(location.getWorld());
if (areas == null) {
return null;
}
int y;
int x;
switch (areas.length) {
case 1:
return areas[0];
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
x = location.getX();
y = location.getY();
for (PlotArea area : areas) {
if (area.contains(x, y)) {
return area;
}
}
return null;
default:
QuadMap<PlotArea> search = this.plotAreaGrid.get(location.getWorld());
return search.get(location.getX(), location.getZ());
}
}
}
@Override
public void addPlotArea(PlotArea plotArea) {
HashSet<PlotArea> localAreas = new HashSet<>(Arrays.asList(getPlotAreas(plotArea.worldname, null)));
HashSet<PlotArea> globalAreas = new HashSet<>(Arrays.asList(plotAreas));
localAreas.add(plotArea);
globalAreas.add(plotArea);
this.plotAreas = globalAreas.toArray(new PlotArea[globalAreas.size()]);
this.plotAreaMap.put(plotArea.worldname, localAreas.toArray(new PlotArea[localAreas.size()]));
QuadMap<PlotArea> map = this.plotAreaGrid.get(plotArea.worldname);
if (map == null) {
map = new QuadMap<PlotArea>(Integer.MAX_VALUE, 0, 0) {
@Override
public RegionWrapper getRegion(PlotArea value) {
return value.getRegion();
}
};
this.plotAreaGrid.put(plotArea.worldname, map);
}
map.add(plotArea);
}
@Override
public void removePlotArea(PlotArea area) {
ArrayList<PlotArea> globalAreas = new ArrayList<PlotArea>(Arrays.asList(plotAreas));
globalAreas.remove(area);
this.plotAreas = globalAreas.toArray(new PlotArea[globalAreas.size()]);
if (globalAreas.isEmpty()) {
this.plotAreaMap.remove(area.worldname);
this.plotAreaGrid.remove(area.worldname);
} else {
this.plotAreaMap.put(area.worldname, globalAreas.toArray(new PlotArea[globalAreas.size()]));
this.plotAreaGrid.get(area.worldname).remove(area);
}
}
@Override
public PlotArea getPlotArea(String world, String id) {
PlotArea[] areas = this.plotAreaMap.get(world);
if (areas == null) {
return null;
}
if (areas.length == 1) {
return areas[0];
} else if (id == null) {
return null;
}
for (PlotArea area : areas) {
if (StringMan.isEqual(id, area.id)) {
return area;
}
}
return null;
}
@Override
public PlotArea getPlotArea(Location location) {
switch (this.plotAreas.length) {
case 0:
return null;
case 1:
PlotArea pa = this.plotAreas[0];
return pa.contains(location) ? pa : null;
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
String world = location.getWorld();
int hash = world.hashCode();
for (PlotArea area : this.plotAreas) {
if (hash == area.worldhash) {
if (area.contains(location.getX(), location.getZ()) && (!this.plotAreaHasCollision || world.equals(area.worldname))) {
return area;
}
}
}
return null;
default:
PlotArea[] areas = this.plotAreaMap.get(location.getWorld());
if (areas == null) {
return null;
}
int x;
int y;
switch (areas.length) {
case 0:
PlotArea a = areas[0];
return a.contains(location.getX(), location.getZ()) ? a : null;
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
x = location.getX();
y = location.getY();
for (PlotArea area : areas) {
if (area.contains(x, y)) {
return area;
}
}
return null;
default:
QuadMap<PlotArea> search = this.plotAreaGrid.get(location.getWorld());
return search.get(location.getX(), location.getZ());
}
}
}
@Override
public PlotArea[] getPlotAreas(String world, RegionWrapper region) {
if (region == null) {
PlotArea[] areas = this.plotAreaMap.get(world);
if (areas == null) {
return noPlotAreas;
}
return areas;
}
QuadMap<PlotArea> areas = this.plotAreaGrid.get(world);
if (areas == null) {
return noPlotAreas;
} else {
Set<PlotArea> found = areas.get(region);
return found.toArray(new PlotArea[found.size()]);
}
}
@Override
public void addWorld(String worldName) {
if (!this.plotAreaHasCollision && !this.plotAreaHashCheck.add(worldName.hashCode())) {
this.plotAreaHasCollision = true;
}
Set<String> tmp = new HashSet<>();
Collections.addAll(tmp, worlds);
tmp.add(worldName);
worlds = tmp.toArray(new String[tmp.size()]);
}
@Override
public void removeWorld(String worldName) {
Set<String> tmp = new HashSet<>();
Collections.addAll(tmp, worlds);
tmp.remove(worldName);
worlds = tmp.toArray(new String[tmp.size()]);
}
@Override
public String[] getAllWorlds() {
return worlds;
}
}

View File

@ -0,0 +1,19 @@
package com.intellectualcrafters.plot.object.worlds;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.RegionWrapper;
public interface PlotAreaManager {
public PlotArea getApplicablePlotArea(Location location);
public PlotArea getPlotArea(Location location);
public PlotArea getPlotArea(String world, String id);
public PlotArea[] getPlotAreas(String world, RegionWrapper region);
public PlotArea[] getAllPlotAreas();
public String[] getAllWorlds();
public void addPlotArea(PlotArea area);
public void removePlotArea(PlotArea area);
public void addWorld(String worldName);
public void removeWorld(String worldName);
}

View File

@ -0,0 +1,23 @@
package com.intellectualcrafters.plot.object.worlds;
import com.intellectualcrafters.configuration.ConfigurationSection;
import com.intellectualcrafters.plot.config.ConfigurationNode;
import com.intellectualcrafters.plot.generator.IndependentPlotGenerator;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotId;
public class SinglePlotArea extends PlotArea {
public SinglePlotArea(String worldName, String id, IndependentPlotGenerator generator, PlotId min, PlotId max) {
super(worldName, id, generator, min, max);
}
@Override
public void loadConfiguration(ConfigurationSection config) {
}
@Override
public ConfigurationNode[] getSettingNodes() {
return new ConfigurationNode[0];
}
}

View File

@ -0,0 +1,77 @@
package com.intellectualcrafters.plot.object.worlds;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.ArrayUtil;
public class SinglePlotAreaManager extends DefaultPlotAreaManager {
private final SinglePlotArea area;
private final SinglePlotArea[] array;
private PlotArea[] all;
public SinglePlotAreaManager(SinglePlotArea area) {
this.area = area;
this.array = new SinglePlotArea[] { area };
this.all = new PlotArea[] { area };
}
@Override
public PlotArea getApplicablePlotArea(Location location) {
PlotArea found = super.getApplicablePlotArea(location);
return found != null ? found : area;
}
@Override
public PlotArea getPlotArea(Location location) {
PlotArea found = super.getPlotArea(location);
return found != null ? found : area;
}
@Override
public PlotArea getPlotArea(String world, String id) {
PlotArea found = super.getPlotArea(world, id);
return found != null ? found : area;
}
@Override
public PlotArea[] getPlotAreas(String world, RegionWrapper region) {
PlotArea[] found = super.getPlotAreas(world, region);
return found != null ? found : array;
}
@Override
public PlotArea[] getAllPlotAreas() {
return all;
}
@Override
public String[] getAllWorlds() {
return super.getAllWorlds();
}
@Override
public void addPlotArea(PlotArea area) {
super.addPlotArea(area);
all = ArrayUtil.concatAll(super.getAllPlotAreas(), array);
}
@Override
public void removePlotArea(PlotArea area) {
if (area == this.area) {
throw new UnsupportedOperationException("Cannot remove base area!");
}
super.removePlotArea(area);
}
@Override
public void addWorld(String worldName) {
super.addWorld(worldName);
}
@Override
public void removeWorld(String worldName) {
super.removeWorld(worldName);
}
}

View File

@ -0,0 +1,111 @@
package com.intellectualcrafters.plot.object.worlds;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotManager;
import java.util.ArrayList;
public class SinglePlotManager extends PlotManager {
@Override
public PlotId getPlotIdAbs(PlotArea plotArea, int x, int y, int z) {
return null;
}
@Override
public PlotId getPlotId(PlotArea plotArea, int x, int y, int z) {
return null;
}
@Override
public Location getPlotBottomLocAbs(PlotArea plotArea, PlotId plotId) {
return null;
}
@Override
public Location getPlotTopLocAbs(PlotArea plotArea, PlotId plotId) {
return null;
}
@Override
public boolean clearPlot(PlotArea plotArea, Plot plot, Runnable whenDone) {
return false;
}
@Override
public boolean claimPlot(PlotArea plotArea, Plot plot) {
return false;
}
@Override
public boolean unclaimPlot(PlotArea plotArea, Plot plot, Runnable whenDone) {
return false;
}
@Override
public Location getSignLoc(PlotArea plotArea, Plot plot) {
return null;
}
@Override
public String[] getPlotComponents(PlotArea plotArea, PlotId plotId) {
return new String[0];
}
@Override
public boolean setComponent(PlotArea plotArea, PlotId plotId, String component, PlotBlock[] blocks) {
return false;
}
@Override
public boolean createRoadEast(PlotArea plotArea, Plot plot) {
return false;
}
@Override
public boolean createRoadSouth(PlotArea plotArea, Plot plot) {
return false;
}
@Override
public boolean createRoadSouthEast(PlotArea plotArea, Plot plot) {
return false;
}
@Override
public boolean removeRoadEast(PlotArea plotArea, Plot plot) {
return false;
}
@Override
public boolean removeRoadSouth(PlotArea plotArea, Plot plot) {
return false;
}
@Override
public boolean removeRoadSouthEast(PlotArea plotArea, Plot plot) {
return false;
}
@Override
public boolean startPlotMerge(PlotArea plotArea, ArrayList<PlotId> plotIds) {
return false;
}
@Override
public boolean startPlotUnlink(PlotArea plotArea, ArrayList<PlotId> plotIds) {
return false;
}
@Override
public boolean finishPlotMerge(PlotArea plotArea, ArrayList<PlotId> plotIds) {
return false;
}
@Override
public boolean finishPlotUnlink(PlotArea plotArea, ArrayList<PlotId> plotIds) {
return false;
}
}

View File

@ -0,0 +1,19 @@
package com.intellectualcrafters.plot.util;
import java.util.Arrays;
public class ArrayUtil {
public static final <T> T[] concatAll(T[] first, T[]... rest) {
int totalLength = first.length;
for (T[] array : rest) {
totalLength += array.length;
}
T[] result = Arrays.copyOf(first, totalLength);
int offset = first.length;
for (T[] array : rest) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
return result;
}
}

View File

@ -308,7 +308,11 @@ public class MainListener {
if (block == null) { if (block == null) {
return; return;
} }
Location loc = SpongeUtil.getLocation(player.getWorld().getName(), block.getLocation().get()); Optional<org.spongepowered.api.world.Location<World>> bloc = block.getLocation();
if (!bloc.isPresent()) {
return;
}
Location loc = SpongeUtil.getLocation(player.getWorld().getName(), bloc.get());
PlotArea area = loc.getPlotArea(); PlotArea area = loc.getPlotArea();
if (area == null) { if (area == null) {
return; return;
@ -393,7 +397,11 @@ public class MainListener {
List<Transaction<BlockSnapshot>> transactions = event.getTransactions(); List<Transaction<BlockSnapshot>> transactions = event.getTransactions();
Transaction<BlockSnapshot> first = transactions.get(0); Transaction<BlockSnapshot> first = transactions.get(0);
Location loc = SpongeUtil.getLocation(worldName, first.getOriginal().getPosition()); Location loc = SpongeUtil.getLocation(worldName, first.getOriginal().getPosition());
Plot plot = loc.getPlot(); PlotArea area = loc.getPlotArea();
if (area == null) {
return;
}
Plot plot = area.getPlot(loc);
if (plot == null) { if (plot == null) {
if (!loc.isPlotArea()) { if (!loc.isPlotArea()) {
return; return;
@ -469,19 +477,22 @@ public class MainListener {
} }
event.filter(l -> { event.filter(l -> {
Location loc1 = SpongeUtil.getLocation(worldName, l); Location loc1 = SpongeUtil.getLocation(worldName, l);
Plot plot1 = loc1.getPlot(); PlotArea area = loc1.getPlotArea();
if (area == null) {
return true;
}
Plot plot1 = area.getPlot(loc1);
if (plot1 == null) { if (plot1 == null) {
return loc1.getPlotAbs() == null || Permissions.hasPermission(pp, C.PERMISSION_ADMIN_DESTROY_ROAD); return Permissions.hasPermission(pp, C.PERMISSION_ADMIN_DESTROY_ROAD, true);
} }
if (!plot1.hasOwner()) { if (!plot1.hasOwner()) {
if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_DESTROY_UNOWNED)) { if (!Permissions.hasPermission(pp, C.PERMISSION_ADMIN_DESTROY_UNOWNED, true)) {
return true;
}
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_DESTROY_UNOWNED);
return false; return false;
} }
if (plot1.isAdded(pp.getUUID()) || Permissions.hasPermission(pp, C.PERMISSION_ADMIN_DESTROY_OTHER)) {
return true; return true;
}
if (!plot1.isAdded(pp.getUUID()) || !Permissions.hasPermission(pp, C.PERMISSION_ADMIN_DESTROY_OTHER, true)) {
return false;
} else { } else {
com.google.common.base.Optional<HashSet<PlotBlock>> destroy = plot1.getFlag(Flags.BREAK); com.google.common.base.Optional<HashSet<PlotBlock>> destroy = plot1.getFlag(Flags.BREAK);
BlockState state = l.getBlock(); BlockState state = l.getBlock();
@ -596,24 +607,24 @@ public class MainListener {
Location loc = SpongeUtil.getLocation(worldName, l); Location loc = SpongeUtil.getLocation(worldName, l);
Plot plot = loc.getPlot(); Plot plot = loc.getPlot();
if (plot == null) { if (plot == null) {
return loc.getPlotArea() != null && !Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_ROAD, true); return loc.getPlotArea() == null || Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_ROAD, true);
} }
if (!plot.hasOwner()) { if (!plot.hasOwner()) {
if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_UNOWNED, true)) { if (Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_UNOWNED, true)) {
return false;
}
return true; return true;
} }
if (plot.isAdded(pp.getUUID()) || Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_OTHER, true)) {
return false; return false;
}
if (plot.isAdded(pp.getUUID()) || Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_OTHER, true)) {
return true;
} else { } else {
com.google.common.base.Optional<HashSet<PlotBlock>> place = plot.getFlag(Flags.PLACE); com.google.common.base.Optional<HashSet<PlotBlock>> place = plot.getFlag(Flags.PLACE);
BlockState state = l.getBlock(); BlockState state = l.getBlock();
if (place.isPresent() && place.get().contains(SpongeUtil.getPlotBlock(state))) { if (place.isPresent() && place.get().contains(SpongeUtil.getPlotBlock(state))) {
return false; return true;
} }
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_OTHER); MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_OTHER);
return true; return false;
} }
} }
}); });