From 48426c9a86b4e1cab3bee5c8c51bdd453dc2ca5f Mon Sep 17 00:00:00 2001 From: Lixfel Date: Mon, 24 May 2021 17:40:24 +0200 Subject: [PATCH] WIP Signed-off-by: Lixfel --- .../fightsystem/record/RecordSystem_14.java | 52 ++++++ .../fightsystem/record/RecordSystem_15.java | 21 +++ .../fightsystem/record/RecordSystem_8.java | 7 +- .../fightsystem/fight/FightSchematic.java | 53 +------ .../steamwar/fightsystem/fight/FightTeam.java | 6 +- .../fightsystem/fight/FightWorld.java | 17 +- .../fightsystem/fight/FreezeWorld.java | 73 +++++++++ .../fightsystem/listener/FightScoreboard.java | 29 +++- .../fightsystem/record/BlockTextCreator.java | 150 ++++++++++++++++++ .../fightsystem/record/PacketProcessor.java | 38 ++--- .../steamwar/fightsystem/record/REntity.java | 129 +++++++++------ .../fightsystem/record/RecordSystem.java | 13 ++ 12 files changed, 458 insertions(+), 130 deletions(-) create mode 100644 FightSystem_14/src/de/steamwar/fightsystem/record/RecordSystem_14.java create mode 100644 FightSystem_Main/src/de/steamwar/fightsystem/fight/FreezeWorld.java create mode 100644 FightSystem_Main/src/de/steamwar/fightsystem/record/BlockTextCreator.java diff --git a/FightSystem_14/src/de/steamwar/fightsystem/record/RecordSystem_14.java b/FightSystem_14/src/de/steamwar/fightsystem/record/RecordSystem_14.java new file mode 100644 index 0000000..5e65cb4 --- /dev/null +++ b/FightSystem_14/src/de/steamwar/fightsystem/record/RecordSystem_14.java @@ -0,0 +1,52 @@ +/* + 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 net.minecraft.server.v1_14_R1.BlockPosition; +import net.minecraft.server.v1_14_R1.EntityPose; +import net.minecraft.server.v1_14_R1.IBlockData; +import net.minecraft.server.v1_14_R1.WorldServer; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_14_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock; + +import java.util.Objects; + +public class RecordSystem_14 { + private RecordSystem_14(){} + + static int blockToId(Block block){ + return net.minecraft.server.v1_14_R1.Block.REGISTRY_ID.getId(((CraftBlock)block).getNMS()); + } + + static Object getPose(boolean sneaking){ + return sneaking ? EntityPose.SNEAKING : EntityPose.STANDING; + } + + static void setBlock(World world, int x, int y, int z, int blockState){ + IBlockData blockData = Objects.requireNonNull(net.minecraft.server.v1_14_R1.Block.REGISTRY_ID.fromId(blockState)); + WorldServer cworld = ((CraftWorld)world).getHandle(); + BlockPosition pos = new BlockPosition(x, y, z); + cworld.removeTileEntity(pos); + cworld.setTypeAndData(pos, blockData, 1042); + cworld.getChunkProvider().flagDirty(pos); + } +} diff --git a/FightSystem_15/src/de/steamwar/fightsystem/record/RecordSystem_15.java b/FightSystem_15/src/de/steamwar/fightsystem/record/RecordSystem_15.java index 6d1a1e3..db63363 100644 --- a/FightSystem_15/src/de/steamwar/fightsystem/record/RecordSystem_15.java +++ b/FightSystem_15/src/de/steamwar/fightsystem/record/RecordSystem_15.java @@ -19,13 +19,34 @@ package de.steamwar.fightsystem.record; +import net.minecraft.server.v1_15_R1.BlockPosition; +import net.minecraft.server.v1_15_R1.EntityPose; +import net.minecraft.server.v1_15_R1.IBlockData; +import net.minecraft.server.v1_15_R1.WorldServer; +import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock; +import java.util.Objects; + class RecordSystem_15 { private RecordSystem_15(){} static int blockToId(Block block){ return net.minecraft.server.v1_15_R1.Block.REGISTRY_ID.getId(((CraftBlock)block).getNMS()); } + + static Object getPose(boolean sneaking){ + return sneaking ? EntityPose.CROUCHING : EntityPose.STANDING; + } + + static void setBlock(World world, int x, int y, int z, int blockState){ + IBlockData blockData = Objects.requireNonNull(net.minecraft.server.v1_15_R1.Block.REGISTRY_ID.fromId(blockState)); + WorldServer cworld = ((CraftWorld)world).getHandle(); + BlockPosition pos = new BlockPosition(x, y, z); + cworld.removeTileEntity(pos); + cworld.setTypeAndData(pos, blockData, 1042); + cworld.getChunkProvider().flagDirty(pos); + } } diff --git a/FightSystem_8/src/de/steamwar/fightsystem/record/RecordSystem_8.java b/FightSystem_8/src/de/steamwar/fightsystem/record/RecordSystem_8.java index 207a3fd..19dfa53 100644 --- a/FightSystem_8/src/de/steamwar/fightsystem/record/RecordSystem_8.java +++ b/FightSystem_8/src/de/steamwar/fightsystem/record/RecordSystem_8.java @@ -19,13 +19,18 @@ package de.steamwar.fightsystem.record; +import org.bukkit.World; import org.bukkit.block.Block; +@SuppressWarnings("deprecation") class RecordSystem_8 { private RecordSystem_8(){} - @SuppressWarnings("deprecation") static int blockToId(Block block){ return block.getTypeId() << 4 + block.getData(); } + + static void setBlock(World world, int x, int y, int z, int blockState){ + world.getBlockAt(x, y, z).setTypeIdAndData(blockState >> 4, (byte)(blockState & 0b1111), false); + } } diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightSchematic.java b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightSchematic.java index 7ec3d43..5dc4346 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightSchematic.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightSchematic.java @@ -25,7 +25,6 @@ import de.steamwar.core.VersionedRunnable; import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; -import de.steamwar.fightsystem.IFightSystem; import de.steamwar.fightsystem.record.RecordSystem; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependent; @@ -33,13 +32,12 @@ import de.steamwar.fightsystem.utils.ColorConverter; import de.steamwar.fightsystem.utils.Region; import de.steamwar.sql.NoClipboardException; import de.steamwar.sql.Schematic; -import org.bukkit.*; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.Block; -import org.bukkit.event.EventHandler; import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.event.block.*; -import org.bukkit.event.inventory.InventoryMoveItemEvent; import java.io.IOException; import java.util.List; @@ -145,7 +143,7 @@ public class FightSchematic extends StateDependent { throw securityException; } - Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> HandlerList.unregisterAll(freezer), 3); + Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), freezer::disable, 3); Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), team::teleportToSpawn, 40); } @@ -174,45 +172,4 @@ public class FightSchematic extends StateDependent { block.setType(replacement); }); } - - private static class FreezeWorld implements Listener { - private FreezeWorld(){ - Bukkit.getPluginManager().registerEvents(this, IFightSystem.getPlugin()); - } - - @EventHandler - public void onBlockPhysicsEvent(BlockPhysicsEvent e){ - e.setCancelled(true); - } - - @EventHandler - public void onPistonExtend(BlockPistonExtendEvent e){ - e.setCancelled(true); - } - - @EventHandler - public void onPistonRetract(BlockPistonRetractEvent e){ - e.setCancelled(true); - } - - @EventHandler - public void onBlockGrow(BlockGrowEvent e){ - e.setCancelled(true); - } - - @EventHandler - public void onRedstoneEvent(BlockRedstoneEvent e){ - e.setNewCurrent(e.getOldCurrent()); - } - - @EventHandler - public void onBlockDispense(BlockDispenseEvent e){ - e.setCancelled(true); - } - - @EventHandler - public void onInventoryMoveEvent(InventoryMoveItemEvent e){ - e.setCancelled(true); - } - } } diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java index dcdacea..944d194 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -83,10 +83,10 @@ public class FightTeam implements IFightTeam{ new KitLoader(); new SpectateHandler(); - if(FightScoreboard.getScoreboard().getTeam(name) == null) - team = FightScoreboard.getScoreboard().registerNewTeam(name); + if(FightScoreboard.getBukkit().getTeam(name) == null) + team = FightScoreboard.getBukkit().registerNewTeam(name); else - team = FightScoreboard.getScoreboard().getTeam(name); + team = FightScoreboard.getBukkit().getTeam(name); assert team != null; setTeamColor(team, color); //noinspection deprecation diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightWorld.java b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightWorld.java index 342f1a4..a6343fd 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightWorld.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightWorld.java @@ -38,7 +38,7 @@ public class FightWorld extends StateDependent { paper = Bukkit.getVersion().contains("git-Paper"); } - private final World world = Bukkit.getWorlds().get(0); + private static final World world = Bukkit.getWorlds().get(0); public FightWorld() { super(ArenaMode.Restartable, FightState.Schem); @@ -56,6 +56,19 @@ public class FightWorld extends StateDependent { @Override public void disable() { + resetWorld(); + } + + public static void forceLoad(){ + Config.ArenaRegion.forEachChunk((cX, cZ) -> { + world.loadChunk(cX, cZ); + world.setChunkForceLoaded(cX, cZ, true); + }); + world.setSpawnLocation(Config.SpecSpawn); + world.setKeepSpawnInMemory(true); + } + + public static void resetWorld(){ for(Entity entity : world.getEntities()){ if(entity.getType() != EntityType.PLAYER){ entity.remove(); @@ -68,7 +81,7 @@ public class FightWorld extends StateDependent { Bukkit.unloadWorld(backup, false); } - private void resetChunk(World backup, int x, int z, boolean isPaper){ + private static void resetChunk(World backup, int x, int z, boolean isPaper){ VersionedRunnable.call( new VersionedRunnable(() -> FightWorld_8.resetChunk(world, backup, x, z, isPaper), 8), new VersionedRunnable(() -> FightWorld_9.resetChunk(world, backup, x, z, isPaper), 9), diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FreezeWorld.java b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FreezeWorld.java new file mode 100644 index 0000000..b3efc75 --- /dev/null +++ b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FreezeWorld.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.fight; + +import de.steamwar.fightsystem.IFightSystem; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.block.*; +import org.bukkit.event.inventory.InventoryMoveItemEvent; + +public class FreezeWorld implements Listener { + public FreezeWorld(){ + Bukkit.getPluginManager().registerEvents(this, IFightSystem.getPlugin()); + } + + public void disable(){ + HandlerList.unregisterAll(this); + } + + @EventHandler + public void onBlockPhysicsEvent(BlockPhysicsEvent e){ + e.setCancelled(true); + } + + @EventHandler + public void onPistonExtend(BlockPistonExtendEvent e){ + e.setCancelled(true); + } + + @EventHandler + public void onPistonRetract(BlockPistonRetractEvent e){ + e.setCancelled(true); + } + + @EventHandler + public void onBlockGrow(BlockGrowEvent e){ + e.setCancelled(true); + } + + @EventHandler + public void onRedstoneEvent(BlockRedstoneEvent e){ + e.setNewCurrent(e.getOldCurrent()); + } + + @EventHandler + public void onBlockDispense(BlockDispenseEvent e){ + e.setCancelled(true); + } + + @EventHandler + public void onInventoryMoveEvent(InventoryMoveItemEvent e){ + e.setCancelled(true); + } +} diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/listener/FightScoreboard.java b/FightSystem_Main/src/de/steamwar/fightsystem/listener/FightScoreboard.java index 7de7628..ad00139 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/listener/FightScoreboard.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/listener/FightScoreboard.java @@ -43,20 +43,28 @@ import java.util.*; public class FightScoreboard implements Listener, ScoreboardCallback { - private static final Set fullScoreboard = EnumSet.of(FightState.RUNNING, FightState.SPECTATE); + public static Scoreboard getBukkit() { + return Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard(); + } + private static final Set fullScoreboard = EnumSet.of(FightState.RUNNING, FightState.SPECTATE); + private static FightScoreboard scoreboard; + + public static FightScoreboard getScoreboard(){ + return scoreboard; + } + + private boolean replaying = false; private int index = 0; private String title = ""; private final HashMap scores = new HashMap<>(); - public static Scoreboard getScoreboard() { - return Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard(); - } public FightScoreboard(){ new StateDependentListener(ArenaMode.AntiSpectate, FightState.All, this); new StateDependentTask(ArenaMode.AntiSpectate, FightState.All, this::updateScoreboard, 0, 20); + scoreboard = this; } @EventHandler @@ -106,7 +114,9 @@ public class FightScoreboard implements Listener, ScoreboardCallback { } private void updateScoreboard() { - scores.clear(); + if(replaying) + return; + switch((index++ / 10) % 3){ case 0: generalScoreboard(); @@ -119,12 +129,17 @@ public class FightScoreboard implements Listener, ScoreboardCallback { } } - private void setTitle(String t) { + public void setReplaying(boolean replaying) { + this.replaying = replaying; + } + + public void setTitle(String t) { + scores.clear(); title = t; RecordSystem.scoreboardTitle(t); } - private void addScore(String string, int i) { + public void addScore(String string, int i) { scores.put(string, i); RecordSystem.scoreboardData(string, i); } diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/record/BlockTextCreator.java b/FightSystem_Main/src/de/steamwar/fightsystem/record/BlockTextCreator.java new file mode 100644 index 0000000..957286f --- /dev/null +++ b/FightSystem_Main/src/de/steamwar/fightsystem/record/BlockTextCreator.java @@ -0,0 +1,150 @@ +/* + 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.jnbt.NBTInputStream; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitWorld; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; +import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicReader; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.math.transform.AffineTransform; +import com.sk89q.worldedit.session.ClipboardHolder; +import com.sk89q.worldedit.world.World; +import de.steamwar.fightsystem.Config; +import de.steamwar.fightsystem.FightSystem; +import de.steamwar.fightsystem.utils.ColorConverter; +import de.steamwar.sql.Team; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.DyeColor; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.zip.GZIPInputStream; + +public class BlockTextCreator { + private BlockTextCreator(){} + + private static final int BETWEEN_CHARACTERS_WIDTH = 1; + + private static final World WORLD = new BukkitWorld(Bukkit.getWorlds().get(0)); + + + private static BlockArrayClipboard[] createText(String text){ + List result = new ArrayList<>(); + for(char c : text.toCharArray()){ + try { + try { + result.add((BlockArrayClipboard) new SpongeSchematicReader(new NBTInputStream(new GZIPInputStream(new FileInputStream(new File(FightSystem.getPlugin().getDataFolder(), "text/" + nameConversion(c) + ".schem"))))).read()); + } catch (FileNotFoundException e) { + Bukkit.getLogger().log(Level.WARNING, "Could not display character " + c + " due to missing file!"); + result.add((BlockArrayClipboard) new SpongeSchematicReader(new NBTInputStream(new GZIPInputStream(new FileInputStream(new File(FightSystem.getPlugin().getDataFolder(), "text/.schem"))))).read()); + } + }catch (IOException e) { + throw new SecurityException("Could not load text", e); + } + } + return result.toArray(new BlockArrayClipboard[0]); + } + + private static String nameConversion(char c) { + switch (Character.toUpperCase(c)) { + case '/': + return "slash"; + default: + return c + ""; + } + } + + private static int[] characterSize(BlockArrayClipboard[] characters){ + int[] lengthes = new int[characters.length]; + for(int i = 0; i < lengthes.length; i++) + lengthes[i] = characters[i].getDimensions().getBlockX(); + return lengthes; + } + + private static int[] textOffsets(int[] lengthes){ + int[] offsets = new int[lengthes.length]; + int previousOffset = 0; + for(int i = 0; i < offsets.length; i++){ + offsets[i] = previousOffset; + previousOffset += lengthes[i] + BETWEEN_CHARACTERS_WIDTH; + } + return offsets; + } + + private static int textLength(int[] lengthes, int[] offsets){ + if(lengthes.length == 0) + return 0; + return lengthes[lengthes.length - 1] + offsets[offsets.length - 1]; + } + + private static void pasteChar(BlockArrayClipboard character, int charOffset, int length, int x, int y, int z, AffineTransform transform, DyeColor c){ + BlockVector3 offset = character.getRegion().getMinimumPoint().subtract(character.getOrigin()); + BlockVector3 v = BlockVector3.ZERO.subtract(- charOffset + length / 2, 0, 0).subtract(offset); + v = transform.apply(v.toVector3()).toBlockPoint(); + v = v.add(x, y, z); + + EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(WORLD, -1); + ClipboardHolder ch = new ClipboardHolder(character); + ch.setTransform(transform); + Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(true).build()); + e.flushSession(); + } + + private static void pasteText(String text, int x, int y, int z, AffineTransform transform, DyeColor c){ + BlockArrayClipboard[] characters = createText(text); + int[] lengthes = characterSize(characters); + int[] offsets = textOffsets(lengthes); + int length = textLength(lengthes, offsets); + + for(int i = 0; i < characters.length; i++) + pasteChar(characters[i], offsets[i], length, x, y, z, transform, c); + Paster.replaceTeamColor( + WorldEdit.getInstance().getEditSessionFactory().getEditSession(WORLD, -1), + c, + x - length / 2, y, z, length, 6, 0); + } + + private static void pasteForTeam(int teamId, int x, int z, boolean rotate, String color){ + Team team = Team.get(teamId); + AffineTransform aT = new AffineTransform(); + if(rotate){ + aT = aT.rotateY(180); + z += Config.SchemsizeZ / 2; + }else + z -= Config.SchemsizeZ / 2; + DyeColor c = ColorConverter.chat2dye(ChatColor.getByChar(ChatColor.getLastColors(color).replace("§", ""))); + pasteText(team.getTeamKuerzel(), x, Config.upperArenaBorder + 10, z, aT, c); + } + + public static void pasteTeamNames(int teamBlueId, int teamRedId){ + pasteForTeam(teamBlueId, Config.TeamBluePasteX, Config.TeamBluePasteZ, Config.TeamBlueRotate, Config.TeamBluePrefix); + pasteForTeam(teamRedId, Config.TeamRedPasteX, Config.TeamRedPasteZ, Config.TeamRedRotate, Config.TeamRedPrefix); + } +} diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/record/PacketProcessor.java b/FightSystem_Main/src/de/steamwar/fightsystem/record/PacketProcessor.java index 50685e4..50839ab 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/record/PacketProcessor.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/record/PacketProcessor.java @@ -23,9 +23,11 @@ import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.FightTeam; +import de.steamwar.fightsystem.fight.FightWorld; +import de.steamwar.fightsystem.fight.FreezeWorld; +import de.steamwar.fightsystem.listener.FightScoreboard; import de.steamwar.fightsystem.utils.TechHider; 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; @@ -50,10 +52,12 @@ class PacketProcessor { private final LinkedList syncList = new LinkedList<>(); private final Set hiddenBlockIds = TechHider.getHiddenBlockIds(); private final int obfuscateWith = TechHider.getObfuscateWith(); + private final FreezeWorld freezer = new FreezeWorld(); public PacketProcessor(PacketSource source){ this.source = source; + FightScoreboard.getScoreboard().setReplaying(true); if(source.async()) { Bukkit.getScheduler().runTaskAsynchronously(FightSystem.getPlugin(), this::process); task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::runSync, 1, 1); @@ -88,11 +92,8 @@ class PacketProcessor { 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)); + execSync(() -> new REntity(entityId, userId)); } private void entityMoves() throws IOException { @@ -197,17 +198,7 @@ class PacketProcessor { if(!Config.ArenaRegion.in2dRegion(x, z)) return; //Outside of the arena - if (TechHider.ENABLED && hiddenBlockIds.contains(blockState)) { - blockState = 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); - }); + execSync(() -> RecordSystem.setBlock(x, y, z, TechHider.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState)); } private void particle() throws IOException { @@ -268,20 +259,22 @@ class PacketProcessor { private void scoreboardTitle() throws IOException { String title = source.rString(); - SpectateSystem.getScoreboard().setTitle(title); + FightScoreboard.getScoreboard().setTitle(title); } private void scoreboardData() throws IOException { String key = source.rString(); int value = source.rInt(); - SpectateSystem.getScoreboard().addValue(key, value); + FightScoreboard.getScoreboard().addScore(key, value); } - private void endSpectating(){ + private void endReplay(){ REntity.dieAll(); - WorldLoader.reloadWorld(); - SpectateSystem.getScoreboard().setTitle("§eKein Kampf"); + FightScoreboard.getScoreboard().setReplaying(false); + freezer.disable(); + //TODO: Stop server if singular replay + FightWorld.resetWorld(); } private void bow() throws IOException { @@ -306,7 +299,6 @@ class PacketProcessor { } private void process(){ - try{ boolean tickFinished = false; while(!source.isClosed() && !tickFinished){ @@ -414,7 +406,7 @@ class PacketProcessor { } if(source.isClosed()){ - Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::endSpectating); + Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::endReplay); task.cancel(); } } diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/record/REntity.java b/FightSystem_Main/src/de/steamwar/fightsystem/record/REntity.java index 9b8df3d..e001101 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/record/REntity.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/record/REntity.java @@ -6,11 +6,11 @@ import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.wrappers.*; import de.steamwar.core.Core; +import de.steamwar.fightsystem.listener.FightScoreboard; import de.steamwar.sql.SteamwarUser; import net.royawesome.jlibnoise.MathHelper; import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.OfflinePlayer; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; @@ -18,6 +18,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.scoreboard.NameTagVisibility; import org.bukkit.scoreboard.Team; +import java.lang.reflect.InvocationTargetException; import java.util.*; public class REntity { @@ -33,39 +34,52 @@ public class REntity { if(entity.fireTick > 0) { entity.fireTick--; if(entity.fireTick == 0) { - //TODO /*DataWatcher dataWatcher = new DataWatcher(null); - DataWatcherObject dataWatcherObject = new DataWatcherObject<>(0, DataWatcherRegistry.a); dataWatcher.register(dataWatcherObject, (byte) 0); dataWatcher.markDirty(dataWatcherObject); entity.sendDataWatcher(dataWatcher);*/ + WrappedDataWatcher watcher = new WrappedDataWatcher(); + watcher.setObject(0, (byte) 0, true); + ProtocolLibrary.getProtocolManager().broadcastServerPacket(entity.getDataWatcherPacket(watcher)); } } }); } - public static void playerJoins(Player player){ - /*for(REntity entity : entities.values()){ - entity.sendToPlayer(player); - entity.sendLocation(player); + public static void playerJoins(Player player) throws InvocationTargetException { + for(REntity entity : entities.values()){ + if(entity.entityType == EntityType.PLAYER){ + ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getPlayerInfoPacket()); + ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getNamedSpawnPacket()); + for (Map.Entry entry : entity.itemSlots.entrySet()) { + ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getEquipmentPacket(entry.getKey(), entry.getValue())); + } + }else{ + ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getSpawnEntityPacket()); + } + //ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getTeleportPacket()); Sollte nicht nötig sein? if(entity.fireTick != 0) { + WrappedDataWatcher watcher = new WrappedDataWatcher(); + watcher.setObject(0, (byte) 1, true); + /*ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getDataWatcherPacket(watcher)); DataWatcher dataWatcher = new DataWatcher(null); - DataWatcherObject dataWatcherObject = new DataWatcherObject<>(0, DataWatcherRegistry.a); dataWatcher.register(dataWatcherObject, (byte) 1); dataWatcher.markDirty(dataWatcherObject); - entity.sendDataWatcher(dataWatcher); + entity.sendDataWatcher(dataWatcher);*/ } if(entity.sneaks) { - DataWatcher dataWatcher = new DataWatcher(null); - + WrappedDataWatcher watcher = new WrappedDataWatcher(); + watcher.setObject(6, RecordSystem.getPose(true), true); + ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getDataWatcherPacket(watcher)); + /*DataWatcher dataWatcher = new DataWatcher(null); DataWatcherObject dataWatcherObject = new DataWatcherObject<>(6, DataWatcherRegistry.s); dataWatcher.register(dataWatcherObject, EntityPose.CROUCHING); dataWatcher.markDirty(dataWatcherObject); - entity.sendDataWatcher(dataWatcher); + entity.sendDataWatcher(dataWatcher);*/ } - }*/ + } } public static void dieAll(){ @@ -73,27 +87,33 @@ public class REntity { entities.clear(); } + private static final String SCOREBOARD_TEAMNAME = "Replay"; private static final Team team; static { - if(Bukkit.getScoreboardManager().getMainScoreboard().getTeam("Replay") == null) - team = Bukkit.getScoreboardManager().getMainScoreboard().registerNewTeam("Replay"); + if(FightScoreboard.getBukkit().getTeam(SCOREBOARD_TEAMNAME) == null) + team = FightScoreboard.getBukkit().registerNewTeam(SCOREBOARD_TEAMNAME); else - team = Bukkit.getScoreboardManager().getMainScoreboard().getTeam("Replay"); + team = FightScoreboard.getBukkit().getTeam(SCOREBOARD_TEAMNAME); team.setNameTagVisibility(NameTagVisibility.NEVER); } private static int entityCount = Integer.MAX_VALUE; private static final Random random = new Random(); - private final int internalId, entityId; + private final int internalId; + private final int entityId; private final UUID uuid; private final EntityType entityType; private final PlayerInfoData playerInfoData; private final Map itemSlots = new HashMap<>(); - private double locX, locY, locZ; - private byte yaw, pitch, headYaw; + private double locX; + private double locY; + private double locZ; + private byte yaw; + private byte pitch; + private byte headYaw; private int fireTick; private boolean sneaks; @@ -107,7 +127,9 @@ public class REntity { this.playerInfoData = new PlayerInfoData(WrappedGameProfile.fromOfflinePlayer(Bukkit.getOfflinePlayer(uuid)), 0, EnumWrappers.NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(user.getUserName())); entities.put(internalId, this); - //TODO: Spawn him! + ProtocolLibrary.getProtocolManager().broadcastServerPacket(getPlayerInfoPacket()); + ProtocolLibrary.getProtocolManager().broadcastServerPacket(getNamedSpawnPacket()); + team.addEntry(user.getUserName()); } public REntity(int internalId, EntityType entityType){ @@ -159,14 +181,19 @@ public class REntity { public void sneak(boolean sneaking) { sneaks = sneaking; - /* - DataWatcher dataWatcher = new DataWatcher(null); + /*DataWatcher dataWatcher = new DataWatcher(null); DataWatcherObject dataWatcherObject = new DataWatcherObject<>(6, DataWatcherRegistry.s); dataWatcher.register(dataWatcherObject, sneaking?EntityPose.CROUCHING:EntityPose.STANDING); - dataWatcher.markDirty(dataWatcherObject); + dataWatcher.markDirty(dataWatcherObject);*/ - sendDataWatcher(dataWatcher);*/ + WrappedDataWatcher watcher = new WrappedDataWatcher(); + if(Core.getVersion() > 12){ + watcher.setObject(6, RecordSystem.getPose(sneaking), true); + }else{ + watcher.setObject(0, sneaking ? (byte) 2 : (byte) 0, true); + } + ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(watcher)); } public void setOnFire(boolean perma) { @@ -177,31 +204,29 @@ public class REntity { } /*DataWatcher dataWatcher = new DataWatcher(null); - DataWatcherObject dataWatcherObject = new DataWatcherObject<>(0, DataWatcherRegistry.a); dataWatcher.register(dataWatcherObject, (byte) 1); - dataWatcher.markDirty(dataWatcherObject); + dataWatcher.markDirty(dataWatcherObject);*/ - sendDataWatcher(dataWatcher);*/ + WrappedDataWatcher watcher = new WrappedDataWatcher(); + watcher.setObject(0, (byte) 1, true); + ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(watcher)); } public void setBowDrawn(boolean drawn, boolean offHand) { /*DataWatcher dataWatcher = new DataWatcher(null); - DataWatcherObject dataWatcherObject = new DataWatcherObject<>(7, DataWatcherRegistry.a); dataWatcher.register(dataWatcherObject, (byte) ((drawn ? 1 : 0) + (offHand ? 2 : 0))); dataWatcher.markDirty(dataWatcherObject); - - sendDataWatcher(dataWatcher); - - private void sendDataWatcher(DataWatcher dataWatcher) { - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entity.getId(), dataWatcher, false); - - for(Player player : Bukkit.getOnlinePlayers()){ - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } - } */ + + WrappedDataWatcher watcher = new WrappedDataWatcher(); + if(Core.getVersion() > 8){ + watcher.setObject(Core.getVersion() > 12 ? 7 : 6, (byte) ((drawn ? 1 : 0) + (offHand ? 2 : 0)), true); + }else{ + watcher.setObject(0, (byte)0x10, true); + } + ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(watcher)); } public void setItem(String item, boolean enchanted, String slot) { @@ -222,9 +247,9 @@ public class REntity { if(entityType == EntityType.PLAYER){ PacketContainer infoPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.PLAYER_INFO); infoPacket.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER); - infoPacket.getPlayerInfoDataLists().write(0, Collections.singletonList(new PlayerInfoData())); + infoPacket.getPlayerInfoDataLists().write(0, Collections.singletonList(playerInfoData)); ProtocolLibrary.getProtocolManager().broadcastServerPacket(infoPacket); - team.removeEntry(name); + team.removeEntry(playerInfoData.getProfile().getName()); } PacketContainer destroyPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_DESTROY); @@ -232,11 +257,6 @@ public class REntity { ProtocolLibrary.getProtocolManager().broadcastServerPacket(destroyPacket); } - private int entityTypeToId(){ - //TODO - return 0; - } - private int calcVelocity(double value) { return (int)(Math.max(-3.9, Math.min(value, 3.9)) * 8000); } @@ -261,6 +281,13 @@ public class REntity { bytes.write(1, pitch); } + private PacketContainer getDataWatcherPacket(WrappedDataWatcher dataWatcher) { + PacketContainer metadataPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); + metadataPacket.getIntegers().write(0, entityId); + metadataPacket.getDataWatcherModifier().write(0, dataWatcher); + return metadataPacket; + } + private PacketContainer getTeleportPacket(){ PacketContainer teleportPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_TELEPORT); fillPositioningPacket(teleportPacket, teleportPacket.getIntegers()); @@ -291,7 +318,17 @@ public class REntity { if(Core.getVersion() > 12){ spawnPacket.getEntityTypeModifier().write(0, entityType); }else{ - ints.write(6, entityTypeToId()); + switch(entityType){ + case PRIMED_TNT: + ints.write(6, 50); + break; + case ARROW: + ints.write(6, 60); + break; + case FIREBALL: + ints.write(6, 63); + break; + } } return spawnPacket; } diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/record/RecordSystem.java b/FightSystem_Main/src/de/steamwar/fightsystem/record/RecordSystem.java index f60741e..9af466b 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/record/RecordSystem.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/record/RecordSystem.java @@ -20,6 +20,7 @@ package de.steamwar.fightsystem.record; import de.steamwar.core.VersionedCallable; +import de.steamwar.core.VersionedRunnable; import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; @@ -323,6 +324,18 @@ public class RecordSystem { private static int blockToId(Block block){ return VersionedCallable.call(new VersionedCallable<>(() -> RecordSystem_8.blockToId(block), 8), + new VersionedCallable<>(() -> RecordSystem_14.blockToId(block), 14), new VersionedCallable<>(() -> RecordSystem_15.blockToId(block), 15)); } + + public static Object getPose(boolean sneaking){ + return VersionedCallable.call(new VersionedCallable<>(() -> RecordSystem_14.getPose(sneaking), 14), + new VersionedCallable<>(() -> RecordSystem_15.getPose(sneaking), 15)); + } + + public static void setBlock(int x, int y, int z, int blockState){ + VersionedRunnable.call(new VersionedRunnable(() -> RecordSystem_8.setBlock(WORLD, x, y, z, blockState), 8), + new VersionedRunnable(() -> RecordSystem_14.setBlock(WORLD, x, y, z, blockState), 14), + new VersionedRunnable(() -> RecordSystem_15.setBlock(WORLD, x, y, z, blockState), 15)); + } }