From 9f9c5abee030aeca722408292185e02017c83c42 Mon Sep 17 00:00:00 2001 From: charburgx Date: Sat, 21 Mar 2020 17:00:53 -0400 Subject: [PATCH 01/13] Changed version --- pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2ab7333d..5eacd8ba 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ org.mctourney.autoreferee AutoReferee - 2.8.4 + 2.8.5 AutoReferee Core Plugin https://www.reddit.com/r/mctourney Bukkit plugin for automatically refereeing competitive Minecraft matches. diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 1910e541..052207b2 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: AutoReferee main: org.mctourney.autoreferee.AutoReferee -version: 2.8.4 +version: 2.8.5 author: "authorblues, net" load: startup From e556a4410a90574348749ed80b2be003be4b2ece Mon Sep 17 00:00:00 2001 From: charburgx Date: Sat, 21 Mar 2020 17:50:34 -0400 Subject: [PATCH 02/13] Fixed dead repositories --- pom.xml | 6 +++--- .../org/mctourney/autoreferee/util/ColorConverterTest.java | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 5eacd8ba..2971a2ac 100644 --- a/pom.xml +++ b/pom.xml @@ -32,8 +32,8 @@ https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - sk89q-mvn2 - http://mvn2.sk89q.com/repo + sk89q + http://maven.sk89q.com/repo/ Plugin Metrics @@ -125,7 +125,7 @@ org.mcstats.bukkit metrics - R7 + R8-SNAPSHOT compile diff --git a/src/test/java/org/mctourney/autoreferee/util/ColorConverterTest.java b/src/test/java/org/mctourney/autoreferee/util/ColorConverterTest.java index 449d010b..f189e029 100644 --- a/src/test/java/org/mctourney/autoreferee/util/ColorConverterTest.java +++ b/src/test/java/org/mctourney/autoreferee/util/ColorConverterTest.java @@ -1,5 +1,4 @@ package org.mctourney.autoreferee.util; - import org.bukkit.Color; import org.junit.Assert; import org.junit.Test; @@ -9,6 +8,8 @@ public class ColorConverterTest @Test public void testHexToColor() throws Exception { + //org.apache.commons.lang.Validate; + Assert.assertEquals(Color.fromRGB(255, 255, 255), ColorConverter.hexToColor("#ffffff")); Assert.assertEquals(Color.fromRGB(255, 0, 136), ColorConverter.hexToColor("#ff0088")); Assert.assertEquals(Color.fromRGB(222, 173, 0), ColorConverter.hexToColor("#dead00")); From 622bc52f8caf54bac5fc5cec4feebee3f87ebdf0 Mon Sep 17 00:00:00 2001 From: charburgx Date: Sun, 22 Mar 2020 04:24:15 -0400 Subject: [PATCH 03/13] Implemented experimental mode --- src/main/java/org/mctourney/autoreferee/AutoReferee.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/org/mctourney/autoreferee/AutoReferee.java b/src/main/java/org/mctourney/autoreferee/AutoReferee.java index 5506a3f8..369628f4 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoReferee.java +++ b/src/main/java/org/mctourney/autoreferee/AutoReferee.java @@ -478,6 +478,15 @@ public void sendMessageSync(CommandSender recipient, String ...msgs) catch (IllegalStateException ignored) { } } + /** + * Get whether server is in experimental mode or not + * + * @return Whether server is in experimental mode + */ + public boolean isExperimentalMode() { + return this.getConfig().getBoolean("experimental-mode", false); + } + private class SyncMessageTask extends BukkitRunnable { private class RoutedMessage From a9c73f073ccf6eaca29c589a8f3ee2332aa6497c Mon Sep 17 00:00:00 2001 From: charburgx Date: Sun, 22 Mar 2020 04:24:40 -0400 Subject: [PATCH 04/13] Implemented experimental mode --- .../mctourney/autoreferee/AutoRefMatch.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java index de806c73..d3e3fd19 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java @@ -87,6 +87,7 @@ import org.mctourney.autoreferee.listeners.ZoneListener; import org.mctourney.autoreferee.regions.AutoRefRegion; import org.mctourney.autoreferee.regions.CuboidRegion; +import org.mctourney.autoreferee.regions.RegionGraph; import org.mctourney.autoreferee.util.ArmorPoints; import org.mctourney.autoreferee.util.BlockData; import org.mctourney.autoreferee.util.BookUtil; @@ -968,7 +969,9 @@ public AutoRefMatch(World world, boolean tmp) messageReferees("match", getWorld().getName(), "init"); loadWorldConfiguration(); - + if(AutoReferee.getInstance().isExperimentalMode()) // experemental feature + { this.initRegionGraphs(); this.computeRegionGraphs(); } + messageReferees("match", getWorld().getName(), "map", getMapName()); setCurrentState(MatchStatus.WAITING); @@ -2116,7 +2119,19 @@ public Set getRegions(AutoRefTeam team) public boolean addRegion(AutoRefRegion reg) { return reg != null && !regions.contains(reg) && regions.add(reg); } - + + protected void initRegionGraphs() { + for ( AutoRefTeam t : this.getTeams() ) { + t.initRegionGraph(); + } + } + + protected void computeRegionGraphs() { + for ( AutoRefTeam t : this.getTeams() ) { + t.computeRegionGraph(); + } + } + /** * A redstone mechanism necessary to start a match. * From c95e31625da26dcdb93034da7eb8f36bcc77bfab Mon Sep 17 00:00:00 2001 From: charburgx Date: Sun, 22 Mar 2020 04:28:29 -0400 Subject: [PATCH 05/13] Revert "Implemented experimental mode" This reverts commit a9c73f073ccf6eaca29c589a8f3ee2332aa6497c. --- .../mctourney/autoreferee/AutoRefMatch.java | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java index d3e3fd19..de806c73 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java @@ -87,7 +87,6 @@ import org.mctourney.autoreferee.listeners.ZoneListener; import org.mctourney.autoreferee.regions.AutoRefRegion; import org.mctourney.autoreferee.regions.CuboidRegion; -import org.mctourney.autoreferee.regions.RegionGraph; import org.mctourney.autoreferee.util.ArmorPoints; import org.mctourney.autoreferee.util.BlockData; import org.mctourney.autoreferee.util.BookUtil; @@ -969,9 +968,7 @@ public AutoRefMatch(World world, boolean tmp) messageReferees("match", getWorld().getName(), "init"); loadWorldConfiguration(); - if(AutoReferee.getInstance().isExperimentalMode()) // experemental feature - { this.initRegionGraphs(); this.computeRegionGraphs(); } - + messageReferees("match", getWorld().getName(), "map", getMapName()); setCurrentState(MatchStatus.WAITING); @@ -2119,19 +2116,7 @@ public Set getRegions(AutoRefTeam team) public boolean addRegion(AutoRefRegion reg) { return reg != null && !regions.contains(reg) && regions.add(reg); } - - protected void initRegionGraphs() { - for ( AutoRefTeam t : this.getTeams() ) { - t.initRegionGraph(); - } - } - - protected void computeRegionGraphs() { - for ( AutoRefTeam t : this.getTeams() ) { - t.computeRegionGraph(); - } - } - + /** * A redstone mechanism necessary to start a match. * From bcb6e41693af33b0682c3ca9cde47ff9fb5abe1a Mon Sep 17 00:00:00 2001 From: charburgx Date: Sun, 22 Mar 2020 04:33:09 -0400 Subject: [PATCH 06/13] Implemented RegionGraph for pearls --- pom.xml | 9 +- .../mctourney/autoreferee/AutoRefMatch.java | 21 +- .../mctourney/autoreferee/AutoRefTeam.java | 54 ++++ .../autoreferee/regions/AutoRefRegion.java | 6 +- .../autoreferee/regions/RegionGraph.java | 257 ++++++++++++++++++ .../autoreferee/util/ColorConverterTest.java | 3 +- 6 files changed, 342 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java diff --git a/pom.xml b/pom.xml index 2971a2ac..4daa2232 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ UTF-8 1.8.8-R0.1-SNAPSHOT - 1.6 + 1.8 @@ -128,6 +128,12 @@ R8-SNAPSHOT compile + + + org.jgrapht + jgrapht-core + 1.4.0 + @@ -250,6 +256,7 @@ com.google.code.gson:gson org.jdom:jdom2 org.mcstats.bukkit:metrics + org.jgrapht:jgrapht-core diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java index de806c73..c036d1b8 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java @@ -87,6 +87,7 @@ import org.mctourney.autoreferee.listeners.ZoneListener; import org.mctourney.autoreferee.regions.AutoRefRegion; import org.mctourney.autoreferee.regions.CuboidRegion; +import org.mctourney.autoreferee.regions.RegionGraph; import org.mctourney.autoreferee.util.ArmorPoints; import org.mctourney.autoreferee.util.BlockData; import org.mctourney.autoreferee.util.BookUtil; @@ -968,7 +969,9 @@ public AutoRefMatch(World world, boolean tmp) messageReferees("match", getWorld().getName(), "init"); loadWorldConfiguration(); - + if(AutoReferee.getInstance().isExperimentalMode()) // experemental feature + { this.initRegionGraphs(); this.computeRegionGraphs(); } + messageReferees("match", getWorld().getName(), "map", getMapName()); setCurrentState(MatchStatus.WAITING); @@ -2116,7 +2119,19 @@ public Set getRegions(AutoRefTeam team) public boolean addRegion(AutoRefRegion reg) { return reg != null && !regions.contains(reg) && regions.add(reg); } - + + protected void initRegionGraphs() { + for ( AutoRefTeam t : this.getTeams() ) { + t.initRegionGraph(); + } + } + + protected void computeRegionGraphs() { + for ( AutoRefTeam t : this.getTeams() ) { + t.computeRegionGraph(); + } + } + /** * A redstone mechanism necessary to start a match. * @@ -3624,4 +3639,4 @@ public void sendMatchInfo(CommandSender sender) : String.format(ChatColor.GRAY + "The current match time is: " + "%02d:%02d:%02d", timestamp/3600L, (timestamp/60L)%60L, timestamp%60L)); } -} +} \ No newline at end of file diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java index bffd80ae..e549434c 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java @@ -1,10 +1,12 @@ package org.mctourney.autoreferee; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.logging.Level; +import java.util.stream.Collectors; import com.google.common.collect.Maps; @@ -28,6 +30,8 @@ import org.mctourney.autoreferee.listeners.GoalsInventorySnapshot; import org.mctourney.autoreferee.listeners.ZoneListener; import org.mctourney.autoreferee.regions.AutoRefRegion; +import org.mctourney.autoreferee.regions.AutoRefRegion.Flag; +import org.mctourney.autoreferee.regions.RegionGraph; import org.mctourney.autoreferee.util.BlockData; import org.mctourney.autoreferee.util.Metadatable; import org.mctourney.autoreferee.util.PlayerKit; @@ -343,6 +347,56 @@ public Location getSpawnLocation() return regs[random.nextInt(spawnRegions.size())].getLocation(); } + private RegionGraph graph; + + protected RegionGraph getRegGraph() { + return this.graph; + } + + protected void initRegionGraph() { + // this is an expiremental feature + if(!AutoReferee.getInstance().isExperimentalMode()) return; + + if(this.getMatch() == null) return; + World w = this.getMatch().getWorld(); + if(w == null) return; + + if(this.getRegions() == null) return; + + graph = new RegionGraph(w, this.getRegions()); + } + + protected void computeRegionGraph() { + // this is an expiremental feature + if(!AutoReferee.getInstance().isExperimentalMode()) return; + + RegionGraph graph = this.getRegGraph(); + if(graph == null) return; + + if(this.getMatch() == null) return; + World w = this.getMatch().getWorld(); + if(w == null) return; + + graph.computeGraph().findConnectedRegions(); + } + + private Set unrestrictedPts() { + if(this.getRegions() == null) return null; + + return this.getRegions().stream() + .filter(reg -> reg.getFlags().contains(Flag.NON_RESTRICTED)) + .map(reg -> reg.getBoundingCuboid().getMinimumPoint().getBlock().getLocation()) + .collect(Collectors.toSet()); + } + + public boolean isRestrictedLoc(Location l) { + boolean def = false; + if(!this.getRegGraph().loaded()) return def; + if(this.getRegGraph().connectedRegions().isEmpty()) return def; + + return this.getRegGraph().isInRestrictedArea(l, this.unrestrictedPts()); + } + private Set goals = Sets.newHashSet(); /** diff --git a/src/main/java/org/mctourney/autoreferee/regions/AutoRefRegion.java b/src/main/java/org/mctourney/autoreferee/regions/AutoRefRegion.java index 53c85d72..43036def 100644 --- a/src/main/java/org/mctourney/autoreferee/regions/AutoRefRegion.java +++ b/src/main/java/org/mctourney/autoreferee/regions/AutoRefRegion.java @@ -38,10 +38,12 @@ public static enum Flag NO_ACCESS (1 << 4, false, 'a', "noaccess"), NO_TELEPORT (1 << 5, false, 't', "noteleport"), SPAWNERS_ONLY (1 << 6, false, 'w', "spawnersonly"), - NO_FLOW (1 << 7, true, 'f', "noflow"); + NO_FLOW (1 << 7, true, 'f', "noflow"), + DUNGEON_BOUNDARY (1 << 8, false, 'd', "dungeonboundary"), + NON_RESTRICTED (1 << 9, false, 'r', "nonrestricted"); // generated from above values - public static final String OPTIONS = "abenstwf"; + public static final String OPTIONS = "abdenrstwf"; private int value; private String name; diff --git a/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java b/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java new file mode 100644 index 00000000..f77194f7 --- /dev/null +++ b/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java @@ -0,0 +1,257 @@ +package org.mctourney.autoreferee.regions; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.jgrapht.Graph; +import org.jgrapht.alg.connectivity.ConnectivityInspector; +import org.jgrapht.graph.DefaultEdge; +import org.jgrapht.graph.SimpleGraph; + +import com.google.common.collect.HashBiMap; +import com.google.common.collect.Sets; +import com.sk89q.worldedit.Vector; + +public class RegionGraph { + public static final List UNBREAKABLE_BLOCKS + = Arrays.asList(Material.BEDROCK, Material.ENDER_PORTAL_FRAME, Material.BARRIER); + + private Graph graph = new SimpleGraph(DefaultEdge.class); + private HashBiMap vertices = HashBiMap.create(); + private Set> connectedRegions = Sets.newHashSet(); + + private Set mapRegions; + private Set dungeonOpenings = Sets.newHashSet(); + private World world; + + private boolean loaded = false; + + public RegionGraph(World w, Set regions) { + this.mapRegions = regions; + this.world = w; + } + + // converts block data into a Graph object + // this can then be used to make computations + // (e.g. finding dungeons, bedrock holes) + // + // computationally meh but its ok b/c it will + // only be run once per match + public RegionGraph computeGraph() { + CuboidRegion bound = this.boundingBox(); + if(bound == null) return this; + + this.graph = new SimpleGraph(DefaultEdge.class); + this.vertices.clear(); + this.connectedRegions.clear(); + + // add all passable blocks as vertices + for(AutoRefRegion r : regions()) { + for(Vec3 vec : blocks(r)) { + Block b = world().getBlockAt(vec.x(), vec.y(), vec.z()); + + // disregard unbreakable blocks and dungeon openings + // so we only have disconnected regions as vertices + if(!this.isDungeonBound(b)) { + Object vertex = new Object(); + this.vertices.put( vec , vertex ); + this.graph().addVertex(vertex); + } + } + } + + // add edges between all blocks + // not separated by unbreakables + for(AutoRefRegion r : regions()) { + for(Vec3 vec : blocks(r)) { + Arrays.asList(world().getBlockAt(vec.x() + 1, vec.y(), vec.z()), + world().getBlockAt(vec.x() - 1, vec.y(), vec.z()), + world().getBlockAt(vec.x(), vec.y() + 1, vec.z()), + world().getBlockAt(vec.x(), vec.y() - 1, vec.z()), + world().getBlockAt(vec.x(), vec.y(), vec.z() + 1), + world().getBlockAt(vec.x(), vec.y(), vec.z() - 1)) + .forEach( b -> { + // if it is not dungeon boundary and is within the region + if(!this.isDungeonBound(b) && regions().stream().anyMatch(reg -> reg.containsBlock(b))) { + Object v1 = this.vertex(vec(b)); if(v1 == null) return; + Object v2 = this.vertex(vec); if(v2 == null) return; + this.graph().addEdge( v1, v2 ); + } + });; + } + } + + this.setLoaded(true); + return this; + } + + // finds connected areas (e.g. dungeons, the outside world) + // useful for finding bedrock holes, and determining legality + // of enderpearl teleports + public RegionGraph findConnectedRegions() { + ConnectivityInspector conn = new ConnectivityInspector(this.graph()); + List> components = conn.connectedSets(); + + this.connectedRegions = components.stream() + .map(s -> s.stream() + .map(o -> { + Vec3 vec = this.vertexVec(o); + return vec; + }) + .filter(s2 -> s2 != null) + .collect(Collectors.toSet())).collect(Collectors.toSet()); + + return this; + } + + public Boolean isInRestrictedArea(Location l, Set nonrestricted) { + if(this.connectedRegions().isEmpty()) return true; + + Set vecs = nonrestricted.stream().map(loc -> vec(loc)).collect(Collectors.toSet()); + Set> outsideRegions = regionsWithPoints(vecs); + if(outsideRegions == null) return null; + + return !outsideRegions.stream().anyMatch(s -> s.contains( vec(l) )); + } + + public Set> regionsWithPoints(Set pts) { + return this.connectedRegions() + .stream() + .filter( s -> s.stream().anyMatch(v -> pts.contains(v)) ) + .collect(Collectors.toSet()); + } + + public Set> regionsWithoutPoint(Vec3 p) { + return this.connectedRegions() + .stream() + .filter( s -> !s.contains(p) ) + .collect(Collectors.toSet()); + } + + // creates Vec3 from coords + private Vec3 vec(int x, int y, int z) { + CuboidRegion bound = this.boundingBox(); + if(bound == null) return null; + + int maxX = bound.getMaximumPoint().getBlockX(); int minX = bound.getMinimumPoint().getBlockX(); + int maxY = bound.getMaximumPoint().getBlockY(); int minY = bound.getMinimumPoint().getBlockY(); + int maxZ = bound.getMaximumPoint().getBlockZ(); int minZ = bound.getMinimumPoint().getBlockZ(); + + return new Vec3( x, y, z, maxX, maxY, maxZ, minX, minY, minZ ); + } + + // create Vec3 from Location + private Vec3 vec(Location l) { + return vec(l.getBlockX(), l.getBlockY(), l.getBlockZ()); + } + + // create Vec3 from block + private Vec3 vec(Block b) { + return vec(b.getLocation()); + } + + // helper function + // gets all blocks in an ARRegion + private Set blocks(AutoRefRegion reg) { + CuboidRegion bound = reg.getBoundingCuboid(); + Set r = Sets.newHashSet(); + + int maxX = bound.getMaximumPoint().getBlockX(); int minX = bound.getMinimumPoint().getBlockX(); + int maxY = bound.getMaximumPoint().getBlockY(); int minY = bound.getMinimumPoint().getBlockY(); + int maxZ = bound.getMaximumPoint().getBlockZ(); int minZ = bound.getMinimumPoint().getBlockZ(); + + for( int z = minZ; z <= maxZ; z++ ) { + for(int y = minY; y <= maxY; y++) { + for(int x = minX; x <= maxX; x++) { + if(reg.contains(new Location( world(), x, y, z ))) { + r.add(vec( x, y, z )); + } + } + } + } + + return r; + } + + private CuboidRegion boundingBox() { + Set reg = this.regions().stream() + .map(r -> r.getBoundingCuboid()) + .collect(Collectors.toSet()); + + return reg.stream() + .reduce((a, b) -> CuboidRegion.combine(a, b)) + .orElse(null); + } + + private boolean isDungeonBound(Block b) { + return UNBREAKABLE_BLOCKS.contains(b.getType()) || + this.openings().stream().anyMatch(reg -> reg.containsBlock(b)); + } + + private Graph graph() { return this.graph; } + private HashBiMap vertices() { return this.vertices; } + private Object vertex(Vec3 vec) { return this.vertices().get(vec); } + private Vec3 vertexVec(Object obj) { return this.vertices().inverse().get(obj); } + + private World world() { return this.world; } + private Set regions() { return this.mapRegions; } + private Set openings() { return this.dungeonOpenings; } + public Set> connectedRegions() { return this.connectedRegions; } + + public boolean loaded() { return this.loaded; } + + public RegionGraph setLoaded(boolean loaded) { this.loaded = loaded; return this; } + public RegionGraph setDungeonOpenings(Set openings) { + this.dungeonOpenings = openings; return this; + } +} + +// helper class, needed as keys for hashmap +class Vec3 { + private int x; + private int y; + private int z; + private int maxX; + private int maxY; + private int maxZ; + private int minX; + private int minY; + private int minZ; + + //public Vec3() { } + public Vec3(int x, int y, int z, int maxX, int maxY, int maxZ, int minX, int minY, int minZ) + { this.x = x; this.y = y; this.z = z; this.maxX = maxX; this.maxY = maxY; this.maxZ = maxZ; } + + public int x() { return this.x; } + public int y() { return this.y; } + public int z() { return this.z; } + + public Vec3 x(int x) { this.x = this.minX + ( (x - this.minX) % (this.width() + 1)); return this; } + public Vec3 y(int y) { this.y = this.minY + ( (y - this.minY) % (this.length() + 1)); return this; } + public Vec3 z(int z) { this.z = this.minZ + ( (z - this.minZ) % (this.height() + 1)); return this; } + + private int width() { return this.maxX - this.minX; } + private int length() { return this.maxY - this.minY; } + private int height() { return this.maxZ - this.minZ; } + + @Override + public boolean equals(Object obj) { + if(obj == this) return true; + if(!(obj instanceof Vec3)) return false; + Vec3 vec = (Vec3) obj; + + return (this.x() == vec.x() && this.y() == vec.y() && this.z() == vec.z()); + } + + @Override + public int hashCode() { + return ( x() - this.minX ) + (( y() - this.minY ) * ( this.width() + 1 )) + ((z() - this.minZ) * ( this.width() + 1 ) * (this.length() + 1)); + } +} diff --git a/src/test/java/org/mctourney/autoreferee/util/ColorConverterTest.java b/src/test/java/org/mctourney/autoreferee/util/ColorConverterTest.java index f189e029..449d010b 100644 --- a/src/test/java/org/mctourney/autoreferee/util/ColorConverterTest.java +++ b/src/test/java/org/mctourney/autoreferee/util/ColorConverterTest.java @@ -1,4 +1,5 @@ package org.mctourney.autoreferee.util; + import org.bukkit.Color; import org.junit.Assert; import org.junit.Test; @@ -8,8 +9,6 @@ public class ColorConverterTest @Test public void testHexToColor() throws Exception { - //org.apache.commons.lang.Validate; - Assert.assertEquals(Color.fromRGB(255, 255, 255), ColorConverter.hexToColor("#ffffff")); Assert.assertEquals(Color.fromRGB(255, 0, 136), ColorConverter.hexToColor("#ff0088")); Assert.assertEquals(Color.fromRGB(222, 173, 0), ColorConverter.hexToColor("#dead00")); From 3b2a03b50a63617081a5a0b4bc6f750b694207b2 Mon Sep 17 00:00:00 2001 From: charburgx Date: Sun, 22 Mar 2020 06:16:54 -0400 Subject: [PATCH 07/13] Implemented RegionGraph --- pom.xml | 3 +- .../mctourney/autoreferee/AutoRefMatch.java | 2 +- .../mctourney/autoreferee/AutoRefTeam.java | 13 ++- .../mctourney/autoreferee/AutoReferee.java | 5 + .../commands/ConfigurationCommands.java | 101 ++++++++++++++++++ .../autoreferee/regions/RegionGraph.java | 80 ++++++-------- .../org/mctourney/autoreferee/util/Vec3.java | 49 +++++++++ 7 files changed, 196 insertions(+), 57 deletions(-) create mode 100644 src/main/java/org/mctourney/autoreferee/util/Vec3.java diff --git a/pom.xml b/pom.xml index 4daa2232..e357d0a4 100644 --- a/pom.xml +++ b/pom.xml @@ -237,7 +237,7 @@ org.apache.maven.plugins maven-shade-plugin - 1.7 + 3.2.2 package @@ -257,6 +257,7 @@ org.jdom:jdom2 org.mcstats.bukkit:metrics org.jgrapht:jgrapht-core + org.jheaps:jheaps diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java index c036d1b8..e51199e5 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java @@ -2126,7 +2126,7 @@ protected void initRegionGraphs() { } } - protected void computeRegionGraphs() { + public void computeRegionGraphs() { for ( AutoRefTeam t : this.getTeams() ) { t.computeRegionGraph(); } diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java index e549434c..5cee8538 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java @@ -349,12 +349,12 @@ public Location getSpawnLocation() private RegionGraph graph; - protected RegionGraph getRegGraph() { + public RegionGraph getRegGraph() { return this.graph; } protected void initRegionGraph() { - // this is an expiremental feature + // this is an experimental feature if(!AutoReferee.getInstance().isExperimentalMode()) return; if(this.getMatch() == null) return; @@ -363,10 +363,13 @@ protected void initRegionGraph() { if(this.getRegions() == null) return; - graph = new RegionGraph(w, this.getRegions()); + graph = new RegionGraph(w, this.getRegions()) + .setDungeonOpenings( this.getRegions().stream() + .filter(r -> r.getFlags().contains(Flag.DUNGEON_BOUNDARY)) + .collect(Collectors.toSet())); } - protected void computeRegionGraph() { + public void computeRegionGraph() { // this is an expiremental feature if(!AutoReferee.getInstance().isExperimentalMode()) return; @@ -380,7 +383,7 @@ protected void computeRegionGraph() { graph.computeGraph().findConnectedRegions(); } - private Set unrestrictedPts() { + public Set unrestrictedPts() { if(this.getRegions() == null) return null; return this.getRegions().stream() diff --git a/src/main/java/org/mctourney/autoreferee/AutoReferee.java b/src/main/java/org/mctourney/autoreferee/AutoReferee.java index 369628f4..ab21a578 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoReferee.java +++ b/src/main/java/org/mctourney/autoreferee/AutoReferee.java @@ -353,6 +353,11 @@ public void onEnable() consoleLog = getConfig().getBoolean("console-log", true); consoleLogInColor = getConfig().getBoolean("console-colors", true); + // experimental mode? + if(this.isExperimentalMode()) { + getLogger().info(this.getName() + " loaded in Experimental Mode. This is not intended for regular use!"); + } + // setup the map library folder AutoRefMap.getMapLibrary(); diff --git a/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java b/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java index f2599370..b5cf868b 100644 --- a/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java +++ b/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java @@ -7,8 +7,10 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; import org.bukkit.entity.NPC; @@ -28,6 +30,7 @@ import org.mctourney.autoreferee.regions.CuboidRegion; import org.mctourney.autoreferee.util.BlockData; import org.mctourney.autoreferee.util.LocationUtil; +import org.mctourney.autoreferee.util.Vec3; import org.mctourney.autoreferee.util.commands.AutoRefCommand; import org.mctourney.autoreferee.util.commands.AutoRefPermission; import org.mctourney.autoreferee.util.commands.CommandHandler; @@ -42,6 +45,7 @@ import org.jdom2.output.Format; import org.jdom2.output.XMLOutputter; +import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.selections.CuboidSelection; import com.sk89q.worldedit.bukkit.selections.Selection; @@ -524,4 +528,101 @@ public boolean scoreboardSave(CommandSender sender, AutoRefMatch match, String[] return true; } + + @AutoRefCommand(name= {"autoref", "regions"}, argmin=1, argmax=1, options="rpf") + @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) + public boolean arRegions(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { + if(!AutoReferee.getInstance().isExperimentalMode()) return false; + if ( match == null ) return false; + Player player = (Player) sender; + + WorldEditPlugin worldEdit = AutoReferee.getWorldEdit(); + if (worldEdit == null) + { + // world edit not installed + sender.sendMessage("This method requires WorldEdit installed and running."); + return true; + } + + AutoRefTeam team = match.getTeam(args[0]); + + if(options.hasOption('r')) { + team.computeRegionGraph(); + player.sendMessage( "" + team.getRegGraph().connectedRegions().size() ); + } + + if(options.hasOption('p')) { + Selection sel = worldEdit.getSelection(player); + if(sel == null || !(sel instanceof CuboidSelection)) return true; + + CuboidSelection csel = (CuboidSelection) sel; + if(!sel.getRegionSelector().isDefined()) return true; + + com.sk89q.worldedit.regions.CuboidRegion reg; + + try { + reg + = (com.sk89q.worldedit.regions.CuboidRegion) csel.getRegionSelector().getRegion(); + } catch (IncompleteRegionException e) { + e.printStackTrace(); + return false; + } + + Location l0 = new Location(player.getWorld(), reg.getPos1().getBlockX(), reg.getPos1().getBlockY(), reg.getPos1().getBlockZ()); + Location l1 = new Location(player.getWorld(), reg.getPos2().getBlockX(), reg.getPos2().getBlockY(), reg.getPos2().getBlockZ()); + + Set path = team.getRegGraph().shortestPath(l0, l1); + + if(path == null) { + player.sendMessage("No path found"); + return true; + } + + path.forEach(b -> b.setType(Material.WOOL)); + } + + if(options.hasOption('f')) { + byte data = 1; + + for( Set reg : team.getRegGraph().regionsWithoutPointsLoc( team.unrestrictedPts() ) ) { + for( Vec3 v : reg ) { + Block b = v.loc(player.getWorld()).getBlock(); + b.setType(Material.WOOL); + b.setData(data); + } + + data = (byte)(data + 1); + } + } + + return true; + } + + @AutoRefCommand(name= {"autoref", "test"}, argmin=1, argmax=1) + @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) + public boolean bruh(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { + if ( match == null ) return false; + Player p = (Player) sender; + + if(!p.isOp()) return false; + + WorldEditPlugin worldEdit = AutoReferee.getWorldEdit(); + if (worldEdit == null) + { + // world edit not installed + sender.sendMessage("This method requires WorldEdit installed and running."); + return true; + } + + Selection sel = worldEdit.getSelection(p); + if(sel == null || !(sel instanceof CuboidSelection)) return true; + CuboidSelection csel = (CuboidSelection) sel; + + AutoRefTeam team = match.getTeam(args[0]); + + p.sendMessage("" + ( team.getRegGraph().vec(csel.getMaximumPoint()).hashCode() == + team.getRegGraph().vec(csel.getMinimumPoint()).hashCode() )); + + return true; + } } diff --git a/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java b/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java index f77194f7..5c300273 100644 --- a/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java +++ b/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java @@ -11,9 +11,12 @@ import org.bukkit.World; import org.bukkit.block.Block; import org.jgrapht.Graph; +import org.jgrapht.GraphPath; import org.jgrapht.alg.connectivity.ConnectivityInspector; +import org.jgrapht.alg.shortestpath.DijkstraShortestPath; import org.jgrapht.graph.DefaultEdge; import org.jgrapht.graph.SimpleGraph; +import org.mctourney.autoreferee.util.Vec3; import com.google.common.collect.HashBiMap; import com.google.common.collect.Sets; @@ -115,10 +118,10 @@ public Boolean isInRestrictedArea(Location l, Set nonrestricted) { if(this.connectedRegions().isEmpty()) return true; Set vecs = nonrestricted.stream().map(loc -> vec(loc)).collect(Collectors.toSet()); - Set> outsideRegions = regionsWithPoints(vecs); - if(outsideRegions == null) return null; + Set> restrictedRegions = regionsWithoutPoints(vecs); + if(restrictedRegions == null) return null; - return !outsideRegions.stream().anyMatch(s -> s.contains( vec(l) )); + return restrictedRegions.stream().anyMatch(s -> s.contains( vec(l) )); } public Set> regionsWithPoints(Set pts) { @@ -128,13 +131,33 @@ public Set> regionsWithPoints(Set pts) { .collect(Collectors.toSet()); } - public Set> regionsWithoutPoint(Vec3 p) { + public Set> regionsWithoutPoints(Set pts) { return this.connectedRegions() .stream() - .filter( s -> !s.contains(p) ) + .filter( s -> s.stream().allMatch(v -> !pts.contains(v)) ) .collect(Collectors.toSet()); } + public Set> regionsWithoutPointsLoc(Set pts) { + Set ptsVec = pts.stream().map(l -> vec(l)).collect(Collectors.toSet()); + return regionsWithoutPoints( ptsVec ); + } + + public Set shortestPath(Location l0, Location l1) { + if(!this.loaded()) return Sets.newHashSet(); + + DijkstraShortestPath path = new DijkstraShortestPath(this.graph()); + GraphPath gpath = path.getPath( vertex(vec(l0)), vertex(vec(l1)) ); + + if(gpath == null) return null; + + return gpath.getVertexList().stream() + .map(v -> this.world().getBlockAt(vertexVec(v).loc(this.world()))) + .collect(Collectors.toSet()); + + //return null; + } + // creates Vec3 from coords private Vec3 vec(int x, int y, int z) { CuboidRegion bound = this.boundingBox(); @@ -148,12 +171,12 @@ private Vec3 vec(int x, int y, int z) { } // create Vec3 from Location - private Vec3 vec(Location l) { + public Vec3 vec(Location l) { return vec(l.getBlockX(), l.getBlockY(), l.getBlockZ()); } // create Vec3 from block - private Vec3 vec(Block b) { + public Vec3 vec(Block b) { return vec(b.getLocation()); } @@ -212,46 +235,3 @@ public RegionGraph setDungeonOpenings(Set openings) { this.dungeonOpenings = openings; return this; } } - -// helper class, needed as keys for hashmap -class Vec3 { - private int x; - private int y; - private int z; - private int maxX; - private int maxY; - private int maxZ; - private int minX; - private int minY; - private int minZ; - - //public Vec3() { } - public Vec3(int x, int y, int z, int maxX, int maxY, int maxZ, int minX, int minY, int minZ) - { this.x = x; this.y = y; this.z = z; this.maxX = maxX; this.maxY = maxY; this.maxZ = maxZ; } - - public int x() { return this.x; } - public int y() { return this.y; } - public int z() { return this.z; } - - public Vec3 x(int x) { this.x = this.minX + ( (x - this.minX) % (this.width() + 1)); return this; } - public Vec3 y(int y) { this.y = this.minY + ( (y - this.minY) % (this.length() + 1)); return this; } - public Vec3 z(int z) { this.z = this.minZ + ( (z - this.minZ) % (this.height() + 1)); return this; } - - private int width() { return this.maxX - this.minX; } - private int length() { return this.maxY - this.minY; } - private int height() { return this.maxZ - this.minZ; } - - @Override - public boolean equals(Object obj) { - if(obj == this) return true; - if(!(obj instanceof Vec3)) return false; - Vec3 vec = (Vec3) obj; - - return (this.x() == vec.x() && this.y() == vec.y() && this.z() == vec.z()); - } - - @Override - public int hashCode() { - return ( x() - this.minX ) + (( y() - this.minY ) * ( this.width() + 1 )) + ((z() - this.minZ) * ( this.width() + 1 ) * (this.length() + 1)); - } -} diff --git a/src/main/java/org/mctourney/autoreferee/util/Vec3.java b/src/main/java/org/mctourney/autoreferee/util/Vec3.java new file mode 100644 index 00000000..92f0fc0f --- /dev/null +++ b/src/main/java/org/mctourney/autoreferee/util/Vec3.java @@ -0,0 +1,49 @@ +package org.mctourney.autoreferee.util; + +import org.bukkit.Location; +import org.bukkit.World; + +//helper class, needed as keys for hashmap +public class Vec3 { + private int x; + private int y; + private int z; + private int maxX; + private int maxY; + private int maxZ; + private int minX; + private int minY; + private int minZ; + + //public Vec3() { } + public Vec3(int x, int y, int z, int maxX, int maxY, int maxZ, int minX, int minY, int minZ) + { this.x = x; this.y = y; this.z = z; this.maxX = maxX; this.maxY = maxY; this.maxZ = maxZ; } + + public int x() { return this.x; } + public int y() { return this.y; } + public int z() { return this.z; } + + public Vec3 x(int x) { this.x = this.minX + ( (x - this.minX) % (this.width() + 1)); return this; } + public Vec3 y(int y) { this.y = this.minY + ( (y - this.minY) % (this.length() + 1)); return this; } + public Vec3 z(int z) { this.z = this.minZ + ( (z - this.minZ) % (this.height() + 1)); return this; } + + private int width() { return this.maxX - this.minX; } + private int length() { return this.maxY - this.minY; } + private int height() { return this.maxZ - this.minZ; } + + public Location loc(World w) { return new Location(w, x(), y(), z()); } + + @Override + public boolean equals(Object obj) { + if(obj == this) return true; + if(!(obj instanceof Vec3)) return false; + Vec3 vec = (Vec3) obj; + + return (this.x() == vec.x() && this.y() == vec.y() && this.z() == vec.z()); + } + + @Override + public int hashCode() { + return ( x() - this.minX ) + (( y() - this.minY ) * ( this.width() + 1 )) + ((z() - this.minZ) * ( this.width() + 1 ) * (this.length() + 1)); + } +} From 01efc4ef5ce194e54cfbfb141381afd3d921d795 Mon Sep 17 00:00:00 2001 From: charburgx Date: Sun, 22 Mar 2020 16:26:42 -0400 Subject: [PATCH 08/13] Fully implemented no-enderpearl zones as experimental feature --- dependency-reduced-pom.xml | 187 ++++++++++++++++++ .../mctourney/autoreferee/AutoRefMatch.java | 30 ++- .../mctourney/autoreferee/AutoRefTeam.java | 23 ++- .../mctourney/autoreferee/AutoReferee.java | 1 + .../commands/ConfigurationCommands.java | 10 +- .../autoreferee/listeners/ZoneListener.java | 46 ++++- .../autoreferee/regions/RegionGraph.java | 54 ++++- 7 files changed, 332 insertions(+), 19 deletions(-) create mode 100644 dependency-reduced-pom.xml diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml new file mode 100644 index 00000000..df93b5cb --- /dev/null +++ b/dependency-reduced-pom.xml @@ -0,0 +1,187 @@ + + + 4.0.0 + org.mctourney.autoreferee + AutoReferee + AutoReferee Core Plugin + 2.8.5 + Bukkit plugin for automatically refereeing competitive Minecraft matches. + https://www.reddit.com/r/mctourney + + scm:git:git://github.com/rmct/AutoReferee.git + scm:git:git@github.com:rmct/AutoReferee.git + https://github.com/rmct/AutoReferee + + + ${basedir}/src/main/java + + + . + true + ${basedir}/src/main/resources/ + + plugin.yml + colors.csv + autoreferee.properties + + + + defaults/ + true + ${basedir}/src/main/resources/ + + map.xml + config.yml + + + + webstats/ + ${basedir}/src/main/resources/webstats + + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.1 + + + validate + + create + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + + java + + + + + org.mctourney.autoreferee.AutoRefereeTools + + + + + + + maven-jar-plugin + 2.3.2 + + + + true + org.mctourney.autoreferee.AutoRefereeTools + + + + + + maven-surefire-plugin + 2.11 + + + maven-compiler-plugin + 2.3.2 + + ${java.target.version} + ${java.target.version} + true + true + true + + + + maven-shade-plugin + 3.2.2 + + + package + + shade + + + true + + + org.apache.commons:commons-lang3 + commons-io:commons-io + commons-codec:commons-codec + commons-cli:commons-cli + commons-collections:commons-collections + com.google.code.gson:gson + org.jdom:jdom2 + org.mcstats.bukkit:metrics + org.jgrapht:jgrapht-core + org.jheaps:jheaps + + + + + + + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + sk89q + http://maven.sk89q.com/repo/ + + + Plugin Metrics + http://repo.mcstats.org/content/repositories/public + + + + + com.sk89q + worldedit + 5.3 + compile + + + spoutapi + org.spout + + + vanilla + org.spout + + + + + org.bukkit + bukkit + 1.8.8-R0.1-SNAPSHOT + provided + + + junit + junit + 4.8.1 + test + + + com.google.guava + guava + 14.0 + compile + + + + 1.8 + UTF-8 + 1.8.8-R0.1-SNAPSHOT + + diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java index e51199e5..cc0eefd7 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java @@ -9,6 +9,7 @@ import java.text.SimpleDateFormat; import java.util.*; import java.util.logging.Level; +import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.ZipEntry; @@ -931,6 +932,7 @@ public void run() public AutoRefMatch(World world, boolean tmp, MatchStatus state) { this(world, tmp); setCurrentState(state); } + @SuppressWarnings("deprecation") public AutoRefMatch(World world, boolean tmp) { setPrimaryWorld(world); @@ -969,8 +971,19 @@ public AutoRefMatch(World world, boolean tmp) messageReferees("match", getWorld().getName(), "init"); loadWorldConfiguration(); - if(AutoReferee.getInstance().isExperimentalMode()) // experemental feature - { this.initRegionGraphs(); this.computeRegionGraphs(); } + + if(AutoReferee.getInstance().isExperimentalMode()) { // experimental feature + this.initRegionGraphs(); + + graphTask = Bukkit.getScheduler() + .scheduleAsyncDelayedTask(AutoReferee.getInstance(), new BukkitRunnable() { + @Override + public void run() { + computeRegionGraphs(); + graphTask = -1; + } + }); + } messageReferees("match", getWorld().getName(), "map", getMapName()); setCurrentState(MatchStatus.WAITING); @@ -2120,6 +2133,14 @@ public Set getRegions(AutoRefTeam team) public boolean addRegion(AutoRefRegion reg) { return reg != null && !regions.contains(reg) && regions.add(reg); } + public int graphTask = -1; + + public boolean cancelGraphTask() { + if(graphTask < 0) return false; + Bukkit.getScheduler().cancelTask(graphTask); + return true; + } + protected void initRegionGraphs() { for ( AutoRefTeam t : this.getTeams() ) { t.initRegionGraph(); @@ -2132,6 +2153,11 @@ public void computeRegionGraphs() { } } + public boolean regionGraphsLoaded() { + return this.getTeams().stream() + .allMatch(t -> t.getRegGraph().loaded()); + } + /** * A redstone mechanism necessary to start a match. * diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java index 5cee8538..484b7110 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java @@ -353,7 +353,9 @@ public RegionGraph getRegGraph() { return this.graph; } - protected void initRegionGraph() { + public boolean regGraphLoaded() { return this.getRegGraph().loaded(); } + + public void initRegionGraph() { // this is an experimental feature if(!AutoReferee.getInstance().isExperimentalMode()) return; @@ -363,15 +365,18 @@ protected void initRegionGraph() { if(this.getRegions() == null) return; - graph = new RegionGraph(w, this.getRegions()) - .setDungeonOpenings( this.getRegions().stream() + graph = new RegionGraph(w, this.getRegions(), AutoReferee.getInstance().getLogger()) + .computeGraph().regions(this.getRegions()); + /*.setDungeonOpenings( this.getRegions().stream() .filter(r -> r.getFlags().contains(Flag.DUNGEON_BOUNDARY)) - .collect(Collectors.toSet())); + .collect(Collectors.toSet()));*/ } + // safe from async thread public void computeRegionGraph() { // this is an expiremental feature if(!AutoReferee.getInstance().isExperimentalMode()) return; + if(this.getRegions() == null) return; RegionGraph graph = this.getRegGraph(); if(graph == null) return; @@ -380,7 +385,7 @@ public void computeRegionGraph() { World w = this.getMatch().getWorld(); if(w == null) return; - graph.computeGraph().findConnectedRegions(); + graph.findConnectedRegions(); } public Set unrestrictedPts() { @@ -392,6 +397,14 @@ public Set unrestrictedPts() { .collect(Collectors.toSet()); } + /*public Set dungeonOpenings() { + if(this.getRegions() == null) return null; + + return this.regions().stream() + .filter(r -> r.getFlags().contains(Flag.DUNGEON_BOUNDARY)) + .collect(Collectors.toSet()); + }*/ + public boolean isRestrictedLoc(Location l) { boolean def = false; if(!this.getRegGraph().loaded()) return def; diff --git a/src/main/java/org/mctourney/autoreferee/AutoReferee.java b/src/main/java/org/mctourney/autoreferee/AutoReferee.java index ab21a578..bf9d23fa 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoReferee.java +++ b/src/main/java/org/mctourney/autoreferee/AutoReferee.java @@ -485,6 +485,7 @@ public void sendMessageSync(CommandSender recipient, String ...msgs) /** * Get whether server is in experimental mode or not + * @author char * * @return Whether server is in experimental mode */ diff --git a/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java b/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java index b5cf868b..9e37d113 100644 --- a/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java +++ b/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java @@ -547,8 +547,10 @@ public boolean arRegions(CommandSender sender, AutoRefMatch match, String[] args AutoRefTeam team = match.getTeam(args[0]); if(options.hasOption('r')) { + match.cancelGraphTask(); + team.initRegionGraph(); team.computeRegionGraph(); - player.sendMessage( "" + team.getRegGraph().connectedRegions().size() ); + player.sendMessage( "Found " + team.getRegGraph().connectedRegions().size() + " regions."); } if(options.hasOption('p')) { @@ -620,8 +622,10 @@ public boolean bruh(CommandSender sender, AutoRefMatch match, String[] args, Com AutoRefTeam team = match.getTeam(args[0]); - p.sendMessage("" + ( team.getRegGraph().vec(csel.getMaximumPoint()).hashCode() == - team.getRegGraph().vec(csel.getMinimumPoint()).hashCode() )); + Location pos = p.getLocation(); + pos.getBlock().setType(Material.WOOL); + + return true; } diff --git a/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java b/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java index 0a5958a3..1f11fcc0 100644 --- a/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java +++ b/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java @@ -3,12 +3,14 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.entity.EnderPearl; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Minecart; @@ -26,6 +28,7 @@ import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.event.player.PlayerBedEnterEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent; @@ -35,6 +38,7 @@ import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerPickupItemEvent; import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.event.vehicle.VehicleEnterEvent; import org.bukkit.event.weather.WeatherChangeEvent; import org.bukkit.plugin.Plugin; @@ -47,6 +51,7 @@ import org.mctourney.autoreferee.goals.BlockGoal; import org.mctourney.autoreferee.regions.AutoRefRegion; import org.mctourney.autoreferee.regions.AutoRefRegion.Flag; +import org.mctourney.autoreferee.regions.RegionGraph; import org.mctourney.autoreferee.util.BlockData; import org.mctourney.autoreferee.util.LocationUtil; @@ -155,7 +160,7 @@ else if (exit != null && fallspeed < FREEFALL_THRESHOLD && onGround) } } } - + @EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true) public void enderpearlThrow(ProjectileLaunchEvent event) { @@ -176,6 +181,10 @@ public void enderpearlThrow(ProjectileLaunchEvent event) } } } + + private boolean doPreventDungeonExits() { + return AutoReferee.getInstance().isExperimentalMode(); + } public boolean validPlayer(Player player) { @@ -412,7 +421,7 @@ public void teleportEvent(Player pl, Location fm, Location to, String reason) AutoRefPlayer apl = match.getPlayer(pl); if (apl == null) return; apl.setLastTeleportLocation(to); - + // generate message regarding the teleport event String bedrock = BlockGoal.blockInRange(BlockData.BEDROCK, to, 5) != null ? " (near bedrock)" : ""; String message = apl.getDisplayName() + ChatColor.GRAY + " has teleported @ " + @@ -421,6 +430,32 @@ public void teleportEvent(Player pl, Location fm, Location to, String reason) boolean excludeStreamers = dsq <= LONG_TELE_DISTANCE * LONG_TELE_DISTANCE; for (Player ref : match.getReferees(excludeStreamers)) ref.sendMessage(message); } + + public boolean enderPearlLegal(Player pl, Location fm, Location to, AutoRefMatch match) { + boolean def = true; + // This is an experimental feature + AutoReferee plugin = AutoReferee.getInstance(); + if(!plugin.isExperimentalMode()) return def; + if(match.getCurrentState() != MatchStatus.PLAYING) return def; + + AutoRefTeam t = match.getPlayerTeam(pl); + if(t == null) return def; + + if( RegionGraph.unbreakableInRange(to, 1) != null ) + { return false; } + + if(t.regGraphLoaded()) { + if(t.isRestrictedLoc(fm)) { + plugin.getLogger().info("Pearl 1"); + return false; + }else if(t.isRestrictedLoc(to)) { + plugin.getLogger().info("Pearl 2"); + return false; + } + } + + return def; + } @EventHandler(priority=EventPriority.MONITOR) public void playerTeleport(PlayerTeleportEvent event) @@ -448,6 +483,13 @@ public void playerTeleport(PlayerTeleportEvent event) if (apl.getTeam().hasFlag(event.getTo(), Flag.NO_TELEPORT)) { event.setCancelled(true); return; } + if(event.getCause() == TeleportCause.ENDER_PEARL) { + if(!enderPearlLegal(event.getPlayer(), event.getFrom(), event.getTo(), match)) { + event.getPlayer().sendMessage(ChatColor.RED + "Illegal pearl!"); + event.setCancelled(true); return; + } + } + String reason = "by " + event.getCause().name().toLowerCase().replaceAll("_", " "); teleportEvent(event.getPlayer(), event.getFrom(), event.getTo(), reason); diff --git a/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java b/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java index 5c300273..e8625d59 100644 --- a/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java +++ b/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java @@ -3,6 +3,7 @@ import java.util.Arrays; import java.util.List; import java.util.Set; +import java.util.logging.Logger; import java.util.stream.Collector; import java.util.stream.Collectors; @@ -16,6 +17,8 @@ import org.jgrapht.alg.shortestpath.DijkstraShortestPath; import org.jgrapht.graph.DefaultEdge; import org.jgrapht.graph.SimpleGraph; +import org.mctourney.autoreferee.regions.AutoRefRegion.Flag; +import org.mctourney.autoreferee.util.BlockData; import org.mctourney.autoreferee.util.Vec3; import com.google.common.collect.HashBiMap; @@ -35,10 +38,12 @@ public class RegionGraph { private World world; private boolean loaded = false; + private Logger logger; - public RegionGraph(World w, Set regions) { + public RegionGraph(World w, Set regions, Logger logger) { this.mapRegions = regions; this.world = w; + this.logger = logger; } // converts block data into a Graph object @@ -51,6 +56,8 @@ public RegionGraph computeGraph() { CuboidRegion bound = this.boundingBox(); if(bound == null) return this; + this.setLoaded(false); + this.graph = new SimpleGraph(DefaultEdge.class); this.vertices.clear(); this.connectedRegions.clear(); @@ -91,7 +98,6 @@ public RegionGraph computeGraph() { } } - this.setLoaded(true); return this; } @@ -99,6 +105,8 @@ public RegionGraph computeGraph() { // useful for finding bedrock holes, and determining legality // of enderpearl teleports public RegionGraph findConnectedRegions() { + log("Computing a RegionGraph..."); + ConnectivityInspector conn = new ConnectivityInspector(this.graph()); List> components = conn.connectedSets(); @@ -109,8 +117,10 @@ public RegionGraph findConnectedRegions() { return vec; }) .filter(s2 -> s2 != null) - .collect(Collectors.toSet())).collect(Collectors.toSet()); + .collect(Collectors.toSet())).filter(s2 -> !s2.isEmpty()).collect(Collectors.toSet()); + log("Initialized graph!"); + this.setLoaded(true); return this; } @@ -121,7 +131,8 @@ public Boolean isInRestrictedArea(Location l, Set nonrestricted) { Set> restrictedRegions = regionsWithoutPoints(vecs); if(restrictedRegions == null) return null; - return restrictedRegions.stream().anyMatch(s -> s.contains( vec(l) )); + return restrictedRegions.stream().anyMatch(s -> s.contains( vec(l) )) || + !this.regions().stream().anyMatch(r -> r.contains(l)); } public Set> regionsWithPoints(Set pts) { @@ -213,7 +224,7 @@ private CuboidRegion boundingBox() { .orElse(null); } - private boolean isDungeonBound(Block b) { + public boolean isDungeonBound(Block b) { return UNBREAKABLE_BLOCKS.contains(b.getType()) || this.openings().stream().anyMatch(reg -> reg.containsBlock(b)); } @@ -225,13 +236,42 @@ private boolean isDungeonBound(Block b) { private World world() { return this.world; } private Set regions() { return this.mapRegions; } - private Set openings() { return this.dungeonOpenings; } + public Set openings() { + //return this.dungeonOpenings; + return this.regions().stream() + .filter(r -> r.getFlags().contains(Flag.DUNGEON_BOUNDARY)) + .collect(Collectors.toSet()); + } public Set> connectedRegions() { return this.connectedRegions; } public boolean loaded() { return this.loaded; } - public RegionGraph setLoaded(boolean loaded) { this.loaded = loaded; return this; } + public RegionGraph regions(Set regions) { this.mapRegions = regions; return this; } + private RegionGraph setLoaded(boolean loaded) { this.loaded = loaded; return this; } public RegionGraph setDungeonOpenings(Set openings) { this.dungeonOpenings = openings; return this; } + + private void log(String msg) { + if(this.logger != null) this.logger.info( msg ); + } + + // Proper block in range + public static Location unbreakableInRange(Location loc, int radius) + { + Block b = loc.getBlock(); + int h = loc.getWorld().getMaxHeight(); + int by = loc.getBlockY(); + + for (int y = -radius; y <= radius; ++y) if (by + y >= 0 && by + y < h) + for (int x = -radius; x <= radius; ++x) + for (int z = -radius; z <= radius; ++z) + { + Block rel = b.getRelative(x, y, z); + if(UNBREAKABLE_BLOCKS.contains(rel.getType())) return rel.getLocation(); + //if (blockdata.matchesBlock(rel)) return rel.getLocation(); + } + + return null; + } } From 4a32d222891ccc58697d2eabc1359d991d84d30b Mon Sep 17 00:00:00 2001 From: charburgx Date: Sun, 22 Mar 2020 16:32:06 -0400 Subject: [PATCH 09/13] Added config toggle for scoreboard --- .../mctourney/autoreferee/AutoRefMatch.java | 23 +++++++++++++------ .../mctourney/autoreferee/AutoRefTeam.java | 2 ++ .../mctourney/autoreferee/AutoReferee.java | 10 ++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java index cc0eefd7..ab0028f7 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java @@ -62,6 +62,7 @@ import org.bukkit.material.Redstone; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Scoreboard; @@ -975,14 +976,14 @@ public AutoRefMatch(World world, boolean tmp) if(AutoReferee.getInstance().isExperimentalMode()) { // experimental feature this.initRegionGraphs(); - graphTask = Bukkit.getScheduler() - .scheduleAsyncDelayedTask(AutoReferee.getInstance(), new BukkitRunnable() { + graphTask = + new BukkitRunnable() { @Override public void run() { computeRegionGraphs(); - graphTask = -1; + graphTask = null; } - }); + }.runTaskAsynchronously(AutoReferee.getInstance()); } messageReferees("match", getWorld().getName(), "map", getMapName()); @@ -1187,6 +1188,8 @@ protected void loadWorldConfiguration() protected void clearScoreboardData(Scoreboard sb) { + if(!AutoReferee.getInstance().doScoreboard()) return; + // unregister all old objectives (created by AutoReferee) for (Objective obj : scoreboard.getObjectives()) if (obj.getName().startsWith("ar#")) obj.unregister(); @@ -1198,6 +1201,8 @@ protected void clearScoreboardData(Scoreboard sb) protected void loadScoreboardData() { + if(!AutoReferee.getInstance().doScoreboard()) return; + clearScoreboardData(scoreboard); clearScoreboardData( infoboard); @@ -1257,6 +1262,8 @@ public void saveScoreboardData() public void saveScoreboardData(Scoreboard sb) { + if(!AutoReferee.getInstance().doScoreboard()) return; + Element teams = new Element("teams"); for (Team team : sb.getTeams()) { @@ -1506,6 +1513,8 @@ private void parseExtraGameRules(Element gameplay) private void setupScoreboardObjectives() { + if(!AutoReferee.getInstance().doScoreboard()) return; + // defer to prevent exception on server start, // before any worlds are fully loaded new BukkitRunnable() @@ -2133,11 +2142,11 @@ public Set getRegions(AutoRefTeam team) public boolean addRegion(AutoRefRegion reg) { return reg != null && !regions.contains(reg) && regions.add(reg); } - public int graphTask = -1; + public BukkitTask graphTask = null; public boolean cancelGraphTask() { - if(graphTask < 0) return false; - Bukkit.getScheduler().cancelTask(graphTask); + if(graphTask == null) return false; + graphTask.cancel(); return true; } diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java index 484b7110..0b1b688d 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java @@ -559,6 +559,8 @@ public static AutoRefTeam create(AutoRefMatch match, String name, ChatColor colo protected void setupScoreboard() { + if(!AutoReferee.getInstance().doScoreboard()) return; + String sbteam = this.getScoreboardTeamName(); // set team data on spectators' scoreboard diff --git a/src/main/java/org/mctourney/autoreferee/AutoReferee.java b/src/main/java/org/mctourney/autoreferee/AutoReferee.java index bf9d23fa..a67ccdf1 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoReferee.java +++ b/src/main/java/org/mctourney/autoreferee/AutoReferee.java @@ -493,6 +493,16 @@ public boolean isExperimentalMode() { return this.getConfig().getBoolean("experimental-mode", false); } + /** + * Get whether to create scoreboard or not + * @author char + * + * @return if to create scoreboard + */ + public boolean doScoreboard() { + return this.getConfig().getBoolean("scoreboard", true); + } + private class SyncMessageTask extends BukkitRunnable { private class RoutedMessage From 7342fdb9cd3693f95a5c7c17f9c95295aad492c5 Mon Sep 17 00:00:00 2001 From: charburgx Date: Sun, 22 Mar 2020 21:02:25 -0400 Subject: [PATCH 10/13] Implemented regions.json --- .../mctourney/autoreferee/AutoRefMatch.java | 52 ++++++++++-- .../mctourney/autoreferee/AutoRefTeam.java | 47 +++++++---- .../commands/ConfigurationCommands.java | 30 ++++++- .../autoreferee/listeners/ZoneListener.java | 12 +-- .../autoreferee/regions/RegionGraph.java | 84 ++++++++++++++++++- .../org/mctourney/autoreferee/util/Vec3.java | 3 + 6 files changed, 190 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java index ab0028f7..85504956 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java @@ -23,6 +23,8 @@ import com.google.common.collect.MapDifference; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.gson.Gson; +import com.google.gson.JsonElement; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -973,7 +975,16 @@ public AutoRefMatch(World world, boolean tmp) messageReferees("match", getWorld().getName(), "init"); loadWorldConfiguration(); - if(AutoReferee.getInstance().isExperimentalMode()) { // experimental feature + this.createRegionGraphs(); + + try { + this.loadRegionJSON(); + } catch (FileNotFoundException | ClassCastException e) { + AutoReferee.log("Failed to load " + REGION_CFG_FILENAME); + e.printStackTrace(); + } + + /*if(AutoReferee.getInstance().isExperimentalMode()) { // experimental feature this.initRegionGraphs(); graphTask = @@ -984,7 +995,7 @@ public void run() { graphTask = null; } }.runTaskAsynchronously(AutoReferee.getInstance()); - } + }*/ messageReferees("match", getWorld().getName(), "map", getMapName()); setCurrentState(MatchStatus.WAITING); @@ -2142,12 +2153,10 @@ public Set getRegions(AutoRefTeam team) public boolean addRegion(AutoRefRegion reg) { return reg != null && !regions.contains(reg) && regions.add(reg); } - public BukkitTask graphTask = null; - - public boolean cancelGraphTask() { - if(graphTask == null) return false; - graphTask.cancel(); - return true; + protected void createRegionGraphs() { + for ( AutoRefTeam t : this.getTeams() ) { + t.createRegionGraph(); + } } protected void initRegionGraphs() { @@ -2167,6 +2176,33 @@ public boolean regionGraphsLoaded() { .allMatch(t -> t.getRegGraph().loaded()); } + public static final String REGION_CFG_FILENAME = "regions.json"; + + private void loadRegionJSON( ) throws FileNotFoundException, ClassCastException { + if(!AutoReferee.getInstance().isExperimentalMode()) return; + + File f = new File(this.getWorld().getWorldFolder(), REGION_CFG_FILENAME); + if(!f.exists()) return; + + Gson gson = new Gson(); + Reader reader = new FileReader(f); + + Map data = gson.fromJson(reader, Map.class); + + for( String key : data.keySet() ) { + AutoRefTeam team = this.getTeam(key); + if(team == null) continue; + + Map data2 = (Map) data.get(key); + + List restricted = (List) data2.get("restricted"); + + if(restricted != null) { + team.setRestrictionRegions( team.getRegGraph().fromInts( restricted ) ); + } + } + } + /** * A redstone mechanism necessary to start a match. * diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java index 0b1b688d..295e14d4 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java @@ -36,7 +36,7 @@ import org.mctourney.autoreferee.util.Metadatable; import org.mctourney.autoreferee.util.PlayerKit; import org.mctourney.autoreferee.util.PlayerUtil; - +import org.mctourney.autoreferee.util.Vec3; import org.apache.commons.lang.StringUtils; import com.google.common.collect.Sets; @@ -348,28 +348,34 @@ public Location getSpawnLocation() } private RegionGraph graph; + private Set> restrictedRegions; - public RegionGraph getRegGraph() { - return this.graph; - } + public RegionGraph getRegGraph() { return this.graph; } + public void setRestrictionRegions(Set> regions) + { this.restrictedRegions = regions; } public boolean regGraphLoaded() { return this.getRegGraph().loaded(); } public void initRegionGraph() { + createRegionGraph(); + graph.computeGraph(); + } + + public void createRegionGraph() { // this is an experimental feature - if(!AutoReferee.getInstance().isExperimentalMode()) return; - - if(this.getMatch() == null) return; - World w = this.getMatch().getWorld(); - if(w == null) return; - - if(this.getRegions() == null) return; - - graph = new RegionGraph(w, this.getRegions(), AutoReferee.getInstance().getLogger()) - .computeGraph().regions(this.getRegions()); - /*.setDungeonOpenings( this.getRegions().stream() - .filter(r -> r.getFlags().contains(Flag.DUNGEON_BOUNDARY)) - .collect(Collectors.toSet()));*/ + if(!AutoReferee.getInstance().isExperimentalMode()) return; + + if(this.getMatch() == null) return; + World w = this.getMatch().getWorld(); + if(w == null) return; + + if(this.getRegions() == null) return; + + graph = new RegionGraph(w, this.getRegions(), AutoReferee.getInstance().getLogger(), this) + .regions(this.getRegions()); + /*.setDungeonOpenings( this.getRegions().stream() + .filter(r -> r.getFlags().contains(Flag.DUNGEON_BOUNDARY)) + .collect(Collectors.toSet()));*/ } // safe from async thread @@ -407,6 +413,13 @@ public Set unrestrictedPts() { public boolean isRestrictedLoc(Location l) { boolean def = false; + if(this.getRegGraph() == null) return def; + + if(this.restrictedRegions != null) { + return this.getRegGraph() + .isRestricted(l, this.restrictedRegions, this.getRegions()); + } + if(!this.getRegGraph().loaded()) return def; if(this.getRegGraph().connectedRegions().isEmpty()) return def; diff --git a/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java b/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java index 9e37d113..7341a936 100644 --- a/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java +++ b/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java @@ -2,7 +2,9 @@ import java.io.File; import java.io.FileOutputStream; +import java.io.FileWriter; import java.io.IOException; +import java.util.HashMap; import java.util.Set; import org.bukkit.Bukkit; @@ -39,6 +41,7 @@ import org.apache.commons.lang.StringUtils; import com.google.common.collect.Sets; +import com.google.gson.Gson; import org.jdom2.Element; import org.jdom2.JDOMException; @@ -529,7 +532,7 @@ public boolean scoreboardSave(CommandSender sender, AutoRefMatch match, String[] return true; } - @AutoRefCommand(name= {"autoref", "regions"}, argmin=1, argmax=1, options="rpf") + @AutoRefCommand(name= {"autoref", "regions"}, argmin=1, argmax=1, options="fprs") @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) public boolean arRegions(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { if(!AutoReferee.getInstance().isExperimentalMode()) return false; @@ -547,7 +550,7 @@ public boolean arRegions(CommandSender sender, AutoRefMatch match, String[] args AutoRefTeam team = match.getTeam(args[0]); if(options.hasOption('r')) { - match.cancelGraphTask(); + //match.cancelGraphTask(); team.initRegionGraph(); team.computeRegionGraph(); player.sendMessage( "Found " + team.getRegGraph().connectedRegions().size() + " regions."); @@ -597,6 +600,29 @@ public boolean arRegions(CommandSender sender, AutoRefMatch match, String[] args } } + if(options.hasOption('s')) { + //System.out.println(team.getRegGraph().toJSON( team.unrestrictedPts() )); + + HashMap json = new HashMap(); + + for(AutoRefTeam t : match.getTeams()) { + json.put( t.getName() , t.getRegGraph().toJSON( t.unrestrictedPts() ) ); + } + + Gson gson = new Gson(); + + File f = new File( match.getWorld().getWorldFolder(), AutoRefMatch.REGION_CFG_FILENAME ); + + try (FileWriter writer = new FileWriter( f )) { + gson.toJson(json, writer); + } catch(IOException e) { + player.sendMessage("Error writing file"); + e.printStackTrace(); + } + + player.sendMessage("Successfully wrote " + AutoRefMatch.REGION_CFG_FILENAME + "!"); + } + return true; } diff --git a/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java b/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java index 1f11fcc0..2654ded9 100644 --- a/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java +++ b/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java @@ -444,14 +444,10 @@ public boolean enderPearlLegal(Player pl, Location fm, Location to, AutoRefMatch if( RegionGraph.unbreakableInRange(to, 1) != null ) { return false; } - if(t.regGraphLoaded()) { - if(t.isRestrictedLoc(fm)) { - plugin.getLogger().info("Pearl 1"); - return false; - }else if(t.isRestrictedLoc(to)) { - plugin.getLogger().info("Pearl 2"); - return false; - } + if(t.isRestrictedLoc(fm)) { + return false; + }else if(t.isRestrictedLoc(to)) { + return false; } return def; diff --git a/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java b/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java index e8625d59..81dbed95 100644 --- a/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java +++ b/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java @@ -1,7 +1,10 @@ package org.mctourney.autoreferee.regions; +import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.logging.Logger; import java.util.stream.Collector; @@ -17,12 +20,15 @@ import org.jgrapht.alg.shortestpath.DijkstraShortestPath; import org.jgrapht.graph.DefaultEdge; import org.jgrapht.graph.SimpleGraph; +import org.json.simple.JSONObject; +import org.mctourney.autoreferee.AutoRefTeam; import org.mctourney.autoreferee.regions.AutoRefRegion.Flag; import org.mctourney.autoreferee.util.BlockData; import org.mctourney.autoreferee.util.Vec3; import com.google.common.collect.HashBiMap; import com.google.common.collect.Sets; +import com.google.gson.Gson; import com.sk89q.worldedit.Vector; public class RegionGraph { @@ -39,11 +45,13 @@ public class RegionGraph { private boolean loaded = false; private Logger logger; + private AutoRefTeam team; - public RegionGraph(World w, Set regions, Logger logger) { + public RegionGraph(World w, Set regions, Logger logger, AutoRefTeam team) { this.mapRegions = regions; this.world = w; this.logger = logger; + this.team = team; } // converts block data into a Graph object @@ -51,7 +59,7 @@ public RegionGraph(World w, Set regions, Logger logger) { // (e.g. finding dungeons, bedrock holes) // // computationally meh but its ok b/c it will - // only be run once per match + // save relevant info to a file public RegionGraph computeGraph() { CuboidRegion bound = this.boundingBox(); if(bound == null) return this; @@ -124,6 +132,59 @@ public RegionGraph findConnectedRegions() { return this; } + public HashMap toJSON(Set nonrestricted) { + Set vecs = nonrestricted.stream().map(loc -> vec(loc)).collect(Collectors.toSet()); + Set> restrictedRegions = regionsWithoutPoints(vecs); + + //JSONObject restricted = new JSONObject(); + //JSONObject regions = new JSONObject(); + + /*int i = 0; int j = 0; + for( Set vecl : restrictedRegions ) { + JSONObject region = new JSONObject(); + + for( Vec3 v : vecl ) { + region.put(j, new int[] { v.x(), v.y(), v.z() } ); + j++; + } + + regions.put(i, region); + i++; + }*/ + + + + List> regions = restrictedRegions.stream() + .map( + r -> r.stream().map(v -> (new int[]{ v.x(), v.y(), v.z() }) ) + .collect(Collectors.toList()) + ) + .collect(Collectors.toList()); + + HashMap json = new HashMap(); + json.put("restricted", regions); + + return json; + + /*int i = 0; int j = 0; + for( Set vecl : restrictedRegions ) { + for( Vec3 v : vecl ) { + regions[i][j][0] = v.x(); + regions[i][j][1] = v.y(); + regions[i][j][2] = v.z(); + j++; + } + i++; + }*/ + + //restricted.put("restricted", regions); + //JSONObject r = new JSONObject(); + //r.put(this.team.getName(), restricted); + + //return r; + //restricted.put("", arg1) + } + public Boolean isInRestrictedArea(Location l, Set nonrestricted) { if(this.connectedRegions().isEmpty()) return true; @@ -131,8 +192,12 @@ public Boolean isInRestrictedArea(Location l, Set nonrestricted) { Set> restrictedRegions = regionsWithoutPoints(vecs); if(restrictedRegions == null) return null; + return this.isRestricted(l, restrictedRegions, this.regions()); + } + + public boolean isRestricted(Location l, Set> restrictedRegions, Set regions) { return restrictedRegions.stream().anyMatch(s -> s.contains( vec(l) )) || - !this.regions().stream().anyMatch(r -> r.contains(l)); + !regions.stream().anyMatch(r -> r.contains(l)); } public Set> regionsWithPoints(Set pts) { @@ -274,4 +339,17 @@ public static Location unbreakableInRange(Location loc, int radius) return null; } + + public Set> fromInts(List>> list) { + return list.stream() + .map(l -> l.stream().map(v -> { + if(v.size() < 3) return null; + int v0 = (int) Math.round(v.get(0)); + int v1 = (int) Math.round(v.get(1)); + int v2 = (int) Math.round(v.get(2)); + return vec(v0, v1, v2); + }) + .filter(v -> v != null) + .collect(Collectors.toSet())).collect(Collectors.toSet()); + } } diff --git a/src/main/java/org/mctourney/autoreferee/util/Vec3.java b/src/main/java/org/mctourney/autoreferee/util/Vec3.java index 92f0fc0f..81c65bfe 100644 --- a/src/main/java/org/mctourney/autoreferee/util/Vec3.java +++ b/src/main/java/org/mctourney/autoreferee/util/Vec3.java @@ -1,5 +1,8 @@ package org.mctourney.autoreferee.util; +import java.util.List; +import java.util.Set; + import org.bukkit.Location; import org.bukkit.World; From e3c95eda3ce54c48de479aa635e902a2c9b47339 Mon Sep 17 00:00:00 2001 From: charburgx Date: Mon, 23 Mar 2020 05:22:20 -0400 Subject: [PATCH 11/13] Fully implemented region monitoring --- .../mctourney/autoreferee/AutoRefMatch.java | 2 +- .../mctourney/autoreferee/AutoRefTeam.java | 30 ++++- .../mctourney/autoreferee/AutoReferee.java | 6 + .../commands/ConfigurationCommands.java | 13 +- .../entity/EntityAREnderPearl.java | 112 ++++++++++++++++++ .../autoreferee/listeners/ZoneListener.java | 106 +++++++++++++++-- .../autoreferee/regions/AutoRefRegion.java | 8 +- .../autoreferee/regions/CuboidRegion.java | 8 +- .../autoreferee/regions/CylinderRegion.java | 9 +- .../autoreferee/regions/PointRegion.java | 11 +- .../mctourney/autoreferee/util/MathUtil.java | 7 ++ 11 files changed, 285 insertions(+), 27 deletions(-) create mode 100644 src/main/java/org/mctourney/autoreferee/entity/EntityAREnderPearl.java create mode 100644 src/main/java/org/mctourney/autoreferee/util/MathUtil.java diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java index 85504956..2d52a2ec 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java @@ -2178,7 +2178,7 @@ public boolean regionGraphsLoaded() { public static final String REGION_CFG_FILENAME = "regions.json"; - private void loadRegionJSON( ) throws FileNotFoundException, ClassCastException { + public void loadRegionJSON( ) throws FileNotFoundException, ClassCastException { if(!AutoReferee.getInstance().isExperimentalMode()) return; File f = new File(this.getWorld().getWorldFolder(), REGION_CFG_FILENAME); diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java index 295e14d4..32bbbc9e 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java @@ -302,7 +302,18 @@ public Location getVictoryMonumentLocation() */ public Set getRegions() { return match.getRegions(this); } - + + /** + * Returns whether a particular Location + * is in team's lane or not + * @author char + * + * @param loc + * @return + */ + public boolean containsLoc(Location loc) + { return this.getRegions().stream().anyMatch(reg -> reg.contains(loc)); } + public boolean addRegion(AutoRefRegion reg) { for (AutoRefRegion ereg : match.getRegions()) @@ -411,6 +422,23 @@ public Set unrestrictedPts() { .collect(Collectors.toSet()); }*/ + public Set restrictedRegion(Location l) { + if(this.getRegGraph() == null) return null; + + if(this.restrictedRegions != null) { + return this.restrictedRegions.stream() + .filter(reg -> reg.contains( this.getRegGraph().vec(l) )) + .findAny().orElse(null); + } + + if(!this.getRegGraph().loaded()) return null; + if(this.getRegGraph().connectedRegions().isEmpty()) return null; + + return this.getRegGraph().connectedRegions().stream() + .filter(reg -> reg.contains( this.getRegGraph().vec(l) )) + .findAny().orElse(null); + } + public boolean isRestrictedLoc(Location l) { boolean def = false; if(this.getRegGraph() == null) return def; diff --git a/src/main/java/org/mctourney/autoreferee/AutoReferee.java b/src/main/java/org/mctourney/autoreferee/AutoReferee.java index a67ccdf1..b80c459b 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoReferee.java +++ b/src/main/java/org/mctourney/autoreferee/AutoReferee.java @@ -40,6 +40,7 @@ import org.mctourney.autoreferee.commands.PracticeCommands; import org.mctourney.autoreferee.commands.ScoreboardCommands; import org.mctourney.autoreferee.commands.SpectatorCommands; +import org.mctourney.autoreferee.entity.EntityAREnderPearl; import org.mctourney.autoreferee.listeners.CombatListener; import org.mctourney.autoreferee.listeners.ObjectiveTracker; import org.mctourney.autoreferee.listeners.ObjectiveTracer; @@ -356,6 +357,11 @@ public void onEnable() // experimental mode? if(this.isExperimentalMode()) { getLogger().info(this.getName() + " loaded in Experimental Mode. This is not intended for regular use!"); + + if(EntityAREnderPearl.patch()) + getLogger().info("Successfully patched EntityEnderPearl!"); + else + getLogger().severe("Failed to patch EntityEnderPearl! Please let a dev know about this."); } // setup the map library folder diff --git a/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java b/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java index 7341a936..f997fafe 100644 --- a/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java +++ b/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java @@ -1,6 +1,7 @@ package org.mctourney.autoreferee.commands; import java.io.File; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; @@ -532,7 +533,7 @@ public boolean scoreboardSave(CommandSender sender, AutoRefMatch match, String[] return true; } - @AutoRefCommand(name= {"autoref", "regions"}, argmin=1, argmax=1, options="fprs") + @AutoRefCommand(name= {"autoref", "regions"}, argmin=1, argmax=1, options="flprs") @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) public boolean arRegions(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { if(!AutoReferee.getInstance().isExperimentalMode()) return false; @@ -623,6 +624,16 @@ public boolean arRegions(CommandSender sender, AutoRefMatch match, String[] args player.sendMessage("Successfully wrote " + AutoRefMatch.REGION_CFG_FILENAME + "!"); } + if(options.hasOption('l')) { + try { + match.loadRegionJSON(); + player.sendMessage("Successfully loaded regions file"); + } catch (FileNotFoundException | ClassCastException e) { + player.sendMessage("Failed loading regions file"); + e.printStackTrace(); + } + } + return true; } diff --git a/src/main/java/org/mctourney/autoreferee/entity/EntityAREnderPearl.java b/src/main/java/org/mctourney/autoreferee/entity/EntityAREnderPearl.java new file mode 100644 index 00000000..a63ce04f --- /dev/null +++ b/src/main/java/org/mctourney/autoreferee/entity/EntityAREnderPearl.java @@ -0,0 +1,112 @@ +package org.mctourney.autoreferee.entity; + +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.ChatColor; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.entity.Player; +import org.mctourney.autoreferee.AutoRefMatch; +import org.mctourney.autoreferee.AutoRefTeam; +import org.mctourney.autoreferee.AutoReferee; +import org.mctourney.autoreferee.regions.AutoRefRegion; + +import com.sk89q.worldedit.Location; + +import net.minecraft.server.v1_8_R3.EntityEnderPearl; +import net.minecraft.server.v1_8_R3.EntityLiving; +import net.minecraft.server.v1_8_R3.EntityPlayer; +import net.minecraft.server.v1_8_R3.EntityTypes; +import net.minecraft.server.v1_8_R3.World; + +public class EntityAREnderPearl extends EntityEnderPearl { + private AutoReferee ar; + private AutoRefTeam team; + private Player player; + private boolean canTravelThroughVoid = false; + + public EntityAREnderPearl(Player player, AutoRefTeam team, boolean travelThroughVoid) { + super(((CraftWorld) ((CraftPlayer) player).getWorld()).getHandle(), ((CraftPlayer) player).getHandle()); + this.team = team; + this.player = player; + this.canTravelThroughVoid = travelThroughVoid; + } + + // Called when pearl updates + @Override + public void t_() { + if(!this.canTravelThroughVoid()) { + if(!this.regions().stream() + .anyMatch(r -> r.distanceToRegion( this.locX, this.locY, this.locZ ) <= 0.0 ) ) { + if(this.getAR() != null) + this.getAR().sendMessageSync(this.player(), ChatColor.RED + "Illegal pearl!"); + + this.die(); return; + } + } + + super.t_(); + } + + public void spawn() { + this.getWorld().addEntity(this); + } + + public static boolean PATCHED = false; + + public static boolean patch() { + try { + registerEntity(EntityAREnderPearl.class, "ThrownAREnderpearl", 14); + PATCHED = true; + + return true; + } catch (Exception ignored) { + return false; + } + } + + private static void registerEntity(Class entityClass, String entityName, int entityId) + throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{ + //ReflectionUtil.get + + for(String fieldname : Arrays.asList("c", "d", "f", "g")) { + Field field = EntityTypes.class.getDeclaredField(fieldname); + field.setAccessible(true); + + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); + + Map m = (Map) field.get(null); + + switch(fieldname) { + case "c": + m.put(entityName, entityClass); + break; + case "d": + m.put(entityClass, entityName); + break; + case "f": + m.put(entityClass, entityId); + break; + case "g": + m.put(entityName, entityId); + break; + } + } + } + + public EntityAREnderPearl setAR(AutoReferee ar) { this.ar = ar; return this; } + + private AutoRefTeam team() { return this.team; } + private Set regions() { return this.team().getRegions(); } + private Player player() { return this.player; } + private boolean canTravelThroughVoid() { return this.canTravelThroughVoid; } + private AutoReferee getAR() { return this.ar; } +} diff --git a/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java b/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java index 2654ded9..798f2d86 100644 --- a/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java +++ b/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java @@ -46,6 +46,7 @@ import org.mctourney.autoreferee.AutoRefPlayer; import org.mctourney.autoreferee.AutoRefTeam; import org.mctourney.autoreferee.AutoReferee; +import org.mctourney.autoreferee.entity.EntityAREnderPearl; import org.mctourney.autoreferee.AutoRefMatch.MatchStatus; import org.mctourney.autoreferee.AutoRefMatch.Role; import org.mctourney.autoreferee.goals.BlockGoal; @@ -161,6 +162,8 @@ else if (exit != null && fallspeed < FREEFALL_THRESHOLD && onGround) } } + Set trackedPearls = Sets.newHashSet(); + @EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true) public void enderpearlThrow(ProjectileLaunchEvent event) { @@ -169,7 +172,7 @@ public void enderpearlThrow(ProjectileLaunchEvent event) if (match == null || match.getCurrentState() == MatchStatus.NONE) return; if (event.getEntityType() == EntityType.ENDER_PEARL) - { + { Player player = (Player) event.getEntity().getShooter(); AutoRefPlayer apl = match.getPlayer(player); @@ -179,6 +182,37 @@ public void enderpearlThrow(ProjectileLaunchEvent event) ChatColor.DARK_GRAY + " has thrown an enderpearl while out of bounds."; for (Player ref : match.getReferees()) ref.sendMessage(msg); } + + // Expiremental: track ender pearls + if(!AutoReferee.getInstance().isExperimentalMode()) return; + if(match.getCurrentState() != MatchStatus.PLAYING) return; + if(!EntityAREnderPearl.PATCHED) return; + + if(trackedPearls.contains(event.getEntity())) return; + + if(apl != null && apl.getTeam() != null) { + AutoRefTeam team = apl.getTeam(); + + if(team.isRestrictedLoc(player.getLocation())) { + event.setCancelled(true); + + EntityAREnderPearl pearl = new EntityAREnderPearl(player, team, false) + .setAR(AutoReferee.getInstance()); + + trackedPearls.add(pearl.getBukkitEntity()); + + pearl.spawn(); + } + } + } + } + + @EventHandler(priority=EventPriority.MONITOR) + public void enderpearlHit(ProjectileHitEvent event) { + if(!AutoReferee.getInstance().isExperimentalMode()) return; + + if(event.getEntity() instanceof EnderPearl) { + trackedPearls.remove(event.getEntity()); } } @@ -405,7 +439,11 @@ public void creatureSpawn(CreatureSpawnEvent event) { event.setCancelled(true); return; } } - public void teleportEvent(Player pl, Location fm, Location to, String reason) + public static enum TeleportType { + ENDER_PEARL, BED, VEHICLE, MISC + } + + public void teleportEvent(Player pl, Location fm, Location to, String reason, TeleportType type) { // cannot compare locations in different worlds if (fm.getWorld() != to.getWorld()) return; @@ -431,8 +469,9 @@ public void teleportEvent(Player pl, Location fm, Location to, String reason) for (Player ref : match.getReferees(excludeStreamers)) ref.sendMessage(message); } - public boolean enderPearlLegal(Player pl, Location fm, Location to, AutoRefMatch match) { + public boolean teleportationLegal(Player pl, Location fm, Location to, AutoRefMatch match, TeleportType type) { boolean def = true; + if(type == TeleportType.MISC) return def; // This is an experimental feature AutoReferee plugin = AutoReferee.getInstance(); if(!plugin.isExperimentalMode()) return def; @@ -441,15 +480,36 @@ public boolean enderPearlLegal(Player pl, Location fm, Location to, AutoRefMatch AutoRefTeam t = match.getPlayerTeam(pl); if(t == null) return def; - if( RegionGraph.unbreakableInRange(to, 1) != null ) + // Prevents teleporting through bedrock + if( RegionGraph.unbreakableInRange(to, 0) != null ) { return false; } - if(t.isRestrictedLoc(fm)) { + // Cannot teleport between regions + if(t.restrictedRegion(fm) != t.restrictedRegion(to)) { return false; - }else if(t.isRestrictedLoc(to)) { + } + + // Cannot teleport outside of lane + if(!t.containsLoc( to )) { return false; } + if(type == TeleportType.BED || type == TeleportType.VEHICLE) { + //if(match.isPracticeMode()) return def; + + plugin.getLogger().info(fm.distance(to) + ""); + + // cannot enter bed/vehicle from void lane + if(!t.containsLoc( fm )) { + return false; + } + + // cannot enter bed/vehicle from far distances + if(fm.distance(to) >= 1.5) { + return false; + } + } + return def; } @@ -480,14 +540,15 @@ public void playerTeleport(PlayerTeleportEvent event) { event.setCancelled(true); return; } if(event.getCause() == TeleportCause.ENDER_PEARL) { - if(!enderPearlLegal(event.getPlayer(), event.getFrom(), event.getTo(), match)) { + if(!teleportationLegal(event.getPlayer(), event.getFrom(), event.getTo(), match, TeleportType.ENDER_PEARL)) { event.getPlayer().sendMessage(ChatColor.RED + "Illegal pearl!"); event.setCancelled(true); return; } } String reason = "by " + event.getCause().name().toLowerCase().replaceAll("_", " "); - teleportEvent(event.getPlayer(), event.getFrom(), event.getTo(), reason); + teleportEvent(event.getPlayer(), event.getFrom(), event.getTo(), reason, + event.getCause() == TeleportCause.ENDER_PEARL ? TeleportType.ENDER_PEARL : TeleportType.MISC ); break; } @@ -522,16 +583,39 @@ public void playerVehicleEnter(VehicleEnterEvent event) for (Map.Entry, String> e : entityRenames.entrySet()) if (e.getKey().isAssignableFrom(clazz)) vehicleType = e.getValue(); - if (event.getEntered() instanceof Player) + AutoRefMatch match = plugin.getMatch(event.getVehicle().getWorld()); + if (match == null || match.getCurrentState() == MatchStatus.NONE) return; + + if (event.getEntered() instanceof Player) { + Player pl = (Player) event.getEntered(); Location fm = event.getEntered().getLocation(); + Location to = event.getVehicle().getLocation(); TeleportType type = TeleportType.VEHICLE; + + if(!teleportationLegal(pl, fm, to, match, type)) { + pl.sendMessage(ChatColor.RED + "Invalid teleport"); + event.setCancelled(true); return; + } + teleportEvent((Player) event.getEntered(), event.getEntered().getLocation(), - event.getVehicle().getLocation(), "into a " + vehicleType); + event.getVehicle().getLocation(), "into a " + vehicleType, TeleportType.VEHICLE); + } } @EventHandler(priority=EventPriority.MONITOR) public void playerBedEnter(PlayerBedEnterEvent event) { + AutoRefMatch match = plugin.getMatch(event.getPlayer().getWorld()); + if (match == null || match.getCurrentState() == MatchStatus.NONE) return; + + Player pl = event.getPlayer(); Location fm = event.getPlayer().getLocation(); + Location to = event.getBed().getLocation(); TeleportType type = TeleportType.BED; + + if(!teleportationLegal(pl, fm, to, match, type)) { + pl.sendMessage(ChatColor.RED + "Invalid teleport"); + event.setCancelled(true); return; + } + teleportEvent(event.getPlayer(), event.getPlayer().getLocation(), - event.getBed().getLocation(), "into a bed"); + event.getBed().getLocation(), "into a bed", TeleportType.BED); } @EventHandler diff --git a/src/main/java/org/mctourney/autoreferee/regions/AutoRefRegion.java b/src/main/java/org/mctourney/autoreferee/regions/AutoRefRegion.java index 43036def..2ff1ade5 100644 --- a/src/main/java/org/mctourney/autoreferee/regions/AutoRefRegion.java +++ b/src/main/java/org/mctourney/autoreferee/regions/AutoRefRegion.java @@ -104,7 +104,9 @@ public void announceRegion(AutoRefPlayer apl) } // these methods need to be implemented - public abstract double distanceToRegion(Location loc); + // NOTE: distanceToRegion is accessed by an async + // task and so MUST NOT ACCESS THE BUKKIT API + public abstract double distanceToRegion(double x, double y, double z); public abstract Location getRandomLocation(Random r); public abstract CuboidRegion getBoundingCuboid(); @@ -166,8 +168,10 @@ public Location getGroundedCenter() return loc; } + public double distanceToRegion(Location loc) { return this.distanceToRegion(loc.getX(), loc.getY(), loc.getZ()); } + public boolean contains(Location loc) - { return distanceToRegion(loc) <= 0.0; } + { return distanceToRegion(loc.getX(), loc.getY(), loc.getZ()) <= 0.0; } public boolean containsBlock(Block block) { return this.contains(block.getLocation().clone().add(0.5, 0.5, 0.5)); } diff --git a/src/main/java/org/mctourney/autoreferee/regions/CuboidRegion.java b/src/main/java/org/mctourney/autoreferee/regions/CuboidRegion.java index 914b4bb5..b431bf01 100644 --- a/src/main/java/org/mctourney/autoreferee/regions/CuboidRegion.java +++ b/src/main/java/org/mctourney/autoreferee/regions/CuboidRegion.java @@ -89,13 +89,13 @@ public static CuboidRegion combine(CuboidRegion a, CuboidRegion b) // distance from region, axially aligned (value less than actual distance, but // appropriate for measurements on cuboid regions) @Override - public double distanceToRegion(Location v) + public double distanceToRegion(double x, double y, double z) { - // garbage-in, garbage-out + /*// garbage-in, garbage-out if (v == null || v.getWorld() != world) - return Double.POSITIVE_INFINITY; + return Double.POSITIVE_INFINITY;*/ - double x = v.getX(), y = v.getY(), z = v.getZ(); + //double x = v.getX(), y = v.getY(), z = v.getZ(); Location mx = getMaximumPoint(), mn = getMinimumPoint(); // return maximum distance from this region diff --git a/src/main/java/org/mctourney/autoreferee/regions/CylinderRegion.java b/src/main/java/org/mctourney/autoreferee/regions/CylinderRegion.java index e91d991d..82f4c8f5 100644 --- a/src/main/java/org/mctourney/autoreferee/regions/CylinderRegion.java +++ b/src/main/java/org/mctourney/autoreferee/regions/CylinderRegion.java @@ -9,6 +9,7 @@ import org.mctourney.autoreferee.AutoRefMatch; import org.mctourney.autoreferee.util.LocationUtil; +import org.mctourney.autoreferee.util.MathUtil; public class CylinderRegion extends AutoRefRegion { @@ -39,10 +40,12 @@ public CylinderRegion(World world, Element elt) } @Override - public double distanceToRegion(Location loc) + public double distanceToRegion(double x0, double y0, double z0) { - return multimax(0, y - loc.getY(), loc.getY() - (y + h), - new Location(world, x, loc.getY(), z).distance(loc) - r); + double dist = MathUtil.dist(x, y, z, x0, y, z0); + + return multimax(0, y - y0, y0 - (y + h), + dist - r); } public Location getBase() diff --git a/src/main/java/org/mctourney/autoreferee/regions/PointRegion.java b/src/main/java/org/mctourney/autoreferee/regions/PointRegion.java index 60ffed54..508c9a8f 100644 --- a/src/main/java/org/mctourney/autoreferee/regions/PointRegion.java +++ b/src/main/java/org/mctourney/autoreferee/regions/PointRegion.java @@ -9,13 +9,16 @@ import org.mctourney.autoreferee.AutoRefMatch; import org.mctourney.autoreferee.util.LocationUtil; +import org.mctourney.autoreferee.util.MathUtil; public class PointRegion extends AutoRefRegion { Location pos = null; - + double x = 0; double y = 0; double z = 0; + public PointRegion(Location loc) - { this.pos = loc.getBlock().getLocation(); this.yaw = (int)loc.getYaw(); } + { this.pos = loc.getBlock().getLocation(); this.yaw = (int)loc.getYaw(); + this.x = pos.getX(); this.y = pos.getY(); this.z = pos.getY(); } public PointRegion(AutoRefMatch match, Element e) { this(match.getWorld(), e); } @@ -30,8 +33,8 @@ public Element toElement() } @Override - public double distanceToRegion(Location loc) - { return pos.distance(loc); } + public double distanceToRegion(double x0, double y0, double z0) + { return MathUtil.dist(x, y, z, x0, y0, z0); } @Override public Location getRandomLocation(Random r) diff --git a/src/main/java/org/mctourney/autoreferee/util/MathUtil.java b/src/main/java/org/mctourney/autoreferee/util/MathUtil.java new file mode 100644 index 00000000..feb5fd32 --- /dev/null +++ b/src/main/java/org/mctourney/autoreferee/util/MathUtil.java @@ -0,0 +1,7 @@ +package org.mctourney.autoreferee.util; + +public class MathUtil { + public static double dist( double x, double y, double z, double x0, double y0, double z0 ) { + return Math.sqrt( Math.pow(x - x0, 2) + Math.pow(y - y0, 2) + Math.pow(z - z0, 2) ); + } +} From 55450fc8afdb3cf6e79c0fd3f39084c0ceeb62d2 Mon Sep 17 00:00:00 2001 From: charburgx Date: Mon, 23 Mar 2020 19:35:33 -0400 Subject: [PATCH 12/13] Revertedd extraneous changes --- pom.xml | 18 +++++------ .../mctourney/autoreferee/AutoRefMatch.java | 10 +----- .../mctourney/autoreferee/AutoRefTeam.java | 4 +-- .../mctourney/autoreferee/AutoReferee.java | 10 ------ .../commands/ConfigurationCommands.java | 31 +------------------ .../autoreferee/listeners/ZoneListener.java | 2 -- .../autoreferee/regions/RegionGraph.java | 4 ++- src/main/resources/plugin.yml | 2 +- 8 files changed, 16 insertions(+), 65 deletions(-) diff --git a/pom.xml b/pom.xml index e357d0a4..c7c5c178 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ org.mctourney.autoreferee AutoReferee - 2.8.5 + 2.8.4 AutoReferee Core Plugin https://www.reddit.com/r/mctourney Bukkit plugin for automatically refereeing competitive Minecraft matches. @@ -17,7 +17,7 @@ UTF-8 1.8.8-R0.1-SNAPSHOT - 1.8 + 1.6 @@ -32,8 +32,8 @@ https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - sk89q - http://maven.sk89q.com/repo/ + sk89q-mvn2 + http://mvn2.sk89q.com/repo Plugin Metrics @@ -125,14 +125,14 @@ org.mcstats.bukkit metrics - R8-SNAPSHOT + R7 compile org.jgrapht - jgrapht-core - 1.4.0 + jgrapht-core + 1.4.0 @@ -237,7 +237,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.2 + 1.7 package @@ -266,4 +266,4 @@ - + \ No newline at end of file diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java index 2d52a2ec..70f7e408 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefMatch.java @@ -1199,8 +1199,6 @@ protected void loadWorldConfiguration() protected void clearScoreboardData(Scoreboard sb) { - if(!AutoReferee.getInstance().doScoreboard()) return; - // unregister all old objectives (created by AutoReferee) for (Objective obj : scoreboard.getObjectives()) if (obj.getName().startsWith("ar#")) obj.unregister(); @@ -1211,9 +1209,7 @@ protected void clearScoreboardData(Scoreboard sb) } protected void loadScoreboardData() - { - if(!AutoReferee.getInstance().doScoreboard()) return; - + { clearScoreboardData(scoreboard); clearScoreboardData( infoboard); @@ -1273,8 +1269,6 @@ public void saveScoreboardData() public void saveScoreboardData(Scoreboard sb) { - if(!AutoReferee.getInstance().doScoreboard()) return; - Element teams = new Element("teams"); for (Team team : sb.getTeams()) { @@ -1524,8 +1518,6 @@ private void parseExtraGameRules(Element gameplay) private void setupScoreboardObjectives() { - if(!AutoReferee.getInstance().doScoreboard()) return; - // defer to prevent exception on server start, // before any worlds are fully loaded new BukkitRunnable() diff --git a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java index 32bbbc9e..ae2346e0 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java +++ b/src/main/java/org/mctourney/autoreferee/AutoRefTeam.java @@ -599,9 +599,7 @@ public static AutoRefTeam create(AutoRefMatch match, String name, ChatColor colo } protected void setupScoreboard() - { - if(!AutoReferee.getInstance().doScoreboard()) return; - + { String sbteam = this.getScoreboardTeamName(); // set team data on spectators' scoreboard diff --git a/src/main/java/org/mctourney/autoreferee/AutoReferee.java b/src/main/java/org/mctourney/autoreferee/AutoReferee.java index b80c459b..94ab0ce8 100644 --- a/src/main/java/org/mctourney/autoreferee/AutoReferee.java +++ b/src/main/java/org/mctourney/autoreferee/AutoReferee.java @@ -499,16 +499,6 @@ public boolean isExperimentalMode() { return this.getConfig().getBoolean("experimental-mode", false); } - /** - * Get whether to create scoreboard or not - * @author char - * - * @return if to create scoreboard - */ - public boolean doScoreboard() { - return this.getConfig().getBoolean("scoreboard", true); - } - private class SyncMessageTask extends BukkitRunnable { private class RoutedMessage diff --git a/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java b/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java index f997fafe..720209ac 100644 --- a/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java +++ b/src/main/java/org/mctourney/autoreferee/commands/ConfigurationCommands.java @@ -551,6 +551,7 @@ public boolean arRegions(CommandSender sender, AutoRefMatch match, String[] args AutoRefTeam team = match.getTeam(args[0]); if(options.hasOption('r')) { + player.sendMessage("Computing Region Graph. This may take a while..."); //match.cancelGraphTask(); team.initRegionGraph(); team.computeRegionGraph(); @@ -634,36 +635,6 @@ public boolean arRegions(CommandSender sender, AutoRefMatch match, String[] args } } - return true; - } - - @AutoRefCommand(name= {"autoref", "test"}, argmin=1, argmax=1) - @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) - public boolean bruh(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { - if ( match == null ) return false; - Player p = (Player) sender; - - if(!p.isOp()) return false; - - WorldEditPlugin worldEdit = AutoReferee.getWorldEdit(); - if (worldEdit == null) - { - // world edit not installed - sender.sendMessage("This method requires WorldEdit installed and running."); - return true; - } - - Selection sel = worldEdit.getSelection(p); - if(sel == null || !(sel instanceof CuboidSelection)) return true; - CuboidSelection csel = (CuboidSelection) sel; - - AutoRefTeam team = match.getTeam(args[0]); - - Location pos = p.getLocation(); - pos.getBlock().setType(Material.WOOL); - - - return true; } } diff --git a/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java b/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java index 798f2d86..1aac9584 100644 --- a/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java +++ b/src/main/java/org/mctourney/autoreferee/listeners/ZoneListener.java @@ -497,8 +497,6 @@ public boolean teleportationLegal(Player pl, Location fm, Location to, AutoRefMa if(type == TeleportType.BED || type == TeleportType.VEHICLE) { //if(match.isPracticeMode()) return def; - plugin.getLogger().info(fm.distance(to) + ""); - // cannot enter bed/vehicle from void lane if(!t.containsLoc( fm )) { return false; diff --git a/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java b/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java index 81dbed95..cf8ca986 100644 --- a/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java +++ b/src/main/java/org/mctourney/autoreferee/regions/RegionGraph.java @@ -64,6 +64,8 @@ public RegionGraph computeGraph() { CuboidRegion bound = this.boundingBox(); if(bound == null) return this; + log("Creating a RegionGraph..."); + this.setLoaded(false); this.graph = new SimpleGraph(DefaultEdge.class); @@ -113,7 +115,7 @@ public RegionGraph computeGraph() { // useful for finding bedrock holes, and determining legality // of enderpearl teleports public RegionGraph findConnectedRegions() { - log("Computing a RegionGraph..."); + log("Computing connected regions in a RegionGraph..."); ConnectivityInspector conn = new ConnectivityInspector(this.graph()); List> components = conn.connectedSets(); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 052207b2..1910e541 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: AutoReferee main: org.mctourney.autoreferee.AutoReferee -version: 2.8.5 +version: 2.8.4 author: "authorblues, net" load: startup From 6a4aeb6d9e50baee057faab7d9aa23881fbb5d28 Mon Sep 17 00:00:00 2001 From: charburgx Date: Mon, 23 Mar 2020 19:46:01 -0400 Subject: [PATCH 13/13] Removed dependency-reduced-pom.xml --- dependency-reduced-pom.xml | 187 ------------------------------------- 1 file changed, 187 deletions(-) delete mode 100644 dependency-reduced-pom.xml diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml deleted file mode 100644 index df93b5cb..00000000 --- a/dependency-reduced-pom.xml +++ /dev/null @@ -1,187 +0,0 @@ - - - 4.0.0 - org.mctourney.autoreferee - AutoReferee - AutoReferee Core Plugin - 2.8.5 - Bukkit plugin for automatically refereeing competitive Minecraft matches. - https://www.reddit.com/r/mctourney - - scm:git:git://github.com/rmct/AutoReferee.git - scm:git:git@github.com:rmct/AutoReferee.git - https://github.com/rmct/AutoReferee - - - ${basedir}/src/main/java - - - . - true - ${basedir}/src/main/resources/ - - plugin.yml - colors.csv - autoreferee.properties - - - - defaults/ - true - ${basedir}/src/main/resources/ - - map.xml - config.yml - - - - webstats/ - ${basedir}/src/main/resources/webstats - - - - - org.codehaus.mojo - buildnumber-maven-plugin - 1.1 - - - validate - - create - - - - - - org.codehaus.mojo - exec-maven-plugin - 1.2.1 - - - - java - - - - - org.mctourney.autoreferee.AutoRefereeTools - - - - - - - maven-jar-plugin - 2.3.2 - - - - true - org.mctourney.autoreferee.AutoRefereeTools - - - - - - maven-surefire-plugin - 2.11 - - - maven-compiler-plugin - 2.3.2 - - ${java.target.version} - ${java.target.version} - true - true - true - - - - maven-shade-plugin - 3.2.2 - - - package - - shade - - - true - - - org.apache.commons:commons-lang3 - commons-io:commons-io - commons-codec:commons-codec - commons-cli:commons-cli - commons-collections:commons-collections - com.google.code.gson:gson - org.jdom:jdom2 - org.mcstats.bukkit:metrics - org.jgrapht:jgrapht-core - org.jheaps:jheaps - - - - - - - - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - sk89q - http://maven.sk89q.com/repo/ - - - Plugin Metrics - http://repo.mcstats.org/content/repositories/public - - - - - com.sk89q - worldedit - 5.3 - compile - - - spoutapi - org.spout - - - vanilla - org.spout - - - - - org.bukkit - bukkit - 1.8.8-R0.1-SNAPSHOT - provided - - - junit - junit - 4.8.1 - test - - - com.google.guava - guava - 14.0 - compile - - - - 1.8 - UTF-8 - 1.8.8-R0.1-SNAPSHOT - -