13
0

TeamHalle #6

Zusammengeführt
Lixfel hat 16 Commits von TeamHalle nach master 2022-03-26 16:28:22 +01:00 zusammengeführt
5 geänderte Dateien mit 341 neuen und 15 gelöschten Zeilen

Datei anzeigen

@ -24,6 +24,7 @@ import de.steamwar.lobby.command.FlyCommand;
import de.steamwar.lobby.command.HologramCommand;
import de.steamwar.lobby.command.PortalCommand;
import de.steamwar.lobby.listener.*;
import de.steamwar.lobby.team.TeamPlayer;
import de.steamwar.message.Message;
import org.bukkit.plugin.java.JavaPlugin;
@ -58,6 +59,7 @@ public class LobbySystem extends JavaPlugin {
new WorldInteraction();
new PlayerSeatListener();
new MapsRotateListener();
new TeamPlayer();
new AlphaWall(l -> l.getX() > 1199, AlphaWall.REFLECT_X);
new AlphaWall(l -> l.getX() < 2977, AlphaWall.REFLECT_X);
@ -66,6 +68,10 @@ public class LobbySystem extends JavaPlugin {
}
@Override
public void onDisable() {
TeamPlayer.cleanup();
}
public static LobbySystem getPlugin() {
return plugin;

Datei anzeigen

@ -3,6 +3,10 @@ TIME = HH:mm:ss
DATE=........
COMMAND_HELP_HEAD=§7---=== (§e{0}§7) ===---
# ServerTeamNPC's
NPC_CHAT_1 = §fHallo, ich bin {0} und bin ein {1}.
NPC_CHAT_2 = §fWillkommen auf §eSteam§8War§f, viel Spaß dir.
# Portal Command
PORTAL_COMMAND_LIST_HELP = §8/§7portal §elist §8- §7Listet alle Portale auf
PORTAL_COMMAND_ADD_HELP = §8/§7portal §ecreate §8[§7PortalType§8] §8[§7PortalName§8] §8- §7Fügt ein Portal hinzu

Datei anzeigen

@ -38,24 +38,34 @@ public class Displayable extends BasicListener {
private final Set<Player> visible = new HashSet<>();
private final int chunkX;
private final int chunkZ;
private int chunkX;
private int chunkZ;
private final Consumer<Player> show;
private final Consumer<Player> hide;
private final Consumer<Player> move;
private final Function<Player, Boolean> playerFilter;
public Displayable(Location location, Consumer<Player> show, Consumer<Player> hide) {
this(location, show, hide, player -> true);
public Displayable(Location location, Consumer<Player> show, Consumer<Player> hide, Consumer<Player> move) {
this(location, show, hide, move, player -> true);
}
public Displayable(Location location, Consumer<Player> show, Consumer<Player> hide, Function<Player, Boolean> playerFilter) {
this.chunkX = posToChunk(location.getX());
this.chunkZ = posToChunk(location.getZ());
this(location, show, hide, player -> {}, playerFilter);
}
public Displayable(Location location, Consumer<Player> show, Consumer<Player> hide, Consumer<Player> move, Function<Player, Boolean> playerFilter) {
this.show = show;
this.hide = hide;
this.move = move;
this.playerFilter = playerFilter;
setLocation(location);
}
public void setLocation(Location location) {
chunkX = posToChunk(location.getX());
chunkZ = posToChunk(location.getZ());
Bukkit.getOnlinePlayers().forEach(this::checkLocation);
visible.forEach(move);
}
public Set<Player> getVisitors() {

Datei anzeigen

@ -22,9 +22,12 @@ package de.steamwar.lobby.display;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import com.mojang.authlib.GameProfile;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
@ -62,46 +65,137 @@ public class NPC {
private static final Reflection.ConstructorInvoker headRotationConstructor = Reflection.getConstructor(headRotationPacket);
private static final Reflection.FieldAccessor<Integer> headRotationEntity = Reflection.getField(headRotationPacket, int.class, 0);
private static final Reflection.FieldAccessor<Byte> headRotationYaw = Reflection.getField(headRotationPacket, byte.class, 0);
private static final Class<?> movePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityTeleport");
private static final Reflection.ConstructorInvoker movePacketConstructor = Reflection.getConstructor(movePacket);
private static final Reflection.FieldAccessor<Integer> movePacketEntity = Reflection.getField(movePacket, int.class, 0);
private static final Reflection.FieldAccessor<Double> movePacketX = Reflection.getField(movePacket, double.class, 0);
private static final Reflection.FieldAccessor<Double> movePacketY = Reflection.getField(movePacket, double.class, 1);
private static final Reflection.FieldAccessor<Double> movePacketZ = Reflection.getField(movePacket, double.class, 2);
private static final Reflection.FieldAccessor<Byte> movePacketYaw = Reflection.getField(movePacket, byte.class, 0);
private static final Reflection.FieldAccessor<Byte> movePacketPitch = Reflection.getField(movePacket, byte.class, 1);
private static final Reflection.FieldAccessor<Boolean> movePacketOnGround = Reflection.getField(movePacket, boolean.class, 0);
private static final Class<?> dataWatcherObject = Reflection.getClass("{nms.network.syncher}.DataWatcherObject");
private static final Class<?> dataWatcherRegistry = Reflection.getClass("{nms.network.syncher}.DataWatcherRegistry");
private static final Class<?> dataWatcherSerializer = Reflection.getClass("{nms.network.syncher}.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<?> item = Reflection.getClass("{nms.network.syncher}.DataWatcher$Item");
private static final Reflection.ConstructorInvoker itemConstructor = Reflection.getConstructor(item, dataWatcherObject, Object.class);
private static Object getDataWatcherItem(Object dwo, Object value) {
return itemConstructor.invoke(dwo, value);
}
private static final Class<?> metadataPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityMetadata");
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 Object getDataWatcherPacket(Object dataWatcherObject, Object value) {
Object packet = Reflection.newInstance(metadataPacket);
metadataEntity.set(packet, entityId);
metadataMetadata.set(packet, Collections.singletonList(getDataWatcherItem(dataWatcherObject, value)));
return packet;
}
private static Object skinPartsDataWatcherObject = getDataWatcherObject(16, Byte.class);
private final Displayable display;
private final int entityId;
private final UUID uuid;
private final String name;
private final Location location;
private Location location;
private final Object addPlayerInfo;
private final Object namedSpawn;
private final Object skinParts;
private final Object headRotation;
private final Object removePlayerInfo;
private final Object destroy;
private Object move;
public NPC(Location location, UUID uuid, String name) {
this.entityId = Hologram.createEntityId();
this.uuid = uuid;
this.name = name;
this.location = location;
byte yaw = (byte)(int)(location.getYaw() * 256.0 / 360.0);
GameProfile profile = new GameProfile(uuid, name);
addPlayerInfo = playerInfoPacket(addPlayer, profile);
removePlayerInfo = playerInfoPacket(removePlayer, profile);
destroy = Hologram.destroyPacket(entityId);
skinParts = getDataWatcherPacket(skinPartsDataWatcherObject, (byte) 0x7F);
YoyoNow markierte diese Unterhaltung als gelöst Veraltet
Veraltet
Review

Du weist doch gar nicht, welche SkinParts angezeigt werden sollen, warum darum kümmern?

Du weist doch gar nicht, welche SkinParts angezeigt werden sollen, warum darum kümmern?
Veraltet
Review

Ich würde einfach alle anzeigen und fertig sein, aber noch tut es eh nicht.

Ich würde einfach alle anzeigen und fertig sein, aber noch tut es eh nicht.
namedSpawn = namedSpawnConstructor.invoke();
namedSpawnEntity.set(namedSpawn, entityId);
namedSpawnUUID.set(namedSpawn, uuid);
headRotation = headRotationConstructor.invoke();
headRotationEntity.set(headRotation, entityId);
move = movePacketConstructor.invoke();
movePacketEntity.set(move, entityId);
setPackets(location);
display = new Displayable(location, this::show, this::hide, this::move);
}
public void setLocation(Location location) {
if (isSimilarLocation(location)) {
return;
}
this.location = location;
setPackets(location);
display.setLocation(location);
}
private void setPackets(Location location) {
byte yaw = (byte)(int)(location.getYaw() * 256.0 / 360.0);
byte pitch = (byte)(int)(location.getPitch() * 256.0 / 360.0);
headRotationYaw.set(headRotation, yaw);
movePacketX.set(move, location.getX());
movePacketY.set(move, location.getY());
movePacketZ.set(move, location.getZ());
movePacketYaw.set(move, yaw);
movePacketPitch.set(move, pitch);
movePacketOnGround.set(move, true);
namedSpawnX.set(namedSpawn, location.getX());
namedSpawnY.set(namedSpawn, location.getY());
namedSpawnZ.set(namedSpawn, location.getZ());
namedSpawnYaw.set(namedSpawn, yaw);
namedSpawnPitch.set(namedSpawn, (byte)(int)(location.getPitch() * 256.0 / 360.0));
namedSpawnPitch.set(namedSpawn, pitch);
}
headRotation = headRotationConstructor.invoke();
headRotationEntity.set(headRotation, entityId);
headRotationYaw.set(headRotation, yaw);
display = new Displayable(location, this::show, this::hide);
private boolean isSimilarLocation(Location location) {
if (this.location == null) {
return false;
}
if (Location.normalizeYaw(this.location.getYaw()) != Location.normalizeYaw(location.getYaw())) {
return false;
}
if (Location.normalizePitch(this.location.getPitch()) != Location.normalizePitch(location.getPitch())) {
return false;
}
if (Math.abs(this.location.getX() - location.getX()) > 0.1) {
return false;
}
if (Math.abs(this.location.getY() - location.getY()) > 0.1) {
return false;
}
return !(Math.abs(this.location.getZ() - location.getZ()) > 0.1);
}
public Location getLocation() {
@ -116,13 +210,21 @@ public class NPC {
TinyProtocol.instance.sendPacket(player, addPlayerInfo);
TinyProtocol.instance.sendPacket(player, namedSpawn);
TinyProtocol.instance.sendPacket(player, headRotation);
TinyProtocol.instance.sendPacket(player, skinParts);
}
private void hide(Player player) {
TinyProtocol.instance.sendPacket(player, removePlayerInfo);
if (Bukkit.getOnlinePlayers().stream().noneMatch(p -> p.getUniqueId().equals(uuid))) {
TinyProtocol.instance.sendPacket(player, removePlayerInfo);
}
TinyProtocol.instance.sendPacket(player, destroy);
}
private void move(Player player) {
TinyProtocol.instance.sendPacket(player, headRotation);
TinyProtocol.instance.sendPacket(player, move);
}
public void delete() {
display.delete();
}

Datei anzeigen

@ -0,0 +1,204 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.team;
import de.steamwar.lobby.LobbySystem;
import de.steamwar.lobby.display.NPC;
import de.steamwar.lobby.listener.BasicListener;
import de.steamwar.sql.SteamwarUser;
import lombok.AllArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityInteractEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.stream.Collectors;
public class TeamPlayer extends BasicListener {
private static final List<Cuboid> cuboids = new ArrayList<>();
static {
cuboids.add(new Cuboid(1509, 52, 1464, 1510, 58, 1469));
cuboids.add(new Cuboid(1538, 52, 1464, 1539, 58, 1469));
cuboids.add(new Cuboid(1518, 55, 1433, 1530, 60, 1434));
cuboids.add(new Cuboid(1587, 52, 1471, 1588, 56, 1475));
cuboids.add(new Cuboid(1478, 52, 1461, 1479, 56, 1463));
}
private static final World world = Bukkit.getWorlds().get(0);
private static final Map<String, NPC> entities = new HashMap<>();
private Set<Player> players = new HashSet<>();
YoyoNow markierte diese Unterhaltung als gelöst Veraltet
Veraltet
Review

Bitte nicht den Weltnamen hardcoden...

Bitte nicht den Weltnamen hardcoden...
Veraltet
Review

Ist die Lobby denn immer die Bukkit.getWorlds().get(0)

Ist die Lobby denn immer die `Bukkit.getWorlds().get(0)`
private Random random = new Random();
private List<String> strings = new ArrayList<>();
{
strings.add("NPC_CHAT_1");
strings.add("NPC_CHAT_2");
}
public static void spawnTeamPlayer(World world, SteamwarUser steamwarUser) {
Location location = new Location(world, 1524.5, 52, 1484.5);
String name = steamwarUser.getUserName();
NPC npc = new NPC(location, steamwarUser.getUUID(), name);
YoyoNow markierte diese Unterhaltung als gelöst Veraltet
Veraltet
Review

Und das wartest du bei jeder Teammitgliedänderung? bitte aus der Datenbank holen...

Und das wartest du bei jeder Teammitgliedänderung? bitte aus der Datenbank holen...
Veraltet
Review

Ja ich werde es aus der DB holen, wo soll ich den SQL quack dafür schmeißen?

Ja ich werde es aus der DB holen, wo soll ich den SQL quack dafür schmeißen?
Villager villager = (Villager) world.spawnEntity(location, EntityType.VILLAGER);
villager.setSilent(true);
villager.setInvulnerable(true);
villager.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 1, false, false, false));
villager.setCustomName(name);
villager.setProfession(Villager.Profession.NONE);
entities.put(name, npc);
}
public static void cleanup() {
forceLoad(world, true);
world.getEntitiesByClasses(Villager.class).forEach(Entity::remove);
forceLoad(world, false);
}
private static void forceLoad(World world, boolean setTo) {
for (int x = -10; x < 10; x++) {
for (int z = -10; z < 10; z++) {
world.setChunkForceLoaded(95 + x, 93 + z, setTo);
}
}
}
{
forceLoad(world, true);
world.getEntitiesByClasses(Villager.class).forEach(Entity::remove);
forceLoad(world, false);
SteamwarUser.getServerTeam().forEach(user -> {
spawnTeamPlayer(world, user);
});
AtomicInteger count = new AtomicInteger();
LobbySystem.getPlugin().getLogger().log(Level.INFO, "Loaded " + entities.size() + " team players");
Bukkit.getScheduler().runTaskTimer(LobbySystem.getPlugin(), () -> {
count.incrementAndGet();
if (count.get() % (20 * 60 * 60) == 0) {
count.set(0);
List<SteamwarUser> steamwarUsers = SteamwarUser.getServerTeam();
AtomicInteger added = new AtomicInteger();
steamwarUsers.forEach(user -> {
if (!entities.containsKey(user.getUserName())) {
spawnTeamPlayer(world, user);
added.incrementAndGet();
}
});
AtomicInteger removed = new AtomicInteger();
List<String> names = steamwarUsers.stream().map(SteamwarUser::getUserName).collect(Collectors.toList());
new HashSet<>(entities.keySet()).stream().filter(name -> !names.contains(name)).forEach(name -> {
world.getEntitiesByClasses(Villager.class).forEach(entity -> {
if (entity.getName().equals(name)) {
entity.remove();
}
});
entities.remove(name).delete();
removed.incrementAndGet();
});
if (added.get() > 0 || removed.get() > 0) {
LobbySystem.getPlugin().getLogger().log(Level.INFO, "Loaded " + added.get() + " team players, removed " + removed.get() + " team players");
}
}
world.getEntitiesByClasses(Villager.class).forEach(entity -> {
NPC npc = entities.get(entity.getName());
if (npc != null) {
if (illegalLocation(entity.getLocation())) {
entity.teleport(npc.getLocation());
return;
}
npc.setLocation(entity.getLocation());
}
});
}, 1L, 1L);
}
private boolean illegalLocation(Location location) {
for (Cuboid cuboid : cuboids) {
if (cuboid.contains(location)) {
return true;
}
}
return false;
}
@EventHandler
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if (!(event.getRightClicked() instanceof Villager)) {
return;
}
if (!players.add(event.getPlayer())) {
players.remove(event.getPlayer());
return;
}
SteamwarUser user = SteamwarUser.get(event.getRightClicked().getName());
String message = strings.get(random.nextInt(strings.size()));
LobbySystem.getMessage().send(message, event.getPlayer(), event.getRightClicked().getName(), user.getUserGroup().getColorCode() + user.getUserGroup().name());
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
players.remove(event.getPlayer());
}
@EventHandler
public void onEntityInteract(EntityInteractEvent event) {
if (event.getEntityType() == EntityType.VILLAGER) {
event.setCancelled(true);
}
}
@EventHandler
public void onEntityDamage(EntityDamageEvent event) {
if (event.getEntityType() == EntityType.VILLAGER) {
event.setCancelled(true);
}
}
@AllArgsConstructor
private static class Cuboid {
private double x1;
private double y1;
private double z1;
private double x2;
private double y2;
private double z2;
public boolean contains(Location location) {
return location.getX() >= x1 && location.getX() <= x2 && location.getY() >= y1 && location.getY() <= y2 && location.getZ() >= z1 && location.getZ() <= z2;
}
}
}