WIP Fightserverportale
Dieser Commit ist enthalten in:
Ursprung
5dddb69484
Commit
ecf813c809
1
pom.xml
1
pom.xml
@ -33,6 +33,7 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<source>8</source>
|
<source>8</source>
|
||||||
<target>8</target>
|
<target>8</target>
|
||||||
|
<compilerArgs>-Xlint</compilerArgs>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
@ -17,10 +17,11 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.steamwar.lobby.servers;
|
package de.steamwar.lobby;
|
||||||
|
|
||||||
import com.google.common.io.ByteArrayDataInput;
|
import com.google.common.io.ByteArrayDataInput;
|
||||||
import de.steamwar.comms.packets.FightInfoPacket;
|
import de.steamwar.comms.packets.FightInfoPacket;
|
||||||
|
import de.steamwar.lobby.portal.FightserverPortal;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
@ -29,42 +30,8 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
public class Fightserver {
|
public class Fightserver {
|
||||||
|
|
||||||
private static final List<Consumer<Fightserver>> listeners = new ArrayList<>();
|
|
||||||
|
|
||||||
public static void registerListener(Consumer<Fightserver> listener) {
|
|
||||||
listeners.add(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Map<String, Fightserver> servers = new HashMap<>();
|
private static final Map<String, Fightserver> servers = new HashMap<>();
|
||||||
|
|
||||||
private Instant lastUpdate;
|
|
||||||
private final String serverName;
|
|
||||||
private final String gameMode;
|
|
||||||
private final Observable<Set<Integer>> bluePlayers = new Observable<>();
|
|
||||||
private final Observable<Set<Integer>> redPlayers = new Observable<>();
|
|
||||||
private final Observable<Integer> 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) {
|
public static void newFightInfo(ByteArrayDataInput in) {
|
||||||
FightInfoPacket fightInfo = new FightInfoPacket(in);
|
FightInfoPacket fightInfo = new FightInfoPacket(in);
|
||||||
Fightserver server = servers.get(fightInfo.getServerName());
|
Fightserver server = servers.get(fightInfo.getServerName());
|
||||||
@ -87,4 +54,62 @@ public class Fightserver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final List<FightserverPortal> 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 <T> void update(T old, T current, Consumer<FightserverPortal> observer) {
|
||||||
|
if(!old.equals(current))
|
||||||
|
portals.forEach(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void remove() {
|
||||||
|
portals.forEach(portal -> portal.setServer(null));
|
||||||
|
portals.clear();
|
||||||
|
}
|
||||||
}
|
}
|
@ -57,7 +57,11 @@ public class HologramCommand extends SWCommand {
|
|||||||
public void portalDelete(Player player, String id) {
|
public void portalDelete(Player player, String id) {
|
||||||
if (PortalCommand.noPermissions(player)) return;
|
if (PortalCommand.noPermissions(player)) return;
|
||||||
|
|
||||||
Hologram.getHologram(id).delete();
|
Hologram hologram = Hologram.getHologram(id);
|
||||||
|
if (hologram == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hologram.delete();
|
||||||
LobbySystem.config().save();
|
LobbySystem.config().save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,44 +52,33 @@ public class PortalCommand extends SWCommand {
|
|||||||
@Register({"create", "command"})
|
@Register({"create", "command"})
|
||||||
public void portalAddCommand(Player player, String portalName, String... command) {
|
public void portalAddCommand(Player player, String portalName, String... command) {
|
||||||
if (noPermissions(player)) return;
|
if (noPermissions(player)) return;
|
||||||
Tuple<Location, Location> tuple = getSelection(player);
|
PortalLocations tuple = getSelection(player);
|
||||||
if (tuple == null) {
|
if (tuple == null) return;
|
||||||
LobbySystem.getMessage().send("PORTAL_NO_WORLDEDIT_SELECTION", player);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
new Portal(portalName, tuple.k, tuple.v, portal -> new CommandPortal(String.join(" ", command)));
|
new Portal(portalName, tuple.k, tuple.v, portal -> new CommandPortal(String.join(" ", command)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register({"create", "fightserver"})
|
@Register({"create", "fight"})
|
||||||
public void portalAddFightserver(Player player, String portalName, String group, String target) {
|
public void portalAddFightserver(Player player, String portalName, String gamemode, int order, String target) {
|
||||||
if (noPermissions(player)) return;
|
if (noPermissions(player)) return;
|
||||||
Tuple<Location, Location> tuple = getSelection(player);
|
PortalLocations tuple = getSelection(player);
|
||||||
if (tuple == null) {
|
if (tuple == null) return;
|
||||||
LobbySystem.getMessage().send("PORTAL_NO_WORLDEDIT_SELECTION", player);
|
new Portal(portalName, tuple.k, tuple.v, portal -> new FightserverPortal(portal, gamemode.toLowerCase(), order, target));
|
||||||
return;
|
|
||||||
}
|
|
||||||
new Portal(portalName, tuple.k, tuple.v, portal -> new FightserverPortal(portal, group, target));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register({"create", "teleport"})
|
@Register({"create", "teleport"})
|
||||||
public void portalAddTeleport(Player player, String portalName, String portalDestination) {
|
public void portalAddTeleport(Player player, String portalName, String portalDestination) {
|
||||||
if (noPermissions(player)) return;
|
if (noPermissions(player)) return;
|
||||||
Tuple<Location, Location> tuple = getSelection(player);
|
PortalLocations tuple = getSelection(player);
|
||||||
if (tuple == null) {
|
if (tuple == null) return;
|
||||||
LobbySystem.getMessage().send("PORTAL_NO_WORLDEDIT_SELECTION", player);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
new Portal(portalName, tuple.k, tuple.v, portal -> new TeleportPortal(portal, portalDestination));
|
new Portal(portalName, tuple.k, tuple.v, portal -> new TeleportPortal(portal, portalDestination));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register({"create", "stack"})
|
@Register({"create", "stack"})
|
||||||
public void portalAddStack(Player player, String portalName, String portalDestination, String... command) {
|
public void portalAddStack(Player player, String portalName, String portalDestination, String... command) {
|
||||||
if (noPermissions(player)) return;
|
if (noPermissions(player)) return;
|
||||||
Tuple<Location, Location> tuple = getSelection(player);
|
PortalLocations tuple = getSelection(player);
|
||||||
if (tuple == null) {
|
if (tuple == null) return;
|
||||||
LobbySystem.getMessage().send("PORTAL_NO_WORLDEDIT_SELECTION", player);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
new Portal(portalName, tuple.k, tuple.v, portal -> new StackPortal(portal, portalDestination, String.join(" ", command)));
|
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
|
@Data
|
||||||
private static class Tuple<K, V> {
|
private static class PortalLocations {
|
||||||
private final K k;
|
private final Location k;
|
||||||
private final V v;
|
private final Location v;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Tuple<Location, Location> getSelection(Player player) {
|
private PortalLocations getSelection(Player player) {
|
||||||
RegionSelector regionSelector = WorldEdit.getInstance()
|
RegionSelector regionSelector = WorldEdit.getInstance()
|
||||||
.getSessionManager()
|
.getSessionManager()
|
||||||
.get(BukkitAdapter.adapt(player))
|
.get(BukkitAdapter.adapt(player))
|
||||||
@ -128,8 +117,9 @@ public class PortalCommand extends SWCommand {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
CuboidRegion region = (CuboidRegion)regionSelector.getRegion();
|
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) {
|
} catch (IncompleteRegionException e) {
|
||||||
|
LobbySystem.getMessage().send("PORTAL_NO_WORLDEDIT_SELECTION", player);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,10 @@ public class Displayable extends BasicListener {
|
|||||||
Bukkit.getOnlinePlayers().forEach(player -> checkLocation(player, player.getLocation()));
|
Bukkit.getOnlinePlayers().forEach(player -> checkLocation(player, player.getLocation()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Player> getVisitors() {
|
||||||
|
return visible;
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onJoin(PlayerJoinEvent e) {
|
public void onJoin(PlayerJoinEvent e) {
|
||||||
checkLocation(e.getPlayer(), e.getPlayer().getLocation());
|
checkLocation(e.getPlayer(), e.getPlayer().getLocation());
|
||||||
@ -63,7 +67,7 @@ public class Displayable extends BasicListener {
|
|||||||
|
|
||||||
private void checkLocation(Player player, Location at) {
|
private void checkLocation(Player player, Location at) {
|
||||||
boolean shown = visible.contains(player);
|
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;
|
boolean see = Math.abs(chunkX - posToChunk(at.getX())) < viewDistance && Math.abs(chunkZ - posToChunk(at.getZ())) < viewDistance;
|
||||||
|
|
||||||
if(!shown && see) {
|
if(!shown && see) {
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
package de.steamwar.lobby.display;
|
package de.steamwar.lobby.display;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.Reflection;
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import de.steamwar.lobby.listener.Protocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||||
import org.bukkit.entity.Player;
|
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 Class<?> destroyPacket = Reflection.getClass("{nms}.PacketPlayOutEntityDestroy");
|
||||||
private static final Reflection.ConstructorInvoker destoryPacketConstructor = Reflection.getConstructor(destroyPacket);
|
private static final Reflection.ConstructorInvoker destoryPacketConstructor = Reflection.getConstructor(destroyPacket);
|
||||||
private static final Reflection.FieldAccessor<int[]> destroyIds = Reflection.getField(destroyPacket, int[].class, 0);
|
private static final Reflection.FieldAccessor<int[]> 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<String, Hologram> holograms = new HashMap<>();
|
private static final Map<String, Hologram> holograms = new HashMap<>();
|
||||||
private static int entityIds = -1;
|
|
||||||
private static final Random random = new Random();
|
private static final Random random = new Random();
|
||||||
|
|
||||||
public static List<Hologram> getHolograms() {
|
public static List<Hologram> getHolograms() {
|
||||||
@ -94,11 +104,15 @@ public class Hologram implements ConfigurationSerializable {
|
|||||||
|
|
||||||
private final Displayable display;
|
private final Displayable display;
|
||||||
private final int entityId;
|
private final int entityId;
|
||||||
|
|
||||||
private final Object spawnLiving;
|
private final Object spawnLiving;
|
||||||
|
private Object metadata;
|
||||||
private final Object destroy;
|
private final Object destroy;
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
private final Location location;
|
private final Location location;
|
||||||
private final String text;
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
public Hologram(Map<String, Object> map) {
|
public Hologram(Map<String, Object> map) {
|
||||||
this((String) map.get("id"), (Location) map.get("location"), (String) map.get("text"));
|
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.id = id;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
entityId = entityIds--;
|
entityId = createEntityId();
|
||||||
|
|
||||||
spawnLiving = spawnLivingPacketConstructor.invoke();
|
spawnLiving = spawnLivingPacketConstructor.invoke();
|
||||||
spawnLivingEntityId.set(spawnLiving, entityId);
|
spawnLivingEntityId.set(spawnLiving, entityId);
|
||||||
@ -118,8 +132,9 @@ public class Hologram implements ConfigurationSerializable {
|
|||||||
spawnLivingEntityY.set(spawnLiving, location.getY());
|
spawnLivingEntityY.set(spawnLiving, location.getY());
|
||||||
spawnLivingEntityZ.set(spawnLiving, location.getZ());
|
spawnLivingEntityZ.set(spawnLiving, location.getZ());
|
||||||
|
|
||||||
destroy = destoryPacketConstructor.invoke();
|
constructMetadataPacket();
|
||||||
destroyIds.set(destroy, new int[]{entityId});
|
|
||||||
|
destroy = destroyPacket(entityId);
|
||||||
|
|
||||||
display = new Displayable(location, this::show, this::hide);
|
display = new Displayable(location, this::show, this::hide);
|
||||||
|
|
||||||
@ -127,22 +142,32 @@ public class Hologram implements ConfigurationSerializable {
|
|||||||
holograms.put(id, this);
|
holograms.put(id, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void show(Player player) {
|
public void updateText(String text) {
|
||||||
Protocol.getTinyProtocol().sendPacket(player, spawnLiving);
|
this.text = text;
|
||||||
|
constructMetadataPacket();
|
||||||
|
for(Player player : display.getVisitors()) {
|
||||||
|
TinyProtocol.instance.sendPacket(player, metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Object packet = metadataConstructor.invoke();
|
private void constructMetadataPacket() {
|
||||||
metadataEntity.set(packet, entityId);
|
metadata = metadataConstructor.invoke();
|
||||||
|
metadataEntity.set(metadata, entityId);
|
||||||
List<Object> watchers = new ArrayList<>();
|
List<Object> watchers = new ArrayList<>();
|
||||||
watchers.add(itemConstructor.invoke(invisibleWatcher, (byte) 0x20));
|
watchers.add(itemConstructor.invoke(invisibleWatcher, (byte) 0x20));
|
||||||
watchers.add(itemConstructor.invoke(nameWatcher, Optional.of(chatComponentTextConstructor.invoke(text))));
|
watchers.add(itemConstructor.invoke(nameWatcher, Optional.of(chatComponentTextConstructor.invoke(text))));
|
||||||
watchers.add(itemConstructor.invoke(nameVisibleWatcher, true));
|
watchers.add(itemConstructor.invoke(nameVisibleWatcher, true));
|
||||||
watchers.add(itemConstructor.invoke(sizeWatcher, (byte) 0x10));
|
watchers.add(itemConstructor.invoke(sizeWatcher, (byte) 0x10));
|
||||||
metadataMetadata.set(packet, watchers);
|
metadataMetadata.set(metadata, watchers);
|
||||||
Protocol.getTinyProtocol().sendPacket(player, packet);
|
}
|
||||||
|
|
||||||
|
private void show(Player player) {
|
||||||
|
TinyProtocol.instance.sendPacket(player, spawnLiving);
|
||||||
|
TinyProtocol.instance.sendPacket(player, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hide(Player player) {
|
private void hide(Player player) {
|
||||||
Protocol.getTinyProtocol().sendPacket(player, destroy);
|
TinyProtocol.instance.sendPacket(player, destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
110
src/de/steamwar/lobby/display/NPC.java
Normale Datei
110
src/de/steamwar/lobby/display/NPC.java
Normale Datei
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.lobby.display;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class NPC {
|
||||||
|
private static final Class<?> playerInfoPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPlayerInfo");
|
||||||
|
private static final Reflection.ConstructorInvoker playerInfoConstructor = Reflection.getConstructor(playerInfoPacket);
|
||||||
|
private static final Class<?> playerInfoActionClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPlayerInfo$EnumPlayerInfoAction");
|
||||||
|
private static final Object addPlayer = playerInfoActionClass.getEnumConstants()[0];
|
||||||
|
private static final Reflection.FieldAccessor<?> playerInfoAction = Reflection.getField(playerInfoPacket, playerInfoActionClass, 0);
|
||||||
|
private static final Object removePlayer = playerInfoActionClass.getEnumConstants()[4];
|
||||||
|
private static final Reflection.FieldAccessor<List> playerInfoData = Reflection.getField(playerInfoPacket, List.class, 0);
|
||||||
|
private static final Class<?> playerInfoDataClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPlayerInfo$PlayerInfoData");
|
||||||
|
private static final Class<?> enumGamemode = Reflection.getClass("{nms.world.level}.EnumGamemode");
|
||||||
|
private static final Object creative = enumGamemode.getEnumConstants()[2];
|
||||||
|
private static final Class<?> iChatBaseComponent = Reflection.getClass("{nms.network.chat}.IChatBaseComponent");
|
||||||
|
private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(playerInfoDataClass, playerInfoPacket, GameProfile.class, int.class, enumGamemode, iChatBaseComponent);
|
||||||
|
private static Object playerInfoPacket(Object action, GameProfile profile) {
|
||||||
|
Object packet = playerInfoConstructor.invoke();
|
||||||
|
playerInfoAction.set(packet, action);
|
||||||
|
playerInfoData.set(packet, Collections.singletonList(playerInfoDataConstructor.invoke(packet, profile, 0, creative, null)));
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Class<?> namedSpawnPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutNamedEntitySpawn");
|
||||||
|
private static final Reflection.ConstructorInvoker namedSpawnConstructor = Reflection.getConstructor(namedSpawnPacket);
|
||||||
|
private static final Reflection.FieldAccessor<Integer> namedSpawnEntity = Reflection.getField(namedSpawnPacket, int.class, 0);
|
||||||
|
private static final Reflection.FieldAccessor<UUID> namedSpawnUUID = Reflection.getField(namedSpawnPacket, UUID.class, 0);
|
||||||
|
private static final Reflection.FieldAccessor<Double> namedSpawnX = Reflection.getField(namedSpawnPacket, double.class, 0);
|
||||||
|
private static final Reflection.FieldAccessor<Double> namedSpawnY = Reflection.getField(namedSpawnPacket, double.class, 1);
|
||||||
|
private static final Reflection.FieldAccessor<Double> namedSpawnZ = Reflection.getField(namedSpawnPacket, double.class, 2);
|
||||||
|
private static final Reflection.FieldAccessor<Byte> namedSpawnYaw = Reflection.getField(namedSpawnPacket, byte.class, 0);
|
||||||
|
private static final Reflection.FieldAccessor<Byte> namedSpawnPitch = Reflection.getField(namedSpawnPacket, byte.class, 1);
|
||||||
|
|
||||||
|
private final Displayable display;
|
||||||
|
|
||||||
|
private final int entityId;
|
||||||
|
private final UUID uuid;
|
||||||
|
private final String name;
|
||||||
|
private final Location location;
|
||||||
|
|
||||||
|
private final Object addPlayerInfo;
|
||||||
|
private final Object namedSpawn;
|
||||||
|
private final Object removePlayerInfo;
|
||||||
|
private final Object destroy;
|
||||||
|
|
||||||
|
public NPC(Location location, UUID uuid, String name) {
|
||||||
|
this.entityId = Hologram.createEntityId();
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.name = name;
|
||||||
|
this.location = location;
|
||||||
|
|
||||||
|
GameProfile profile = new GameProfile(uuid, name);
|
||||||
|
addPlayerInfo = playerInfoPacket(addPlayer, profile);
|
||||||
|
removePlayerInfo = playerInfoPacket(removePlayer, profile);
|
||||||
|
destroy = Hologram.destroyPacket(entityId);
|
||||||
|
|
||||||
|
namedSpawn = namedSpawnConstructor.invoke();
|
||||||
|
namedSpawnEntity.set(namedSpawn, entityId);
|
||||||
|
namedSpawnUUID.set(namedSpawn, uuid);
|
||||||
|
namedSpawnX.set(namedSpawn, location.getX());
|
||||||
|
namedSpawnY.set(namedSpawn, location.getY());
|
||||||
|
namedSpawnZ.set(namedSpawn, location.getZ());
|
||||||
|
namedSpawnYaw.set(namedSpawn, (byte)(int)(location.getYaw() * 256.0 / 360.0));
|
||||||
|
namedSpawnPitch.set(namedSpawn, (byte)(int)(location.getPitch() * 256.0 / 360.0));
|
||||||
|
|
||||||
|
display = new Displayable(location, this::show, this::hide);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void show(Player player) {
|
||||||
|
TinyProtocol.instance.sendPacket(player, addPlayerInfo);
|
||||||
|
TinyProtocol.instance.sendPacket(player, namedSpawn);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hide(Player player) {
|
||||||
|
TinyProtocol.instance.sendPacket(player, removePlayerInfo);
|
||||||
|
TinyProtocol.instance.sendPacket(player, destroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
display.delete();
|
||||||
|
}
|
||||||
|
}
|
@ -22,7 +22,7 @@ package de.steamwar.lobby.listener;
|
|||||||
import de.steamwar.comms.BungeeReceiver;
|
import de.steamwar.comms.BungeeReceiver;
|
||||||
import de.steamwar.comms.PacketIdManager;
|
import de.steamwar.comms.PacketIdManager;
|
||||||
import de.steamwar.lobby.LobbySystem;
|
import de.steamwar.lobby.LobbySystem;
|
||||||
import de.steamwar.lobby.servers.Fightserver;
|
import de.steamwar.lobby.Fightserver;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
public class Fightservers {
|
public class Fightservers {
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.lobby.listener;
|
package de.steamwar.lobby.listener;
|
||||||
|
|
||||||
|
import de.steamwar.comms.packets.ImALobbyPacket;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@ -33,6 +34,6 @@ public class Join extends BasicListener {
|
|||||||
player.setGameMode(GameMode.ADVENTURE);
|
player.setGameMode(GameMode.ADVENTURE);
|
||||||
player.setWalkSpeed(0.5f);
|
player.setWalkSpeed(0.5f);
|
||||||
|
|
||||||
//new ImALobbyPacket().send(player);
|
new ImALobbyPacket().send(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ public class Portals extends BasicListener {
|
|||||||
Location to = e.getTo();
|
Location to = e.getTo();
|
||||||
assert to != null;
|
assert to != null;
|
||||||
|
|
||||||
Portal portal = Portal.getPortal(e.getPlayer(), from, to);
|
Portal portal = Portal.getPortal(from, to);
|
||||||
if (portal == null)
|
if (portal == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2021 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.lobby.listener;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import de.steamwar.lobby.LobbySystem;
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class Protocol {
|
|
||||||
|
|
||||||
private static final TinyProtocol tinyProtocol = new TinyProtocol(LobbySystem.getPlugin()) {
|
|
||||||
@Override
|
|
||||||
public Object onPacketOutAsync(Player receiver, Channel channel, Object packet) {
|
|
||||||
return super.onPacketOutAsync(receiver, channel, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object onPacketInAsync(Player sender, Channel channel, Object packet) {
|
|
||||||
return super.onPacketInAsync(sender, channel, packet);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static TinyProtocol getTinyProtocol() {
|
|
||||||
return tinyProtocol;
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,37 +19,93 @@
|
|||||||
|
|
||||||
package de.steamwar.lobby.portal;
|
package de.steamwar.lobby.portal;
|
||||||
|
|
||||||
|
import de.steamwar.comms.packets.FightInfoPacket;
|
||||||
|
import de.steamwar.lobby.display.Hologram;
|
||||||
|
import de.steamwar.lobby.Fightserver;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.*;
|
||||||
|
|
||||||
public class FightserverPortal implements PortalHandler {
|
public class FightserverPortal implements PortalHandler, Comparable<FightserverPortal> {
|
||||||
|
|
||||||
|
private static final Map<String, List<FightserverPortal>> portals = new HashMap<>();
|
||||||
|
|
||||||
|
public static FightserverPortal findFree(String gamemode) {
|
||||||
|
List<FightserverPortal> list = portals.getOrDefault(gamemode, Collections.emptyList());
|
||||||
|
for(FightserverPortal portal : list) {
|
||||||
|
if(portal.server == null)
|
||||||
|
return portal;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private final Portal portal;
|
private final Portal portal;
|
||||||
private final String group;
|
private final String gamemode;
|
||||||
|
private final int order;
|
||||||
private final String target;
|
private final String target;
|
||||||
|
private final Hologram hologram;
|
||||||
|
|
||||||
|
private Fightserver server = null;
|
||||||
private PortalHandler handler = new DummyPortal();
|
private PortalHandler handler = new DummyPortal();
|
||||||
|
|
||||||
public FightserverPortal(Map<String, Object> section, Portal portal) {
|
public FightserverPortal(Map<String, Object> section, Portal portal) {
|
||||||
this.portal = portal;
|
this.portal = portal;
|
||||||
this.group = (String) section.get("group");
|
this.gamemode = (String) section.get("group");
|
||||||
this.target = (String) section.get("target");
|
this.target = (String) section.get("target");
|
||||||
|
this.order = (int) section.get("order");
|
||||||
|
hologram = new Hologram(null, portal.getPos1().clone().add(portal.getOrientation().clone().divide(new Vector(2, 2, 2))), "");
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FightserverPortal(Portal portal, String group, String target) {
|
public FightserverPortal(Portal portal, String gamemode, int order, String target) {
|
||||||
this.portal = portal;
|
this.portal = portal;
|
||||||
this.group = group;
|
this.gamemode = gamemode;
|
||||||
|
this.order = order;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
|
hologram = new Hologram(null, portal.getPos1().clone().add(portal.getOrientation().clone().divide(new Vector(2, 2, 2))), "");
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setServer(Fightserver server) {
|
||||||
|
this.server = server;
|
||||||
|
if (server == null) {
|
||||||
|
setHandler(new TeleportPortal(portal, target));
|
||||||
|
} else {
|
||||||
|
setHandler(new CommandPortal("arena " + server.getServerName()));
|
||||||
|
}
|
||||||
|
updateText();
|
||||||
|
updateBluePlayers();
|
||||||
|
updateRedPlayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateText() {
|
||||||
|
if(server == null) {
|
||||||
|
hologram.updateText("Neuen Kampf starten");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FightInfoPacket info = server.current();
|
||||||
|
hologram.updateText(server.getServerName() + " " + info.getFightState() + " " + (info.getCountdown() / 60) + ":" + (info.getCountdown() % 60));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateBluePlayers() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateRedPlayers() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
setHandler(new TeleportPortal(portal, target));
|
updateText();
|
||||||
|
|
||||||
|
List<FightserverPortal> list = portals.computeIfAbsent(gamemode, mode -> new ArrayList<>());
|
||||||
|
list.add(this);
|
||||||
|
list.sort(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setHandler(PortalHandler handler) {
|
private void setHandler(PortalHandler handler) {
|
||||||
@ -64,7 +120,8 @@ public class FightserverPortal implements PortalHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serialize(Map<String, Object> map) {
|
public void serialize(Map<String, Object> map) {
|
||||||
map.put("group", group);
|
map.put("group", gamemode);
|
||||||
|
map.put("order", order);
|
||||||
map.put("target", target);
|
map.put("target", target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +132,13 @@ public class FightserverPortal implements PortalHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
portals.get(gamemode).remove(this);
|
||||||
|
hologram.delete();
|
||||||
handler.delete();
|
handler.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(FightserverPortal other) {
|
||||||
|
return other.order - order;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ public class Portal implements PortalHandler, ConfigurationSerializable {
|
|||||||
return portals.keySet();
|
return portals.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Portal getPortal(Player player, Location from, Location to) {
|
public static Portal getPortal(Location from, Location to) {
|
||||||
Vector movement = to.toVector().subtract(from.toVector());
|
Vector movement = to.toVector().subtract(from.toVector());
|
||||||
|
|
||||||
for(Portal portal : portals.values()) {
|
for(Portal portal : portals.values()) {
|
||||||
|
@ -65,6 +65,10 @@ public class TeleportPortal implements PortalHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void teleport(Player player, Location from, Location to, Portal target) {
|
private void teleport(Player player, Location from, Location to, Portal target) {
|
||||||
|
if(target == null) {
|
||||||
|
player.sendMessage("teleport " + portal.getId() + " -> UNKNOWN");
|
||||||
|
return;
|
||||||
|
}
|
||||||
player.sendMessage("teleport " + portal.getId() + " -> " + target.getId());
|
player.sendMessage("teleport " + portal.getId() + " -> " + target.getId());
|
||||||
|
|
||||||
Vector ownOrientation = portal.getOrientation().clone();
|
Vector ownOrientation = portal.getOrientation().clone();
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2021 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.lobby.servers;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class Observable<T> {
|
|
||||||
|
|
||||||
private final List<Consumer<T>> observers = new ArrayList<>();
|
|
||||||
|
|
||||||
private T value;
|
|
||||||
|
|
||||||
public Observable() {
|
|
||||||
value = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Observable(T initial) {
|
|
||||||
value = initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void register(Consumer<T> observer) {
|
|
||||||
observers.add(observer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(T value) {
|
|
||||||
if(!value.equals(this.value)) {
|
|
||||||
this.value = value;
|
|
||||||
observers.forEach(observer -> observer.accept(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
In neuem Issue referenzieren
Einen Benutzer sperren