From b466d7fbffd710f460d7a1120254be9e363aafbd Mon Sep 17 00:00:00 2001 From: yoyosource Date: Sat, 8 Apr 2023 15:11:06 +0200 Subject: [PATCH] Add GhostJumpAndRun --- .../lobby/jumpandrun/GhostJumpAndRun.java | 148 ++++++++++++++++++ .../steamwar/lobby/jumpandrun/JumpAndRun.java | 46 +++++- 2 files changed, 189 insertions(+), 5 deletions(-) create mode 100644 src/de/steamwar/lobby/jumpandrun/GhostJumpAndRun.java diff --git a/src/de/steamwar/lobby/jumpandrun/GhostJumpAndRun.java b/src/de/steamwar/lobby/jumpandrun/GhostJumpAndRun.java new file mode 100644 index 0000000..2fb3902 --- /dev/null +++ b/src/de/steamwar/lobby/jumpandrun/GhostJumpAndRun.java @@ -0,0 +1,148 @@ +package de.steamwar.lobby.jumpandrun; + +import de.steamwar.entity.REntityServer; +import de.steamwar.entity.RPlayer; +import de.steamwar.lobby.LobbySystem; +import de.steamwar.sql.UserConfig; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.*; + +import static de.steamwar.lobby.jumpandrun.JumpAndRun.JUMP_AND_RUN_REPLAY_CONFIG; + +public class GhostJumpAndRun implements Listener { + + private Player player; + + private BukkitRunnable recordingRunnable; + private List recordingList = new ArrayList<>(); + + private BukkitRunnable replayRunnable; + private List replayList = new ArrayList<>(); + private REntityServer entityServer; + private RPlayer entityPlayer; + + public GhostJumpAndRun(Player player) { + this.player = player; + + String s = UserConfig.getConfig(player.getUniqueId(), JUMP_AND_RUN_REPLAY_CONFIG); + if (s == null) return; + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(Base64.getDecoder().decode(s)); + while (byteArrayInputStream.available() > 0) { + int x = byteArrayInputStream.read() << 24; + x |= byteArrayInputStream.read() << 16; + x |= byteArrayInputStream.read() << 8; + x |= byteArrayInputStream.read(); + int y = byteArrayInputStream.read() << 24; + y |= byteArrayInputStream.read() << 16; + y |= byteArrayInputStream.read() << 8; + y |= byteArrayInputStream.read(); + int z = byteArrayInputStream.read() << 24; + z |= byteArrayInputStream.read() << 16; + z |= byteArrayInputStream.read() << 8; + z |= byteArrayInputStream.read(); + replayList.add(new Vector(Float.intBitsToFloat(x), Float.intBitsToFloat(y), Float.intBitsToFloat(z))); + } + } + + public void record() { + if (recordingRunnable != null) return; + recordingList.clear(); + recordingRunnable = new BukkitRunnable() { + @Override + public void run() { + recordingList.add(player.getLocation().toVector()); + } + }; + recordingRunnable.runTaskTimer(LobbySystem.getPlugin(), 1, 2); + } + + public void stop() { + if (recordingRunnable == null) return; + recordingRunnable.cancel(); + recordingRunnable = null; + if (recordingRunnable != null) { + replayRunnable.cancel(); + replayRunnable = null; + } + if (entityServer != null) { + entityServer.close(); + entityServer = null; + entityPlayer = null; + } + } + + public void saveBestTime() { + replayList = recordingList; + recordingList = new ArrayList<>(); + } + + public void saveToDB() { + if (replayList.size() > 4000) { + return; + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + for (Vector vector : replayList) { + int x = Float.floatToIntBits((float) vector.getX()); + int y = Float.floatToIntBits((float) vector.getY()); + int z = Float.floatToIntBits((float) vector.getZ()); + outputStream.write(x >> 24); + outputStream.write(x >> 16); + outputStream.write(x >> 8); + outputStream.write(x); + outputStream.write(y >> 24); + outputStream.write(y >> 16); + outputStream.write(y >> 8); + outputStream.write(y); + outputStream.write(z >> 24); + outputStream.write(z >> 16); + outputStream.write(z >> 8); + outputStream.write(z); + } + String replay = Base64.getEncoder().encodeToString(outputStream.toByteArray()); + UserConfig.updatePlayerConfig(player.getUniqueId(), JUMP_AND_RUN_REPLAY_CONFIG, replay); + } + + public void replay() { + if (replayRunnable != null) return; + if (replayList.isEmpty()) return; + + entityServer = new REntityServer(); + entityServer.addPlayer(player); + entityPlayer = new RPlayer(entityServer, UUID.randomUUID(), "Ghost", player.getLocation()); + entityPlayer.setGlowing(true); + entityPlayer.setInvisible(true); + + Iterator iterator = replayList.iterator(); + replayRunnable = new BukkitRunnable() { + @Override + public void run() { + if (!iterator.hasNext()) { + replayRunnable.cancel(); + replayRunnable = null; + entityServer.close(); + entityServer = null; + entityPlayer = null; + return; + } + entityPlayer.move(iterator.next().toLocation(player.getWorld())); + } + }; + replayRunnable.runTaskTimer(LobbySystem.getPlugin(), 1, 2); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + if (event.getPlayer() != player) return; + if (entityServer != null) entityServer.close(); + if (recordingRunnable != null) recordingRunnable.cancel(); + if (replayRunnable != null) replayRunnable.cancel(); + } +} diff --git a/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java b/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java index 64e9b13..ed16e47 100644 --- a/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java +++ b/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java @@ -3,6 +3,7 @@ package de.steamwar.lobby.jumpandrun; import de.steamwar.lobby.LobbySystem; import de.steamwar.lobby.listener.BasicListener; import de.steamwar.lobby.listener.PlayerSpawn; +import de.steamwar.lobby.util.Leaderboard; import de.steamwar.sql.UserConfig; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.Bukkit; @@ -13,6 +14,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; @@ -23,6 +25,9 @@ import java.util.*; public class JumpAndRun extends BasicListener { + public static final String JUMP_AND_RUN_CONFIG = "jump_and_run"; + public static final String JUMP_AND_RUN_REPLAY_CONFIG = "jump_and_run_replay"; + private static final String BAR_EMPTY = "||||||||||||||||||||||||||||||"; public static List points = new ArrayList<>(); @@ -33,6 +38,10 @@ public class JumpAndRun extends BasicListener { private static final Map CLICKED = new HashMap<>(); private static final Map CLICKED_COUNT = new HashMap<>(); + private static final Map GHOSTS = new HashMap<>(); + + private static final Leaderboard LEADERBOARD = new Leaderboard(LobbySystem.getEntityServer(false), JUMP_AND_RUN_CONFIG, new Location(Bukkit.getWorlds().get(0), 2338.5, 42.5, 1231.5), 5); + { Bukkit.getScheduler().runTaskTimer(LobbySystem.getPlugin(), () -> { Set toReset = new HashSet<>(); @@ -75,6 +84,7 @@ public class JumpAndRun extends BasicListener { } }); toReset.forEach(player -> { + GHOSTS.get(player).stop(); reset(player); player.teleport(Bukkit.getWorlds().get(0).getSpawnLocation().clone().add(0.5, 0, 0.5)); }); @@ -116,40 +126,66 @@ public class JumpAndRun extends BasicListener { event.getPlayer().getInventory().setItem(4, new ItemStack(Material.COMPASS, 1)); FAILS.put(event.getPlayer(), 0); START.put(event.getPlayer(), System.currentTimeMillis()); + GHOSTS.get(event.getPlayer()).record(); + GHOSTS.get(event.getPlayer()).replay(); } if (index == points.size() - 1) { long time = System.currentTimeMillis() - START.get(event.getPlayer()); SimpleDateFormat format = new SimpleDateFormat(LobbySystem.getMessage().parse("JUMP_AND_RUN_TIME", event.getPlayer()), Locale.ROOT); String parsed = format.format(new Date(time)); LobbySystem.getMessage().sendPrefixless("JUMP_AND_RUN_FINISHED", event.getPlayer(), parsed.substring(0, parsed.length() - 2), FAILS.get(event.getPlayer())); + GHOSTS.get(event.getPlayer()).stop(); updateJumpAndRunTime(event.getPlayer(), time); reset(event.getPlayer()); } } private void updateJumpAndRunTime(Player player, long time) { - String jumpAndRunTimeConfig = UserConfig.getConfig(player.getUniqueId(), "jump_and_run"); + boolean needsSave = true; + if (UserConfig.getConfig(player.getUniqueId(), JUMP_AND_RUN_REPLAY_CONFIG) == null) { + GHOSTS.get(player).saveBestTime(); + GHOSTS.get(player).saveToDB(); + needsSave = false; + } + + String jumpAndRunTimeConfig = UserConfig.getConfig(player.getUniqueId(), JUMP_AND_RUN_CONFIG); if (jumpAndRunTimeConfig == null) { - UserConfig.updatePlayerConfig(player.getUniqueId(), "jump_and_run", time + ""); + UserConfig.updatePlayerConfig(player.getUniqueId(), JUMP_AND_RUN_CONFIG, time + ""); + if (needsSave) { + GHOSTS.get(player).saveBestTime(); + GHOSTS.get(player).saveToDB(); + } } else { long jumpAndRunTime = Long.parseLong(jumpAndRunTimeConfig); if (time < jumpAndRunTime) { SimpleDateFormat format = new SimpleDateFormat(LobbySystem.getMessage().parse("JUMP_AND_RUN_TIME", player), Locale.ROOT); String parsed = format.format(new Date(jumpAndRunTime - time)); LobbySystem.getMessage().sendPrefixless("JUMP_AND_RUN_PERSONAL_BEST", player, parsed); - UserConfig.updatePlayerConfig(player.getUniqueId(), "jump_and_run", time + ""); + UserConfig.updatePlayerConfig(player.getUniqueId(), JUMP_AND_RUN_CONFIG, time + ""); + if (needsSave) { + GHOSTS.get(player).saveBestTime(); + GHOSTS.get(player).saveToDB(); + } + LEADERBOARD.update(); } } } + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + GHOSTS.put(player, new GhostJumpAndRun(player)); + } + @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { Player player = event.getPlayer(); CURRENT_POS.remove(player); START.remove(player); FAILS.remove(player); - CLICKED.remove(event.getPlayer()); - CLICKED_COUNT.remove(event.getPlayer()); + CLICKED.remove(player); + CLICKED_COUNT.remove(player); + GHOSTS.remove(player); } @EventHandler