diff --git a/pom.xml b/pom.xml
index 1b9e391..f18c8e7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -33,6 +33,7 @@
8
+ -Xlint
diff --git a/src/de/steamwar/lobby/servers/Fightserver.java b/src/de/steamwar/lobby/Fightserver.java
similarity index 58%
rename from src/de/steamwar/lobby/servers/Fightserver.java
rename to src/de/steamwar/lobby/Fightserver.java
index 3c3d468..85a869a 100644
--- a/src/de/steamwar/lobby/servers/Fightserver.java
+++ b/src/de/steamwar/lobby/Fightserver.java
@@ -17,10 +17,11 @@
* along with this program. If not, see .
*/
-package de.steamwar.lobby.servers;
+package de.steamwar.lobby;
import com.google.common.io.ByteArrayDataInput;
import de.steamwar.comms.packets.FightInfoPacket;
+import de.steamwar.lobby.portal.FightserverPortal;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
@@ -29,42 +30,8 @@ import java.util.function.Consumer;
public class Fightserver {
- private static final List> listeners = new ArrayList<>();
-
- public static void registerListener(Consumer listener) {
- listeners.add(listener);
- }
-
private static final Map servers = new HashMap<>();
- private Instant lastUpdate;
- private final String serverName;
- private final String gameMode;
- private final Observable> bluePlayers = new Observable<>();
- private final Observable> redPlayers = new Observable<>();
- private final Observable playerCount = new Observable<>();
-
- private Fightserver(FightInfoPacket fightInfo) {
- serverName = fightInfo.getServerName();
- gameMode = fightInfo.getGameMode();
-
- update(fightInfo);
- listeners.forEach(listener -> listener.accept(this));
-
- servers.put(serverName, this);
- }
-
- private void update(FightInfoPacket fightInfo) {
- bluePlayers.update(new HashSet<>(fightInfo.getBluePlayers()));
- redPlayers.update(new HashSet<>(fightInfo.getRedPlayers()));
- playerCount.update(fightInfo.getBluePlayers().size() + fightInfo.getRedPlayers().size() + fightInfo.getSpectators().size());
- lastUpdate = Instant.now();
- }
-
- private void remove() {
-
- }
-
public static void newFightInfo(ByteArrayDataInput in) {
FightInfoPacket fightInfo = new FightInfoPacket(in);
Fightserver server = servers.get(fightInfo.getServerName());
@@ -87,4 +54,62 @@ public class Fightserver {
}
}
}
+
+ private final List portals = new ArrayList<>();
+
+ private FightInfoPacket fightInfo;
+ private Instant lastUpdate;
+
+ private Fightserver(FightInfoPacket fightInfo) {
+ this.fightInfo = fightInfo;
+
+ update(fightInfo);
+
+ setupPortal(getGameMode().toLowerCase());
+ setupPortal("all");
+
+ servers.put(getServerName(), this);
+ }
+
+ private void setupPortal(String gameMode) {
+ FightserverPortal portal = FightserverPortal.findFree(gameMode);
+ if(portal == null)
+ return;
+
+ portals.add(portal);
+ portal.setServer(this);
+ }
+
+ public String getGameMode() {
+ return fightInfo.getGameMode();
+ }
+
+ public String getServerName() {
+ return fightInfo.getServerName();
+ }
+
+ public FightInfoPacket current() {
+ return fightInfo;
+ }
+
+ private void update(FightInfoPacket fightInfo) {
+ FightInfoPacket old = this.fightInfo;
+ this.fightInfo = fightInfo;
+ lastUpdate = Instant.now();
+
+ update(old.getBluePlayers(), fightInfo.getBluePlayers(), FightserverPortal::updateBluePlayers);
+ update(old.getRedPlayers(), fightInfo.getRedPlayers(), FightserverPortal::updateRedPlayers);
+ update(old.getCountdown(), fightInfo.getCountdown(), FightserverPortal::updateText);
+ update(old.getFightState(), fightInfo.getFightState(), FightserverPortal::updateText);
+ }
+
+ private void update(T old, T current, Consumer observer) {
+ if(!old.equals(current))
+ portals.forEach(observer);
+ }
+
+ private void remove() {
+ portals.forEach(portal -> portal.setServer(null));
+ portals.clear();
+ }
}
diff --git a/src/de/steamwar/lobby/command/HologramCommand.java b/src/de/steamwar/lobby/command/HologramCommand.java
index fb38db4..15832b0 100644
--- a/src/de/steamwar/lobby/command/HologramCommand.java
+++ b/src/de/steamwar/lobby/command/HologramCommand.java
@@ -57,7 +57,11 @@ public class HologramCommand extends SWCommand {
public void portalDelete(Player player, String id) {
if (PortalCommand.noPermissions(player)) return;
- Hologram.getHologram(id).delete();
+ Hologram hologram = Hologram.getHologram(id);
+ if (hologram == null)
+ return;
+
+ hologram.delete();
LobbySystem.config().save();
}
}
diff --git a/src/de/steamwar/lobby/command/PortalCommand.java b/src/de/steamwar/lobby/command/PortalCommand.java
index 989a516..c8c6942 100644
--- a/src/de/steamwar/lobby/command/PortalCommand.java
+++ b/src/de/steamwar/lobby/command/PortalCommand.java
@@ -52,44 +52,33 @@ public class PortalCommand extends SWCommand {
@Register({"create", "command"})
public void portalAddCommand(Player player, String portalName, String... command) {
if (noPermissions(player)) return;
- Tuple tuple = getSelection(player);
- if (tuple == null) {
- LobbySystem.getMessage().send("PORTAL_NO_WORLDEDIT_SELECTION", player);
- return;
- }
+ PortalLocations tuple = getSelection(player);
+ if (tuple == null) return;
new Portal(portalName, tuple.k, tuple.v, portal -> new CommandPortal(String.join(" ", command)));
}
- @Register({"create", "fightserver"})
- public void portalAddFightserver(Player player, String portalName, String group, String target) {
+ @Register({"create", "fight"})
+ public void portalAddFightserver(Player player, String portalName, String gamemode, int order, String target) {
if (noPermissions(player)) return;
- Tuple tuple = getSelection(player);
- if (tuple == null) {
- LobbySystem.getMessage().send("PORTAL_NO_WORLDEDIT_SELECTION", player);
- return;
- }
- new Portal(portalName, tuple.k, tuple.v, portal -> new FightserverPortal(portal, group, target));
+ PortalLocations tuple = getSelection(player);
+ if (tuple == null) return;
+ new Portal(portalName, tuple.k, tuple.v, portal -> new FightserverPortal(portal, gamemode.toLowerCase(), order, target));
}
@Register({"create", "teleport"})
public void portalAddTeleport(Player player, String portalName, String portalDestination) {
if (noPermissions(player)) return;
- Tuple tuple = getSelection(player);
- if (tuple == null) {
- LobbySystem.getMessage().send("PORTAL_NO_WORLDEDIT_SELECTION", player);
- return;
- }
+ PortalLocations tuple = getSelection(player);
+ if (tuple == null) return;
new Portal(portalName, tuple.k, tuple.v, portal -> new TeleportPortal(portal, portalDestination));
}
@Register({"create", "stack"})
public void portalAddStack(Player player, String portalName, String portalDestination, String... command) {
if (noPermissions(player)) return;
- Tuple tuple = getSelection(player);
- if (tuple == null) {
- LobbySystem.getMessage().send("PORTAL_NO_WORLDEDIT_SELECTION", player);
- return;
- }
+ PortalLocations tuple = getSelection(player);
+ if (tuple == null) return;
+
new Portal(portalName, tuple.k, tuple.v, portal -> new StackPortal(portal, portalDestination, String.join(" ", command)));
}
@@ -115,12 +104,12 @@ public class PortalCommand extends SWCommand {
}
@Data
- private static class Tuple {
- private final K k;
- private final V v;
+ private static class PortalLocations {
+ private final Location k;
+ private final Location v;
}
- private Tuple getSelection(Player player) {
+ private PortalLocations getSelection(Player player) {
RegionSelector regionSelector = WorldEdit.getInstance()
.getSessionManager()
.get(BukkitAdapter.adapt(player))
@@ -128,8 +117,9 @@ public class PortalCommand extends SWCommand {
try {
CuboidRegion region = (CuboidRegion)regionSelector.getRegion();
- return new Tuple<>(adapt(player.getWorld(), region.getPos1()), adapt(player.getWorld(), region.getPos2()));
+ return new PortalLocations(adapt(player.getWorld(), region.getPos1()), adapt(player.getWorld(), region.getPos2()));
} catch (IncompleteRegionException e) {
+ LobbySystem.getMessage().send("PORTAL_NO_WORLDEDIT_SELECTION", player);
return null;
}
}
diff --git a/src/de/steamwar/lobby/display/Displayable.java b/src/de/steamwar/lobby/display/Displayable.java
index 52ab923..b84ca97 100644
--- a/src/de/steamwar/lobby/display/Displayable.java
+++ b/src/de/steamwar/lobby/display/Displayable.java
@@ -51,6 +51,10 @@ public class Displayable extends BasicListener {
Bukkit.getOnlinePlayers().forEach(player -> checkLocation(player, player.getLocation()));
}
+ public Set getVisitors() {
+ return visible;
+ }
+
@EventHandler
public void onJoin(PlayerJoinEvent e) {
checkLocation(e.getPlayer(), e.getPlayer().getLocation());
@@ -63,7 +67,7 @@ public class Displayable extends BasicListener {
private void checkLocation(Player player, Location at) {
boolean shown = visible.contains(player);
- int viewDistance = player.getClientViewDistance();
+ int viewDistance = player.getClientViewDistance() / 2;
boolean see = Math.abs(chunkX - posToChunk(at.getX())) < viewDistance && Math.abs(chunkZ - posToChunk(at.getZ())) < viewDistance;
if(!shown && see) {
diff --git a/src/de/steamwar/lobby/display/Hologram.java b/src/de/steamwar/lobby/display/Hologram.java
index 537eafb..c032d18 100644
--- a/src/de/steamwar/lobby/display/Hologram.java
+++ b/src/de/steamwar/lobby/display/Hologram.java
@@ -20,7 +20,7 @@
package de.steamwar.lobby.display;
import com.comphenix.tinyprotocol.Reflection;
-import de.steamwar.lobby.listener.Protocol;
+import com.comphenix.tinyprotocol.TinyProtocol;
import org.bukkit.Location;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Player;
@@ -80,9 +80,19 @@ public class Hologram implements ConfigurationSerializable {
private static final Class> destroyPacket = Reflection.getClass("{nms}.PacketPlayOutEntityDestroy");
private static final Reflection.ConstructorInvoker destoryPacketConstructor = Reflection.getConstructor(destroyPacket);
private static final Reflection.FieldAccessor destroyIds = Reflection.getField(destroyPacket, int[].class, 0);
+ public static Object destroyPacket(int entityId) {
+ Object destroy = destoryPacketConstructor.invoke();
+ destroyIds.set(destroy, new int[]{entityId});
+ return destroy;
+ }
+
+ private static int entityIds = -1;
+ public static int createEntityId() {
+ return entityIds--;
+ }
private static final Map holograms = new HashMap<>();
- private static int entityIds = -1;
+
private static final Random random = new Random();
public static List getHolograms() {
@@ -94,11 +104,15 @@ public class Hologram implements ConfigurationSerializable {
private final Displayable display;
private final int entityId;
+
private final Object spawnLiving;
+ private Object metadata;
private final Object destroy;
+
private final String id;
private final Location location;
- private final String text;
+
+ private String text;
public Hologram(Map map) {
this((String) map.get("id"), (Location) map.get("location"), (String) map.get("text"));
@@ -108,7 +122,7 @@ public class Hologram implements ConfigurationSerializable {
this.id = id;
this.location = location;
this.text = text;
- entityId = entityIds--;
+ entityId = createEntityId();
spawnLiving = spawnLivingPacketConstructor.invoke();
spawnLivingEntityId.set(spawnLiving, entityId);
@@ -118,8 +132,9 @@ public class Hologram implements ConfigurationSerializable {
spawnLivingEntityY.set(spawnLiving, location.getY());
spawnLivingEntityZ.set(spawnLiving, location.getZ());
- destroy = destoryPacketConstructor.invoke();
- destroyIds.set(destroy, new int[]{entityId});
+ constructMetadataPacket();
+
+ destroy = destroyPacket(entityId);
display = new Displayable(location, this::show, this::hide);
@@ -127,22 +142,32 @@ public class Hologram implements ConfigurationSerializable {
holograms.put(id, this);
}
- private void show(Player player) {
- Protocol.getTinyProtocol().sendPacket(player, spawnLiving);
+ public void updateText(String text) {
+ this.text = text;
+ constructMetadataPacket();
+ for(Player player : display.getVisitors()) {
+ TinyProtocol.instance.sendPacket(player, metadata);
+ }
+ }
- Object packet = metadataConstructor.invoke();
- metadataEntity.set(packet, entityId);
+ private void constructMetadataPacket() {
+ metadata = metadataConstructor.invoke();
+ metadataEntity.set(metadata, entityId);
List