Holograms!
Dieser Commit ist enthalten in:
Ursprung
8b1c74e31d
Commit
773f072483
@ -19,23 +19,30 @@
|
||||
|
||||
package de.steamwar.lobby;
|
||||
|
||||
import de.steamwar.lobby.display.Hologram;
|
||||
import de.steamwar.lobby.portal.Portal;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
|
||||
public class Config {
|
||||
|
||||
static {
|
||||
ConfigurationSerialization.registerClass(Portal.class);
|
||||
ConfigurationSerialization.registerClass(Hologram.class);
|
||||
}
|
||||
|
||||
private final FileConfiguration yml;
|
||||
|
||||
public Config(FileConfiguration yml) {
|
||||
this.yml = yml;
|
||||
|
||||
ConfigurationSerialization.registerClass(Portal.class);
|
||||
yml.getList("portals", Portal.getPortals());
|
||||
yml.getList("holograms", Hologram.getHolograms());
|
||||
}
|
||||
|
||||
public void save() {
|
||||
yml.set("portals", Portal.getPortals());
|
||||
yml.set("holograms", Hologram.getHolograms());
|
||||
|
||||
LobbySystem.getPlugin().saveConfig();
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package de.steamwar.lobby.command;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.RegionSelector;
|
||||
import de.steamwar.command.SWCommand;
|
||||
@ -12,7 +11,6 @@ import de.steamwar.lobby.LobbySystem;
|
||||
import de.steamwar.lobby.portal.*;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import lombok.Data;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -23,8 +21,6 @@ import java.util.List;
|
||||
|
||||
public class PortalCommand extends SWCommand {
|
||||
|
||||
private static final WorldEditPlugin worldEditPlugin = (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit");
|
||||
|
||||
public PortalCommand() {
|
||||
super("portal");
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.lobby;
|
||||
package de.steamwar.lobby.display;
|
||||
|
||||
import de.steamwar.lobby.listener.BasicListener;
|
||||
import org.bukkit.Bukkit;
|
156
src/de/steamwar/lobby/display/Hologram.java
Normale Datei
156
src/de/steamwar/lobby/display/Hologram.java
Normale Datei
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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 de.steamwar.lobby.listener.Protocol;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.*;
|
||||
|
||||
public class Hologram implements ConfigurationSerializable {
|
||||
|
||||
private static final Class<?> dataWatcherObject = Reflection.getClass("{nms}.DataWatcherObject");
|
||||
private static final Class<?> dataWatcherRegistry = Reflection.getClass("{nms}.DataWatcherRegistry");
|
||||
private static final Class<?> dataWatcherSerializer = Reflection.getClass("{nms}.DataWatcherSerializer");
|
||||
private static final Reflection.ConstructorInvoker dataWatcherObjectConstructor = Reflection.getConstructor(dataWatcherObject, int.class, dataWatcherSerializer);
|
||||
private static Object getDataWatcherObject(int index, Class<?> type) {
|
||||
for(Field field : dataWatcherRegistry.getFields()) {
|
||||
if(dataWatcherSerializer.isAssignableFrom(field.getType()) && type.equals(((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0])) {
|
||||
try {
|
||||
return dataWatcherObjectConstructor.invoke(index, field.get(null));
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new SecurityException("Could not get field", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new SecurityException("Could not find Serializer for " + type.getName());
|
||||
}
|
||||
|
||||
private static final Class<?> spawnLivingPacket = Reflection.getClass("{nms}.PacketPlayOutSpawnEntityLiving");
|
||||
private static final Reflection.ConstructorInvoker spawnLivingPacketConstructor = Reflection.getConstructor(spawnLivingPacket);
|
||||
private static final Reflection.FieldAccessor<Integer> spawnLivingEntityId = Reflection.getField(spawnLivingPacket, int.class, 0);
|
||||
private static final Reflection.FieldAccessor<UUID> spawnLivingUUID = Reflection.getField(spawnLivingPacket, UUID.class, 0);
|
||||
private static final Reflection.FieldAccessor<Integer> spawnLivingEntityType = Reflection.getField(spawnLivingPacket, int.class, 1);
|
||||
private static final Reflection.FieldAccessor<Double> spawnLivingEntityX = Reflection.getField(spawnLivingPacket, double.class, 0);
|
||||
private static final Reflection.FieldAccessor<Double> spawnLivingEntityY = Reflection.getField(spawnLivingPacket, double.class, 1);
|
||||
private static final Reflection.FieldAccessor<Double> spawnLivingEntityZ = Reflection.getField(spawnLivingPacket, double.class, 2);
|
||||
|
||||
private static final Class<?> metadataPacket = Reflection.getClass("{nms}.PacketPlayOutEntityMetadata");
|
||||
private static final Reflection.ConstructorInvoker metadataConstructor = Reflection.getConstructor(metadataPacket);
|
||||
private static final Reflection.FieldAccessor<Integer> metadataEntity = Reflection.getField(metadataPacket, int.class, 0);
|
||||
private static final Reflection.FieldAccessor<List> metadataMetadata = Reflection.getField(metadataPacket, List.class, 0);
|
||||
private static final Class<?> item = Reflection.getClass("{nms}.DataWatcher$Item");
|
||||
private static final Reflection.ConstructorInvoker itemConstructor = Reflection.getConstructor(item, dataWatcherObject, Object.class);
|
||||
private static final Object invisibleWatcher = getDataWatcherObject(0, Byte.class);
|
||||
private static final Object nameWatcher = getDataWatcherObject(2, String.class);
|
||||
private static final Object nameVisibleWatcher = getDataWatcherObject(3, String.class);
|
||||
private static final Object silentWatcher = getDataWatcherObject(4, Boolean.class);
|
||||
private static final Object noGravityWatcher = getDataWatcherObject(5, Boolean.class);
|
||||
private static final Object sizeWatcher = getDataWatcherObject(15, Byte.class);
|
||||
|
||||
private static final Class<?> destroyPacket = Reflection.getClass("{nms}.PacketPlayOutEntityDestroy");
|
||||
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 List<Hologram> holograms = new ArrayList<>();
|
||||
private static int entityIds = -1;
|
||||
private static final Random random = new Random();
|
||||
|
||||
public static List<Hologram> getHolograms() {
|
||||
return holograms;
|
||||
}
|
||||
|
||||
private final Displayable display;
|
||||
private final int entityId;
|
||||
private final Object spawnLiving;
|
||||
private final Object destroy;
|
||||
private final String id;
|
||||
private final Location location;
|
||||
private final String text;
|
||||
private final boolean persistent;
|
||||
|
||||
public Hologram(Map<String, Object> map) {
|
||||
this((String) map.get("id"), (Location) map.get("location"), (String) map.get("text"), true);
|
||||
}
|
||||
|
||||
public Hologram(String id, Location location, String text, boolean persistent) {
|
||||
this.id = id;
|
||||
this.location = location;
|
||||
this.text = text;
|
||||
this.persistent = persistent;
|
||||
entityId = entityIds--;
|
||||
|
||||
spawnLiving = spawnLivingPacketConstructor.invoke();
|
||||
spawnLivingEntityId.set(spawnLiving, entityId);
|
||||
spawnLivingUUID.set(spawnLiving, new UUID(random.nextLong() & -61441L | 16384L, random.nextLong() & 4611686018427387903L | -9223372036854775808L));
|
||||
spawnLivingEntityType.set(spawnLiving, 1);
|
||||
spawnLivingEntityX.set(spawnLiving, location.getX());
|
||||
spawnLivingEntityY.set(spawnLiving, location.getY());
|
||||
spawnLivingEntityZ.set(spawnLiving, location.getZ());
|
||||
|
||||
destroy = destoryPacketConstructor.invoke();
|
||||
destroyIds.set(destroy, new int[]{entityId});
|
||||
|
||||
display = new Displayable(location, this::show, this::hide);
|
||||
|
||||
if(persistent)
|
||||
holograms.add(this);
|
||||
}
|
||||
|
||||
private void show(Player player) {
|
||||
Protocol.getTinyProtocol().sendPacket(player, spawnLiving);
|
||||
|
||||
Object packet = metadataConstructor.invoke();
|
||||
metadataEntity.set(packet, entityId);
|
||||
List<Object> watchers = new ArrayList<>();
|
||||
watchers.add(itemConstructor.invoke(invisibleWatcher, (byte) 0x20));
|
||||
watchers.add(itemConstructor.invoke(nameWatcher, text));
|
||||
watchers.add(itemConstructor.invoke(nameVisibleWatcher, true));
|
||||
watchers.add(itemConstructor.invoke(silentWatcher, true));
|
||||
watchers.add(itemConstructor.invoke(noGravityWatcher, true));
|
||||
watchers.add(itemConstructor.invoke(sizeWatcher, (byte) 0x10));
|
||||
metadataMetadata.set(packet, watchers);
|
||||
Protocol.getTinyProtocol().sendPacket(player, packet);
|
||||
}
|
||||
|
||||
private void hide(Player player) {
|
||||
Protocol.getTinyProtocol().sendPacket(player, destroy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("id", id);
|
||||
map.put("location", location);
|
||||
map.put("text", text);
|
||||
return map;
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
display.delete();
|
||||
if(persistent)
|
||||
holograms.remove(this);
|
||||
}
|
||||
}
|
44
src/de/steamwar/lobby/listener/Protocol.java
Normale Datei
44
src/de/steamwar/lobby/listener/Protocol.java
Normale Datei
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
@ -5,6 +5,3 @@ authors:
|
||||
main: de.steamwar.lobby.LobbySystem
|
||||
depend: [SpigotCore, WorldEdit]
|
||||
api-version: "1.13"
|
||||
|
||||
commands:
|
||||
ak:
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren