diff --git a/FightSystem_API/src/de/steamwar/fightsystem/ArenaMode.java b/FightSystem_API/src/de/steamwar/fightsystem/ArenaMode.java index 70edcef..a745a3e 100644 --- a/FightSystem_API/src/de/steamwar/fightsystem/ArenaMode.java +++ b/FightSystem_API/src/de/steamwar/fightsystem/ArenaMode.java @@ -29,7 +29,8 @@ public enum ArenaMode { EVENT, TEST, CHECK, - PREPARE; + PREPARE, + SPECTATE; public static final Set All = Collections.unmodifiableSet(EnumSet.allOf(ArenaMode.class)); @@ -39,14 +40,15 @@ public enum ArenaMode { public static final Set Test = Collections.unmodifiableSet(EnumSet.of(TEST, CHECK)); public static final Set Ranked = Collections.unmodifiableSet(EnumSet.of(RANKED)); public static final Set Prepare = Collections.unmodifiableSet(EnumSet.of(PREPARE)); + public static final Set Spectate = Collections.unmodifiableSet(EnumSet.of(SPECTATE)); + public static final Set AntiSpectate = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(SPECTATE))); public static final Set AntiTest = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK))); public static final Set AntiEvent = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(EVENT))); public static final Set AntiPrepare = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(PREPARE))); - public static final Set VariableTeams = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(RANKED, EVENT))); + public static final Set VariableTeams = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(RANKED, EVENT, SPECTATE))); public static final Set RankedEvent = Collections.unmodifiableSet(EnumSet.of(RANKED, EVENT)); public static final Set Restartable = Collections.unmodifiableSet(EnumSet.of(NORMAL, RANKED)); - public static final Set Fight = Collections.unmodifiableSet(EnumSet.of(NORMAL, RANKED, EVENT)); public static final Set SoloLeader = Collections.unmodifiableSet(EnumSet.of(TEST, CHECK, PREPARE)); public static final Set NotOnBau = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK, PREPARE))); } diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem_Main/src/de/steamwar/fightsystem/FightSystem.java index 16a8072..b84f9b7 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/FightSystem.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/FightSystem.java @@ -127,8 +127,8 @@ public class FightSystem extends JavaPlugin { new SkipCommand(); new WinCommand(); - new OneShotStateDependent(ArenaMode.All, FightState.PreRunning, () -> Bukkit.broadcastMessage(PREFIX + "§aDer Kampf beginnt!")); - new OneShotStateDependent(ArenaMode.All, FightState.Running, () -> Bukkit.broadcastMessage(PREFIX + "§aArena freigegeben!")); + new OneShotStateDependent(ArenaMode.AntiSpectate, FightState.PreRunning, () -> Bukkit.broadcastMessage(PREFIX + "§aDer Kampf beginnt!")); + new OneShotStateDependent(ArenaMode.AntiSpectate, FightState.Running, () -> Bukkit.broadcastMessage(PREFIX + "§aArena freigegeben!")); new OneShotStateDependent(ArenaMode.AntiTest, FightState.Running, FightStatistics::start); try { diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/commands/KitCommand.java b/FightSystem_Main/src/de/steamwar/fightsystem/commands/KitCommand.java index 585262b..fd73f66 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/commands/KitCommand.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/commands/KitCommand.java @@ -30,7 +30,7 @@ import org.bukkit.entity.Player; public class KitCommand implements CommandExecutor { public KitCommand() { - new StateDependentCommand(ArenaMode.All, FightState.Setup, "kit", this); + new StateDependentCommand(ArenaMode.AntiSpectate, FightState.Setup, "kit", this); } @Override diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/commands/LeaveCommand.java b/FightSystem_Main/src/de/steamwar/fightsystem/commands/LeaveCommand.java index 7e3327e..5c95c72 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/commands/LeaveCommand.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/commands/LeaveCommand.java @@ -30,7 +30,7 @@ import org.bukkit.entity.Player; public class LeaveCommand implements CommandExecutor { public LeaveCommand() { - new StateDependentCommand(ArenaMode.All, FightState.Setup, "leave", this); + new StateDependentCommand(ArenaMode.AntiSpectate, FightState.Setup, "leave", this); } @Override diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/commands/LockschemCommand.java b/FightSystem_Main/src/de/steamwar/fightsystem/commands/LockschemCommand.java index 6070d12..fdaff2e 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/commands/LockschemCommand.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/commands/LockschemCommand.java @@ -37,7 +37,7 @@ import org.bukkit.entity.Player; public class LockschemCommand implements CommandExecutor { public LockschemCommand() { - new StateDependentCommand(ArenaMode.All, FightState.All, "lockschem", this); + new StateDependentCommand(ArenaMode.AntiSpectate, FightState.All, "lockschem", this); } @Override diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/countdown/NoPlayersOnlineCountdown.java b/FightSystem_Main/src/de/steamwar/fightsystem/countdown/NoPlayersOnlineCountdown.java index fc8ed95..15b433f 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/countdown/NoPlayersOnlineCountdown.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/countdown/NoPlayersOnlineCountdown.java @@ -34,8 +34,8 @@ public class NoPlayersOnlineCountdown extends Countdown implements Listener { public NoPlayersOnlineCountdown() { super(Config.NoPlayerOnlineDuration, null, false); - new StateDependentListener(ArenaMode.All, FightState.PreLeaderSetup, this); - new StateDependentCountdown(ArenaMode.All, FightState.PreLeaderSetup, this){ + new StateDependentListener(ArenaMode.AntiSpectate, FightState.PreLeaderSetup, this); + new StateDependentCountdown(ArenaMode.AntiSpectate, FightState.PreLeaderSetup, this){ @Override public void enable() { if(Bukkit.getOnlinePlayers().isEmpty()) diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/countdown/PreRunningCountdown.java b/FightSystem_Main/src/de/steamwar/fightsystem/countdown/PreRunningCountdown.java index 4506ace..f5ad64c 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/countdown/PreRunningCountdown.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/countdown/PreRunningCountdown.java @@ -29,7 +29,7 @@ public class PreRunningCountdown extends Countdown { public PreRunningCountdown() { super(Config.PreFightDuration, SWSound.BLOCK_NOTE_PLING, true); - new StateDependentCountdown(ArenaMode.All, FightState.PreRunning, this); + new StateDependentCountdown(ArenaMode.AntiSpectate, FightState.PreRunning, this); } @Override diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/countdown/PreSchemCountdown.java b/FightSystem_Main/src/de/steamwar/fightsystem/countdown/PreSchemCountdown.java index e0084a4..fed7dd6 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/countdown/PreSchemCountdown.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/countdown/PreSchemCountdown.java @@ -29,7 +29,7 @@ public class PreSchemCountdown extends Countdown { public PreSchemCountdown() { super(Config.PreSchemPasteDuration, SWSound.BLOCK_NOTE_PLING, false); - new StateDependentCountdown(ArenaMode.All, FightState.PreSchemSetup, this); + new StateDependentCountdown(ArenaMode.AntiSpectate, FightState.PreSchemSetup, this); } @Override diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightSchematic.java b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightSchematic.java index 7a76a2c..7ec3d43 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightSchematic.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightSchematic.java @@ -56,7 +56,7 @@ public class FightSchematic extends StateDependent { private int schematic = 0; public FightSchematic(FightTeam team, boolean rotate) { - super(ArenaMode.All, FightState.PostSchemSetup); + super(ArenaMode.AntiSpectate, FightState.PostSchemSetup); this.team = team; this.region = team.getSchemRegion(); this.rotate = rotate; diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java index bc0dfc7..dcdacea 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -394,7 +394,7 @@ public class FightTeam implements IFightTeam{ private class KitLoader extends StateDependent { private KitLoader() { - super(ArenaMode.All, FightState.Ingame); + super(ArenaMode.AntiSpectate, FightState.Ingame); register(); } @@ -419,7 +419,7 @@ public class FightTeam implements IFightTeam{ private class SpectateHandler extends StateDependent { private SpectateHandler() { - super(ArenaMode.All, FightState.Spectate); + super(ArenaMode.AntiSpectate, FightState.Spectate); register(); } diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/FightScoreboard.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/FightScoreboard.java index 7b98067..7de7628 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/FightScoreboard.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/FightScoreboard.java @@ -55,8 +55,8 @@ public class FightScoreboard implements Listener, ScoreboardCallback { } public FightScoreboard(){ - new StateDependentListener(ArenaMode.All, FightState.All, this); - new StateDependentTask(ArenaMode.All, FightState.All, this::updateScoreboard, 0, 20); + new StateDependentListener(ArenaMode.AntiSpectate, FightState.All, this); + new StateDependentTask(ArenaMode.AntiSpectate, FightState.All, this::updateScoreboard, 0, 20); } @EventHandler diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/HotbarGUI.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/HotbarGUI.java index 2827c50..b8bb8c1 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/HotbarGUI.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/HotbarGUI.java @@ -35,7 +35,7 @@ import org.bukkit.inventory.meta.ItemMeta; public class HotbarGUI implements Listener { public HotbarGUI() { - new StateDependentListener(ArenaMode.All, FightState.Setup, this); + new StateDependentListener(ArenaMode.AntiSpectate, FightState.Setup, this); } @EventHandler diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/InFightDamage.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/InFightDamage.java index d525e6c..660429d 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/InFightDamage.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/InFightDamage.java @@ -36,7 +36,7 @@ import java.util.Objects; public class InFightDamage implements Listener { public InFightDamage() { - new StateDependentListener(ArenaMode.All, FightState.Running, this); + new StateDependentListener(ArenaMode.AntiSpectate, FightState.Running, this); } @EventHandler diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/InFightInventory.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/InFightInventory.java index c72a812..47ae4ed 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/InFightInventory.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/InFightInventory.java @@ -39,7 +39,7 @@ import org.bukkit.inventory.ItemStack; public class InFightInventory implements Listener { public InFightInventory() { - new StateDependentListener(ArenaMode.All, FightState.Running, this); + new StateDependentListener(ArenaMode.AntiSpectate, FightState.Running, this); } @EventHandler diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/IngameDeath.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/IngameDeath.java index 6bf1074..b942f76 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/IngameDeath.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/IngameDeath.java @@ -40,7 +40,7 @@ import org.bukkit.event.player.PlayerQuitEvent; public class IngameDeath implements Listener { public IngameDeath() { - new StateDependentListener(ArenaMode.All, FightState.Ingame, this); + new StateDependentListener(ArenaMode.AntiSpectate, FightState.Ingame, this); } @EventHandler(priority = EventPriority.HIGH) diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/SetupQuit.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/SetupQuit.java index 3b083e7..de61a4d 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/SetupQuit.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/SetupQuit.java @@ -32,7 +32,7 @@ import org.bukkit.event.player.PlayerQuitEvent; public class SetupQuit implements Listener { public SetupQuit(){ - new StateDependentListener(ArenaMode.All, FightState.Setup, this); + new StateDependentListener(ArenaMode.AntiSpectate, FightState.Setup, this); } @EventHandler diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/Spectate.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/Spectate.java new file mode 100644 index 0000000..8e62379 --- /dev/null +++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/Spectate.java @@ -0,0 +1,73 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2020 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 . +*/ + +package de.steamwar.fightsystem.listener; + +import de.steamwar.fightsystem.ArenaMode; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.StateDependentListener; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockExplodeEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerSwapHandItemsEvent; + +public class Spectate implements Listener { + + public Spectate(){ + new StateDependentListener(ArenaMode.Spectate, FightState.All, this); + } + + @EventHandler + public void onLogin(PlayerLoginEvent e){ + Player player = e.getPlayer(); + + if(InspectCommand.inspecting){ + SteamwarUser user = SteamwarUser.get(player.getUniqueId()); + if(!SpectateSystem.allowedGroups.contains(user.getUserGroup())){ + e.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, "§eSteam§8War» §cDerzeit ist das Zuschauen nicht gestattet."); + } + } + } + + @EventHandler + public void onPhysics(BlockPhysicsEvent event) { + event.setCancelled(true); + } + + @EventHandler + public void onBlockExplosion(BlockExplodeEvent e){ + e.setCancelled(true); + } + + @EventHandler + public void handlePlayerSwapHandItemsEvent(PlayerSwapHandItemsEvent event) { + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOW) + public void handlePlayerInteract(PlayerInteractEvent event) { + event.setCancelled(true); + } +} diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/WaterRemover.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/WaterRemover.java index 40ae32e..5aa30ca 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/WaterRemover.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/WaterRemover.java @@ -35,7 +35,7 @@ public class WaterRemover implements Listener { private static final int MIN_Y = Config.BluePasteRegion.getMinY() + Config.WaterDepth; public WaterRemover() { - new StateDependentListener(ArenaMode.All, FightState.Running, this); + new StateDependentListener(ArenaMode.AntiSpectate, FightState.Running, this); } @EventHandler diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/record/PacketProcessor.java b/FightSystem_Main/src/de/steamwar/fightsystem/record/PacketProcessor.java new file mode 100644 index 0000000..8d71506 --- /dev/null +++ b/FightSystem_Main/src/de/steamwar/fightsystem/record/PacketProcessor.java @@ -0,0 +1,423 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2020 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 . +*/ + +package de.steamwar.fightsystem.record; + +import com.sk89q.worldedit.EditSession; +import de.steamwar.fightsystem.FightSystem; +import de.steamwar.sql.NoClipboardException; +import de.steamwar.sql.Schematic; +import de.steamwar.sql.SteamwarUser; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.*; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitTask; + +import java.io.EOFException; +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Objects; +import java.util.logging.Level; + +class PacketProcessor { + + private static final World world = Bukkit.getWorlds().get(0); + private final Map packetCounter = new HashMap<>(); + + private final PacketSource source; + private final BukkitTask task; + private final LinkedList syncList = new LinkedList<>(); + + + public PacketProcessor(PacketSource source){ + this.source = source; + if(source.async()) { + Bukkit.getScheduler().runTaskAsynchronously(FightSystem.getPlugin(), this::process); + task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::runSync, 1, 1); + }else + task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::process, 1, 1); + } + + private void runSync() { + synchronized (syncList) { + for(Runnable runnable : syncList) { + try{ + runnable.run(); + }catch (Exception e) { + Bukkit.getLogger().log(Level.WARNING, "Failed to execute packet", e); + } + } + syncList.clear(); + } + } + + private void execSync(Runnable runnable){ + if (!source.async()) { + runnable.run(); + return; + } + + synchronized (syncList) { + syncList.add(runnable); + } + } + + private void playerJoins() throws IOException { + int entityId = source.rInt(); + int userId = source.rInt(); + SteamwarUser user = SteamwarUser.get(userId); + if(user == null) + throw new IOException("Unknown user " + userId); + + execSync(() -> new RPlayer(user.getUUID(), user.getUserName(), entityId)); + } + + private void entityMoves() throws IOException { + int entityId = source.rInt(); + double locX = source.rDouble(); + double locY = source.rDouble(); + double locZ = source.rDouble(); + float pitch = source.rFloat(); + float yaw = source.rFloat(); + byte headYaw = source.rByte(); + + execSync(() -> REntity.getEntity(entityId).move(locX, locY, locZ, yaw, pitch, headYaw)); + } + + private void entityDespawns() throws IOException { + int entityId = source.rInt(); + + execSync(() -> REntity.getEntity(entityId).remove()); + } + + private void entitySneak() throws IOException { + int entityId = source.rInt(); + boolean sneaking = source.rBoolean(); + + execSync(() -> REntity.getEntity(entityId).sneak(sneaking)); + } + + private void entityAnimation() throws IOException { + int entityId = source.rInt(); + byte animation = source.rByte(); + + execSync(() -> REntity.getEntity(entityId).animation(animation)); + } + + private void tntSpawn() throws IOException { + int entityId = source.rInt(); + + execSync(() -> new RTnT(entityId)); + } + + private void entityVelocity() throws IOException { + int entityId = source.rInt(); + + double dX = source.rDouble(); + double dY = source.rDouble(); + double dZ = source.rDouble(); + + execSync(() -> { + REntity entity = REntity.getEntity(entityId); + if(entity != null) + entity.setMotion(dX, dY, dZ); + }); + } + + private void playerItem() throws IOException { + int entityId = source.rInt(); + String item = source.rString(); + boolean enchanted = source.rBoolean(); + String slot = source.rString(); + + execSync(() -> ((RPlayer)REntity.getEntity(entityId)).setItem(item, enchanted, slot)); + } + + private void arrowSpawn() throws IOException { + int entityId = source.rInt(); + + execSync(() -> new RArrow(entityId)); + } + + private void fireballSpawn() throws IOException { + int entityId = source.rInt(); + + execSync(() -> new RFireball(entityId)); + } + + private void send(ChatMessageType type) throws IOException { + String message = source.rString(); + + BaseComponent[] text = TextComponent.fromLegacyText(message); + Bukkit.getOnlinePlayers().forEach(p -> p.spigot().sendMessage(type, text)); + } + + private void shortBlock() throws IOException { + int x = Byte.toUnsignedInt(source.rByte()) + Config.ArenaMinX; + int y = Byte.toUnsignedInt(source.rByte()); + int z = Byte.toUnsignedInt(source.rByte()) + Config.ArenaMinZ; + int blockState = source.rShort(); + + setBlock(x, y, z, blockState); + } + + private void block() throws IOException { + int x = source.rInt(); + int y = Byte.toUnsignedInt(source.rByte()); + int z = source.rInt(); + int blockState = source.rInt(); + + setBlock(x, y, z, blockState); + } + + private void setBlock(int x, int y, int z, int blockState){ + if(Config.ArenaMinX > x || Config.ArenaMaxX < x || Config.ArenaMinZ > z || Config.ArenaMaxZ < z) + return; //Outside of the arena + + if (!InspectCommand.inspecting && Config.TechhiderActive && Config.HiddenBlocks.contains(blockState)) { + blockState = Config.ObfuscateWith; + } + IBlockData blockData = Objects.requireNonNull(Block.REGISTRY_ID.fromId(blockState)); + execSync(() -> { + WorldServer cworld = ((CraftWorld)world).getHandle(); + BlockPosition pos = new BlockPosition(x, y, z); + cworld.removeTileEntity(pos); + cworld.setTypeAndData(pos, blockData, 1042); + cworld.getChunkProvider().flagDirty(pos); + }); + } + + private void particle() throws IOException { + double x = source.rDouble(); + double y = source.rDouble(); + double z = source.rDouble(); + + String particleName = source.rString(); + + execSync(() -> world.spawnParticle(Particle.valueOf(particleName), x, y, z, 1)); + } + + private void sound() throws IOException { + int x = source.rInt(); + int y = source.rInt(); + int z = source.rInt(); + + String soundName = source.rString(); + String soundCategory = source.rString(); + + float volume = source.rFloat(); + float pitch = source.rFloat(); + + Sound sound = Sound.valueOf(soundName); + SoundCategory sCategory = SoundCategory.valueOf(soundCategory); + + execSync(() -> world.playSound(new Location(world, x, y, z), sound, sCategory, volume, pitch)); + } + + private void soundAtPlayer() throws IOException { + String soundName = source.rString(); + + float volume = source.rFloat(); + float pitch = source.rFloat(); + + Sound sound = Sound.valueOf(soundName); + + execSync(() -> { + for(Player player : Bukkit.getOnlinePlayers()){ + player.playSound(player.getLocation(), sound, volume, pitch); + } + }); + } + + private void pasteSchem(int pasteX, int cornerY, int pasteZ, int cornerX, int cornerZ, boolean rotate, String prefix) throws IOException { + int schemId = source.rInt(); + + Schematic schem = Schematic.getSchemFromDB(schemId); + DyeColor c = ColorConverter.chat2dye(ChatColor.getByChar(ChatColor.getLastColors(prefix).replace("§", ""))); + execSync(() -> { + try { + EditSession e = Paster.pasteSchematic(schem, pasteX, cornerY, pasteZ, rotate); + Paster.replaceTeamColor(e, c, cornerX, cornerY, cornerZ); + } catch (NoClipboardException | IOException e) { + throw new SecurityException("Could not load Clipboard", e); + } + }); + } + + private void teams() throws IOException { + int blueId = source.rInt(); + int redId = source.rInt(); + + execSync(() -> BlockTextCreator.pasteTeamNames(blueId, redId)); + } + + private void scoreboardTitle() throws IOException { + String title = source.rString(); + + SpectateSystem.getScoreboard().setTitle(title); + } + + private void scoreboardData() throws IOException { + String key = source.rString(); + int value = source.rInt(); + + SpectateSystem.getScoreboard().addValue(key, value); + } + + private void endSpectating(){ + WorldLoader.reloadWorld(); + SpectateSystem.getScoreboard().setTitle("§eKein Kampf"); + + for(Map.Entry entry : packetCounter.entrySet()){ + System.out.println(Integer.toHexString(entry.getKey()) + " " + entry.getValue()); + } + + packetCounter.clear(); + } + + private void bow() { + //TODO implement Bow + } + + private void damage() throws IOException { + int entityId = source.rInt(); + + execSync(() -> REntity.getEntity(entityId).damage()); + } + + private void fireTick() throws IOException { + int entityId = source.rInt(); + + execSync(() -> REntity.getEntity(entityId).setOnFire()); + } + + private void process(){ + + try{ + boolean tickFinished = false; + while(!source.isClosed() && !tickFinished){ + byte packetType = source.rByte(); + packetCounter.compute(packetType, (key, value) -> value != null ? value + 1 : 1); + switch(packetType){ + case 0x00: + playerJoins(); + break; + case 0x01: + entityMoves(); + break; + case 0x02: + entityDespawns(); + break; + case 0x03: + entitySneak(); + break; + case 0x04: + entityAnimation(); + break; + case 0x05: + tntSpawn(); + break; + case 0x06: + entityVelocity(); + break; + case 0x07: + playerItem(); + break; + case 0x08: + arrowSpawn(); + break; + case 0x09: + fireballSpawn(); + break; + case 0x0A: + case 0x0B: + damage(); + case 0x0C: + fireTick(); + case 0x30: + block(); + break; + case 0x31: + particle(); + break; + case 0x32: + sound(); + break; + case 0x33: + shortBlock(); + break; + case 0x34: + soundAtPlayer(); + break; + case (byte) 0xA0: + send(ChatMessageType.CHAT); + break; + case (byte) 0xA1: + send(ChatMessageType.ACTION_BAR); + break; + case (byte) 0xA2: + send(ChatMessageType.SYSTEM); + break; + case (byte) 0xB0: + pasteSchem(Config.TeamBluePasteX, Config.TeamBlueCornerY, Config.TeamBluePasteZ, Config.TeamBlueCornerX, Config.TeamBlueCornerZ, Config.TeamBlueRotate, Config.TeamBluePrefix); + break; + case (byte) 0xB1: + pasteSchem(Config.TeamRedPasteX, Config.TeamRedCornerY, Config.TeamRedPasteZ, Config.TeamRedCornerX, Config.TeamRedCornerZ, Config.TeamRedRotate, Config.TeamRedPrefix); + break; + case (byte) 0xB2: + teams(); + break; + case (byte) 0xC0: + scoreboardTitle(); + break; + case (byte) 0xC1: + scoreboardData(); + break; + case (byte) 0xEF: + // Comment + source.rString(); + break; + case (byte) 0xFF: + //Tick + if(!source.async()) + tickFinished = true; + break; + default: + Bukkit.getLogger().log(Level.SEVERE, "Unknown packet recieved, closing: " + packetType); + source.close(); + } + } + } catch (EOFException e) { + Bukkit.getLogger().log(Level.INFO, "The FightServer is offline"); + source.close(); + } catch(IOException e){ + Bukkit.getLogger().log(Level.WARNING, "Could not recieve packet", e); + source.close(); + } + + if(source.isClosed()){ + Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::endSpectating); + task.cancel(); + } + } +} diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/record/PacketSource.java b/FightSystem_Main/src/de/steamwar/fightsystem/record/PacketSource.java new file mode 100644 index 0000000..4297f29 --- /dev/null +++ b/FightSystem_Main/src/de/steamwar/fightsystem/record/PacketSource.java @@ -0,0 +1,79 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2020 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 . +*/ + +package de.steamwar.fightsystem.record; + +import org.bukkit.Bukkit; + +import java.io.DataInputStream; +import java.io.IOException; +import java.util.logging.Level; + +public abstract class PacketSource { + + protected final DataInputStream inputStream; + + protected PacketSource(DataInputStream inputStream){ + this.inputStream = inputStream; + new PacketProcessor(this); + } + + public byte rByte() throws IOException { + return inputStream.readByte(); + } + + public boolean rBoolean() throws IOException { + return inputStream.readBoolean(); + } + + public short rShort() throws IOException { + return inputStream.readShort(); + } + + public int rInt() throws IOException { + return inputStream.readInt(); + } + + public long rLong() throws IOException { + return inputStream.readLong(); + } + + public float rFloat() throws IOException { + return inputStream.readFloat(); + } + + public double rDouble() throws IOException { + return inputStream.readDouble(); + } + + public String rString() throws IOException { + return inputStream.readUTF(); + } + + public void close(){ + try { + inputStream.close(); + } catch (IOException e) { + Bukkit.getLogger().log(Level.SEVERE, "IOException on close", e); + } + } + + abstract boolean isClosed(); + abstract boolean async(); +}