From c30e831c149e42dd576b7218450b3464c5ef9638 Mon Sep 17 00:00:00 2001 From: Iaiao Date: Sun, 10 Jan 2021 14:46:00 +0200 Subject: [PATCH 01/12] Use server's chat messages' format instead of getting those from config --- .../replay/filesystem/ConfigManager.java | 12 ------------ .../recording/RecordingListener.java | 11 ++++++----- .../replaysystem/replaying/ReplayingUtils.java | 16 +--------------- 3 files changed, 7 insertions(+), 32 deletions(-) diff --git a/src/me/jumper251/replay/filesystem/ConfigManager.java b/src/me/jumper251/replay/filesystem/ConfigManager.java index 90769baa..93adf6d6 100644 --- a/src/me/jumper251/replay/filesystem/ConfigManager.java +++ b/src/me/jumper251/replay/filesystem/ConfigManager.java @@ -32,8 +32,6 @@ public class ConfigManager { public static ReplayQuality QUALITY = ReplayQuality.HIGH; - public static String DEATH_MESSAGE, LEAVE_MESSAGE, CHAT_FORMAT, JOIN_MESSAGE; - public static void loadConfigs() { if(!sqlFile.exists()){ sqlCfg.set("host", "localhost"); @@ -59,17 +57,12 @@ public static void loadConfigs() { cfg.set("general.hide_players", false); cfg.set("general.add_new_players", false); cfg.set("general.update_notifications", true); - - cfg.set("general.death_message", "&6{name} &7died."); - cfg.set("general.quit_message", "&6{name} &7left the game."); - cfg.set("general.join_message", "&6{name} &7joined the game."); cfg.set("recording.blocks.enabled", true); cfg.set("recording.blocks.real_changes", true); cfg.set("recording.entities.enabled", false); cfg.set("recording.entities.items.enabled", true); cfg.set("recording.chat.enabled", false); - cfg.set("recording.chat.format", "&r<{name}> {message}"); try { @@ -96,11 +89,6 @@ public static void loadData(boolean initial) { UPDATE_NOTIFY = cfg.getBoolean("general.update_notifications"); if (initial ) USE_DATABASE = cfg.getBoolean("general.use_mysql"); - DEATH_MESSAGE = cfg.getString("general.death_message"); - LEAVE_MESSAGE = cfg.getString("general.quit_message"); - JOIN_MESSAGE = cfg.getString("general.join_message"); - CHAT_FORMAT = cfg.getString("recording.chat.format"); - RECORD_BLOCKS = cfg.getBoolean("recording.blocks.enabled"); REAL_CHANGES = cfg.getBoolean("recording.blocks.real_changes"); RECORD_ITEMS = cfg.getBoolean("recording.entities.items.enabled"); diff --git a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java index e2198aa0..f85c2281 100644 --- a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java +++ b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java @@ -182,12 +182,11 @@ public void onCrit(EntityDamageByEntityEvent e) { } } - @EventHandler + @EventHandler (ignoreCancelled = true, priority = EventPriority.MONITOR) public void onChat(AsyncPlayerChatEvent e) { Player p = e.getPlayer(); if (recorder.getPlayers().contains(p.getName())) { - - this.packetRecorder.addData(p.getName(), new ChatData(e.getMessage())); + this.packetRecorder.addData(p.getName(), new ChatData(String.format(e.getFormat(), e.getPlayer().getDisplayName(), e.getMessage()))); } } @@ -221,17 +220,18 @@ public void onQuit(PlayerQuitEvent e) { this.recorder.getPlayers().remove(p.getName()); if (!this.replayLeft.contains(p.getName())) this.replayLeft.add(p.getName()); + this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getQuitMessage()))); } } - @EventHandler + @EventHandler (priority = EventPriority.MONITOR) public void onJoin(PlayerJoinEvent e) { Player p = e.getPlayer(); if (!this.recorder.getPlayers().contains(p.getName()) && (this.replayLeft.contains(p.getName())) || ConfigManager.ADD_PLAYERS) { this.recorder.getPlayers().add(p.getName()); this.recorder.getData().getWatchers().put(p.getName(), new PlayerWatcher(p.getName())); this.recorder.createSpawnAction(p, p.getLocation(), false); - this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(new MessageBuilder(ConfigManager.JOIN_MESSAGE).set("name", p.getName()).build()))); + this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getJoinMessage()))); } } @@ -241,6 +241,7 @@ public void onDeath(PlayerDeathEvent e) { Player p = e.getEntity(); if (this.recorder.getPlayers().contains(p.getName())) { this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(0, ActionType.DEATH, p.getName(), null)); + this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getDeathMessage()))); } } diff --git a/src/me/jumper251/replay/replaysystem/replaying/ReplayingUtils.java b/src/me/jumper251/replay/replaysystem/replaying/ReplayingUtils.java index 9efb33c4..9d27976f 100644 --- a/src/me/jumper251/replay/replaysystem/replaying/ReplayingUtils.java +++ b/src/me/jumper251/replay/replaysystem/replaying/ReplayingUtils.java @@ -138,11 +138,7 @@ public void handleAction(ActionData action, ReplayData data, boolean reversed) { if (action.getPacketData() instanceof ChatData) { ChatData chatData = (ChatData) action.getPacketData(); - - replayer.sendMessage(new MessageBuilder(ConfigManager.CHAT_FORMAT) - .set("name", action.getName()) - .set("message", chatData.getMessage()) - .build()); + replayer.sendMessage(chatData.getMessage()); } if (action.getPacketData() instanceof InvData) { @@ -331,16 +327,6 @@ public void handleAction(ActionData action, ReplayData data, boolean reversed) { SpawnData oldSpawnData = new SpawnData(npc.getUuid(), LocationData.fromLocation(npc.getLocation()), signatures.get(action.getName())); this.lastSpawnActions.addLast(new ActionData(0, ActionType.SPAWN, action.getName(), oldSpawnData)); - if (action.getType() == ActionType.DESPAWN) { - replayer.sendMessage(new MessageBuilder(ConfigManager.LEAVE_MESSAGE) - .set("name", action.getName()) - .build()); - } else { - replayer.sendMessage(new MessageBuilder(ConfigManager.DEATH_MESSAGE) - .set("name", action.getName()) - .build()); - } - } else { if (!this.lastSpawnActions.isEmpty()) { From 33ecb0089fc27db735566ad43df46500d8c5aea3 Mon Sep 17 00:00:00 2001 From: Iaiao Date: Sun, 10 Jan 2021 16:43:09 +0200 Subject: [PATCH 02/12] Add an option to log everything in chat --- .../packetwrapper/WrapperPlayServerChat.java | 104 ++++++++++++++++++ .../replay/filesystem/ConfigManager.java | 4 +- .../recording/PacketRecorder.java | 20 +++- .../replaysystem/recording/Recorder.java | 1 - .../recording/RecordingListener.java | 6 +- 5 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 src/com/comphenix/packetwrapper/WrapperPlayServerChat.java diff --git a/src/com/comphenix/packetwrapper/WrapperPlayServerChat.java b/src/com/comphenix/packetwrapper/WrapperPlayServerChat.java new file mode 100644 index 00000000..aa425390 --- /dev/null +++ b/src/com/comphenix/packetwrapper/WrapperPlayServerChat.java @@ -0,0 +1,104 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.comphenix.packetwrapper; + +import java.util.Arrays; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers; +import com.comphenix.protocol.wrappers.EnumWrappers.ChatType; +import com.comphenix.protocol.wrappers.WrappedChatComponent; + +public class WrapperPlayServerChat extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.CHAT; + + public WrapperPlayServerChat() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerChat(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve the chat message. + *

+ * Limited to 32767 bytes + * + * @return The current message + */ + public WrappedChatComponent getMessage() { + return handle.getChatComponents().read(0); + } + + /** + * Set the message. + * + * @param value - new value. + */ + public void setMessage(WrappedChatComponent value) { + handle.getChatComponents().write(0, value); + } + + public ChatType getChatType() { + return handle.getChatTypes().read(0); + } + + public void setChatType(ChatType type) { + handle.getChatTypes().write(0, type); + } + + /** + * Retrieve Position. + *

+ * Notes: 0 - Chat (chat box) ,1 - System Message (chat box), 2 - Above + * action bar + * + * @return The current Position + * @deprecated Magic values replaced by enum + */ + @Deprecated + public byte getPosition() { + Byte position = handle.getBytes().readSafely(0); + if (position != null) { + return position; + } else { + return getChatType().getId(); + } + } + + /** + * Set Position. + * + * @param value - new value. + * @deprecated Magic values replaced by enum + */ + @Deprecated + public void setPosition(byte value) { + handle.getBytes().writeSafely(0, value); + + if (EnumWrappers.getChatTypeClass() != null) + { + Arrays.stream(ChatType.values()).filter(t -> t.getId() == value).findAny() + .ifPresent(t -> handle.getChatTypes().writeSafely(0, t)); + } + } +} \ No newline at end of file diff --git a/src/me/jumper251/replay/filesystem/ConfigManager.java b/src/me/jumper251/replay/filesystem/ConfigManager.java index 93adf6d6..7f3d63a6 100644 --- a/src/me/jumper251/replay/filesystem/ConfigManager.java +++ b/src/me/jumper251/replay/filesystem/ConfigManager.java @@ -27,7 +27,7 @@ public class ConfigManager { public static boolean RECORD_BLOCKS, REAL_CHANGES; public static boolean RECORD_ITEMS, RECORD_ENTITIES; - public static boolean RECORD_CHAT; + public static boolean RECORD_CHAT, RECORD_EVERYTHING_IN_CHAT; public static boolean SAVE_STOP, USE_OFFLINE_SKINS, HIDE_PLAYERS, UPDATE_NOTIFY, USE_DATABASE, ADD_PLAYERS; public static ReplayQuality QUALITY = ReplayQuality.HIGH; @@ -63,6 +63,7 @@ public static void loadConfigs() { cfg.set("recording.entities.enabled", false); cfg.set("recording.entities.items.enabled", true); cfg.set("recording.chat.enabled", false); + cfg.set("recording.chat.everything", false); try { @@ -94,6 +95,7 @@ public static void loadData(boolean initial) { RECORD_ITEMS = cfg.getBoolean("recording.entities.items.enabled"); RECORD_ENTITIES = cfg.getBoolean("recording.entities.enabled"); RECORD_CHAT = cfg.getBoolean("recording.chat.enabled"); + RECORD_EVERYTHING_IN_CHAT = cfg.getBoolean("recording.chat.everything"); if (USE_DATABASE) { diff --git a/src/me/jumper251/replay/replaysystem/recording/PacketRecorder.java b/src/me/jumper251/replay/replaysystem/recording/PacketRecorder.java index 84b58ad4..96cd91fd 100644 --- a/src/me/jumper251/replay/replaysystem/recording/PacketRecorder.java +++ b/src/me/jumper251/replay/replaysystem/recording/PacketRecorder.java @@ -13,12 +13,15 @@ import java.util.HashMap; import java.util.List; +import java.util.Arrays; import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import net.md_5.bungee.chat.ComponentSerializer; +import net.md_5.bungee.api.chat.TextComponent; import com.comphenix.packetwrapper.WrapperPlayClientBlockDig; import com.comphenix.packetwrapper.WrapperPlayClientEntityAction; @@ -32,6 +35,7 @@ import com.comphenix.packetwrapper.WrapperPlayServerRelEntityMoveLook; import com.comphenix.packetwrapper.WrapperPlayServerSpawnEntity; import com.comphenix.packetwrapper.WrapperPlayServerSpawnEntityLiving; +import com.comphenix.packetwrapper.WrapperPlayServerChat; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.ListenerPriority; @@ -59,6 +63,7 @@ import me.jumper251.replay.replaysystem.utils.NPCManager; import me.jumper251.replay.utils.VersionUtil; import me.jumper251.replay.utils.VersionUtil.VersionEnum; +import me.jumper251.replay.replaysystem.data.types.ChatData; @@ -102,7 +107,7 @@ public void register() { this.packetAdapter = new PacketAdapter(ReplaySystem.getInstance(), ListenerPriority.HIGHEST, PacketType.Play.Client.POSITION, PacketType.Play.Client.POSITION_LOOK, PacketType.Play.Client.LOOK, PacketType.Play.Client.ENTITY_ACTION, PacketType.Play.Client.ARM_ANIMATION, PacketType.Play.Client.BLOCK_DIG, PacketType.Play.Server.SPAWN_ENTITY, PacketType.Play.Server.ENTITY_DESTROY, PacketType.Play.Server.ENTITY_VELOCITY, PacketType.Play.Server.SPAWN_ENTITY_LIVING, - PacketType.Play.Server.REL_ENTITY_MOVE, PacketType.Play.Server.REL_ENTITY_MOVE_LOOK, PacketType.Play.Server.ENTITY_LOOK, PacketType.Play.Server.POSITION, PacketType.Play.Server.ENTITY_TELEPORT) { + PacketType.Play.Server.REL_ENTITY_MOVE, PacketType.Play.Server.REL_ENTITY_MOVE_LOOK, PacketType.Play.Server.ENTITY_LOOK, PacketType.Play.Server.POSITION, PacketType.Play.Server.ENTITY_TELEPORT, PacketType.Play.Server.CHAT) { @Override public void onPacketReceiving(PacketEvent event) { @@ -303,6 +308,19 @@ public void onPacketSending(PacketEvent event) { addData(p.getName(), new EntityMovingData(packet.getEntityID(), loc.getX(), loc.getY(), loc.getZ(), packet.getPitch(), packet.getYaw())); } } + if(event.getPacketType() == PacketType.Play.Server.CHAT) { + if(ConfigManager.RECORD_CHAT && ConfigManager.RECORD_EVERYTHING_IN_CHAT) { + + WrapperPlayServerChat packet = new WrapperPlayServerChat(event.getPacket()); + + String message = Arrays.stream(ComponentSerializer.parse(packet.getMessage().getJson())).reduce(new TextComponent(), (a, b) -> { + a.addExtra(b); + return a; + }).toLegacyText(); + addData(p.getName(), new ChatData(String.format("[%s received] %s", p.getName(), message))); + + } + } } diff --git a/src/me/jumper251/replay/replaysystem/recording/Recorder.java b/src/me/jumper251/replay/replaysystem/recording/Recorder.java index 7bb15152..0d7d2e64 100644 --- a/src/me/jumper251/replay/replaysystem/recording/Recorder.java +++ b/src/me/jumper251/replay/replaysystem/recording/Recorder.java @@ -90,7 +90,6 @@ public void run() { if (packetData instanceof BlockChangeData && !ConfigManager.RECORD_BLOCKS) continue; if (packetData instanceof EntityItemData && !ConfigManager.RECORD_ITEMS) continue; if ((packetData instanceof EntityData || packetData instanceof EntityMovingData || packetData instanceof EntityAnimationData) && !ConfigManager.RECORD_ENTITIES) continue; - if (packetData instanceof ChatData && !ConfigManager.RECORD_CHAT) continue; ActionData actionData = new ActionData(currentTick, ActionType.PACKET, name, packetData); diff --git a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java index f85c2281..6765f546 100644 --- a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java +++ b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java @@ -185,8 +185,10 @@ public void onCrit(EntityDamageByEntityEvent e) { @EventHandler (ignoreCancelled = true, priority = EventPriority.MONITOR) public void onChat(AsyncPlayerChatEvent e) { Player p = e.getPlayer(); - if (recorder.getPlayers().contains(p.getName())) { - this.packetRecorder.addData(p.getName(), new ChatData(String.format(e.getFormat(), e.getPlayer().getDisplayName(), e.getMessage()))); + if(ConfigManager.RECORD_CHAT && !ConfigManager.RECORD_EVERYTHING_IN_CHAT) { + if (recorder.getPlayers().contains(p.getName())) { + this.packetRecorder.addData(p.getName(), new ChatData(String.format(e.getFormat(), e.getPlayer().getDisplayName(), e.getMessage()))); + } } } From 255e07366965040bfb13a2aed623c097b410e306 Mon Sep 17 00:00:00 2001 From: Iaiao Date: Mon, 22 Feb 2021 20:38:09 +0200 Subject: [PATCH 03/12] Do not record join/leave/death messages if recording everything --- .../replaysystem/recording/RecordingListener.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java index 6765f546..c44fd50e 100644 --- a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java +++ b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java @@ -222,7 +222,9 @@ public void onQuit(PlayerQuitEvent e) { this.recorder.getPlayers().remove(p.getName()); if (!this.replayLeft.contains(p.getName())) this.replayLeft.add(p.getName()); - this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getQuitMessage()))); + if(!ConfigManager.RECORD_EVERYTHING_IN_CHAT) { + this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getQuitMessage()))); + } } } @@ -233,8 +235,9 @@ public void onJoin(PlayerJoinEvent e) { this.recorder.getPlayers().add(p.getName()); this.recorder.getData().getWatchers().put(p.getName(), new PlayerWatcher(p.getName())); this.recorder.createSpawnAction(p, p.getLocation(), false); - this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getJoinMessage()))); - + if(!ConfigManager.RECORD_EVERYTHING_IN_CHAT) { + this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getJoinMessage()))); + } } } @@ -243,7 +246,9 @@ public void onDeath(PlayerDeathEvent e) { Player p = e.getEntity(); if (this.recorder.getPlayers().contains(p.getName())) { this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(0, ActionType.DEATH, p.getName(), null)); - this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getDeathMessage()))); + if(!ConfigManager.RECORD_EVERYTHING_IN_CHAT) { + this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getDeathMessage()))); + } } } From 8064886c0a3ba31e296226609d8a64acb1605ad5 Mon Sep 17 00:00:00 2001 From: Iaiao Date: Tue, 20 Apr 2021 01:31:49 +0300 Subject: [PATCH 04/12] Combine repeating messages when replaying --- .../replay/filesystem/ConfigManager.java | 6 ++-- .../replaysystem/data/types/ChatData.java | 22 +++++++++++++ .../recording/PacketRecorder.java | 6 ++-- .../recording/RecordingListener.java | 13 ++++---- .../replaysystem/replaying/Replayer.java | 31 +++++++++++++++++++ 5 files changed, 66 insertions(+), 12 deletions(-) diff --git a/src/me/jumper251/replay/filesystem/ConfigManager.java b/src/me/jumper251/replay/filesystem/ConfigManager.java index 7f3d63a6..fade14fa 100644 --- a/src/me/jumper251/replay/filesystem/ConfigManager.java +++ b/src/me/jumper251/replay/filesystem/ConfigManager.java @@ -27,7 +27,7 @@ public class ConfigManager { public static boolean RECORD_BLOCKS, REAL_CHANGES; public static boolean RECORD_ITEMS, RECORD_ENTITIES; - public static boolean RECORD_CHAT, RECORD_EVERYTHING_IN_CHAT; + public static boolean RECORD_CHAT, RECORD_PLUGIN_MESSAGES; public static boolean SAVE_STOP, USE_OFFLINE_SKINS, HIDE_PLAYERS, UPDATE_NOTIFY, USE_DATABASE, ADD_PLAYERS; public static ReplayQuality QUALITY = ReplayQuality.HIGH; @@ -63,7 +63,7 @@ public static void loadConfigs() { cfg.set("recording.entities.enabled", false); cfg.set("recording.entities.items.enabled", true); cfg.set("recording.chat.enabled", false); - cfg.set("recording.chat.everything", false); + cfg.set("recording.chat.plugin_messages", false); try { @@ -95,7 +95,7 @@ public static void loadData(boolean initial) { RECORD_ITEMS = cfg.getBoolean("recording.entities.items.enabled"); RECORD_ENTITIES = cfg.getBoolean("recording.entities.enabled"); RECORD_CHAT = cfg.getBoolean("recording.chat.enabled"); - RECORD_EVERYTHING_IN_CHAT = cfg.getBoolean("recording.chat.everything"); + RECORD_PLUGIN_MESSAGES = cfg.getBoolean("recording.chat.plugin_messages"); if (USE_DATABASE) { diff --git a/src/me/jumper251/replay/replaysystem/data/types/ChatData.java b/src/me/jumper251/replay/replaysystem/data/types/ChatData.java index f1137093..49d08ea4 100644 --- a/src/me/jumper251/replay/replaysystem/data/types/ChatData.java +++ b/src/me/jumper251/replay/replaysystem/data/types/ChatData.java @@ -8,12 +8,34 @@ public class ChatData extends PacketData { */ private static final long serialVersionUID = 6849586468365004854L; + private String recipient; private String message; + /** + * Constructs a ChatData with provided message and an empty recipient. + * + * @param message the message + */ public ChatData(String message) { + this.recipient = ""; this.message = message; } + /** + * Constructs a ChatData with provided message and recipient. + * + * @param recipient the recipient + * @param message the message + */ + public ChatData(String recipient, String message) { + this.recipient = recipient; + this.message = message; + } + + public String getRecipient() { + return recipient; + } + public String getMessage() { return message; } diff --git a/src/me/jumper251/replay/replaysystem/recording/PacketRecorder.java b/src/me/jumper251/replay/replaysystem/recording/PacketRecorder.java index 96cd91fd..cec15534 100644 --- a/src/me/jumper251/replay/replaysystem/recording/PacketRecorder.java +++ b/src/me/jumper251/replay/replaysystem/recording/PacketRecorder.java @@ -309,15 +309,15 @@ public void onPacketSending(PacketEvent event) { } } if(event.getPacketType() == PacketType.Play.Server.CHAT) { - if(ConfigManager.RECORD_CHAT && ConfigManager.RECORD_EVERYTHING_IN_CHAT) { + if(ConfigManager.RECORD_CHAT && ConfigManager.RECORD_PLUGIN_MESSAGES) { WrapperPlayServerChat packet = new WrapperPlayServerChat(event.getPacket()); - String message = Arrays.stream(ComponentSerializer.parse(packet.getMessage().getJson())).reduce(new TextComponent(), (a, b) -> { + String message = Arrays.stream(ComponentSerializer.parse(packet.getMessage().getJson())).reduce(new TextComponent(""), (a, b) -> { a.addExtra(b); return a; }).toLegacyText(); - addData(p.getName(), new ChatData(String.format("[%s received] %s", p.getName(), message))); + addData(p.getName(), new ChatData(p.getName(), message)); } } diff --git a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java index c44fd50e..71879bd3 100644 --- a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java +++ b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java @@ -27,7 +27,6 @@ import org.bukkit.inventory.ItemStack; import me.jumper251.replay.filesystem.ConfigManager; -import me.jumper251.replay.filesystem.MessageBuilder; import me.jumper251.replay.listener.AbstractListener; import me.jumper251.replay.replaysystem.data.ActionData; import me.jumper251.replay.replaysystem.data.ActionType; @@ -185,9 +184,11 @@ public void onCrit(EntityDamageByEntityEvent e) { @EventHandler (ignoreCancelled = true, priority = EventPriority.MONITOR) public void onChat(AsyncPlayerChatEvent e) { Player p = e.getPlayer(); - if(ConfigManager.RECORD_CHAT && !ConfigManager.RECORD_EVERYTHING_IN_CHAT) { + if(ConfigManager.RECORD_CHAT && !ConfigManager.RECORD_PLUGIN_MESSAGES) { if (recorder.getPlayers().contains(p.getName())) { - this.packetRecorder.addData(p.getName(), new ChatData(String.format(e.getFormat(), e.getPlayer().getDisplayName(), e.getMessage()))); + for (Player recipient : e.getRecipients()) { + this.packetRecorder.addData(p.getName(), new ChatData(recipient.getDisplayName(), String.format(e.getFormat(), e.getPlayer().getDisplayName(), e.getMessage()))); + } } } @@ -222,7 +223,7 @@ public void onQuit(PlayerQuitEvent e) { this.recorder.getPlayers().remove(p.getName()); if (!this.replayLeft.contains(p.getName())) this.replayLeft.add(p.getName()); - if(!ConfigManager.RECORD_EVERYTHING_IN_CHAT) { + if(!ConfigManager.RECORD_CHAT || !ConfigManager.RECORD_PLUGIN_MESSAGES) { this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getQuitMessage()))); } } @@ -235,7 +236,7 @@ public void onJoin(PlayerJoinEvent e) { this.recorder.getPlayers().add(p.getName()); this.recorder.getData().getWatchers().put(p.getName(), new PlayerWatcher(p.getName())); this.recorder.createSpawnAction(p, p.getLocation(), false); - if(!ConfigManager.RECORD_EVERYTHING_IN_CHAT) { + if(!ConfigManager.RECORD_CHAT || !ConfigManager.RECORD_PLUGIN_MESSAGES) { this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getJoinMessage()))); } } @@ -246,7 +247,7 @@ public void onDeath(PlayerDeathEvent e) { Player p = e.getEntity(); if (this.recorder.getPlayers().contains(p.getName())) { this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(0, ActionType.DEATH, p.getName(), null)); - if(!ConfigManager.RECORD_EVERYTHING_IN_CHAT) { + if(!ConfigManager.RECORD_CHAT || !ConfigManager.RECORD_PLUGIN_MESSAGES) { this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getDeathMessage()))); } } diff --git a/src/me/jumper251/replay/replaysystem/replaying/Replayer.java b/src/me/jumper251/replay/replaysystem/replaying/Replayer.java index 2921e594..af4870ff 100644 --- a/src/me/jumper251/replay/replaysystem/replaying/Replayer.java +++ b/src/me/jumper251/replay/replaysystem/replaying/Replayer.java @@ -10,12 +10,18 @@ import java.util.List; import java.util.Optional; +import java.util.Set; +import java.util.Map; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; +import com.google.common.collect.Sets; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; import me.jumper251.replay.ReplaySystem; import me.jumper251.replay.api.IReplayHook; @@ -26,6 +32,7 @@ import me.jumper251.replay.replaysystem.data.ReplayData; import me.jumper251.replay.replaysystem.data.types.LocationData; import me.jumper251.replay.replaysystem.data.types.SpawnData; +import me.jumper251.replay.replaysystem.data.types.ChatData; import me.jumper251.replay.replaysystem.utils.entities.IEntity; import me.jumper251.replay.replaysystem.utils.entities.INPC; @@ -131,7 +138,17 @@ public void executeTick(int tick, boolean reversed) { this.started = true; List list = data.getActions().get(tick); + Map> messageRecipients = new HashMap<>(); for (ActionData action : list) { + if(action.getType() == ActionType.PACKET && action.getPacketData() instanceof ChatData) { + ChatData chat = (ChatData) action.getPacketData(); + if(messageRecipients.containsKey(chat.getMessage())) { + messageRecipients.get(chat.getMessage()).add(chat.getRecipient()); + } else { + messageRecipients.put(chat.getMessage(), Sets.newHashSet(chat.getRecipient())); + } + continue; + } utils.handleAction(action, data, reversed); @@ -145,6 +162,20 @@ public void executeTick(int tick, boolean reversed) { } + if(!reversed) { + messageRecipients.forEach((message, recipients) -> { + String hoverText = recipients.stream().allMatch(recipient -> recipient == null || recipient.isEmpty()) + ? "" + : "Received: " + String.join(", ", recipients); + TextComponent component = new TextComponent(ReplaySystem.PREFIX); + for (BaseComponent baseComponent : TextComponent.fromLegacyText(message)) { + component.addExtra(baseComponent); + } + component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[] { new TextComponent(hoverText) })); + this.watcher.spigot().sendMessage(component); + }); + } + if (tick == 0) data.getActions().remove(tick); } } From 08d50af46c6c19c67f5696b1b87653b2a02f4313 Mon Sep 17 00:00:00 2001 From: Iaiao Date: Wed, 21 Apr 2021 00:11:37 +0300 Subject: [PATCH 05/12] Make old replays' messages white --- src/me/jumper251/replay/replaysystem/replaying/Replayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/me/jumper251/replay/replaysystem/replaying/Replayer.java b/src/me/jumper251/replay/replaysystem/replaying/Replayer.java index af4870ff..ca1e6c69 100644 --- a/src/me/jumper251/replay/replaysystem/replaying/Replayer.java +++ b/src/me/jumper251/replay/replaysystem/replaying/Replayer.java @@ -167,7 +167,7 @@ public void executeTick(int tick, boolean reversed) { String hoverText = recipients.stream().allMatch(recipient -> recipient == null || recipient.isEmpty()) ? "" : "Received: " + String.join(", ", recipients); - TextComponent component = new TextComponent(ReplaySystem.PREFIX); + TextComponent component = new TextComponent(ReplaySystem.PREFIX + "§r"); for (BaseComponent baseComponent : TextComponent.fromLegacyText(message)) { component.addExtra(baseComponent); } From 173301e05f922d6b18e69ebb0527b1a2e0fff675 Mon Sep 17 00:00:00 2001 From: Iaiao Date: Wed, 21 Apr 2021 00:13:08 +0300 Subject: [PATCH 06/12] Remove unused ChatData replaying code --- .../replay/replaysystem/replaying/ReplayingUtils.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/me/jumper251/replay/replaysystem/replaying/ReplayingUtils.java b/src/me/jumper251/replay/replaysystem/replaying/ReplayingUtils.java index 9d27976f..f0c52b81 100644 --- a/src/me/jumper251/replay/replaysystem/replaying/ReplayingUtils.java +++ b/src/me/jumper251/replay/replaysystem/replaying/ReplayingUtils.java @@ -87,11 +87,6 @@ public void handleAction(ActionData action, ReplayData data, boolean reversed) { replayer.getNPCList().remove(action.getName()); } - } - - if (action.getType() == ActionType.MESSAGE && !reversed) { - ChatData message = (ChatData) action.getPacketData(); - replayer.sendMessage(message.getMessage()); } if (action.getType() == ActionType.PACKET && this.replayer.getNPCList().containsKey(action.getName())) { From 0d6bb3d51240398a187d5c58183c77157c062a5c Mon Sep 17 00:00:00 2001 From: Iaiao Date: Wed, 21 Apr 2021 00:21:12 +0300 Subject: [PATCH 07/12] Record which players received join/leave/death message --- .../replaysystem/recording/RecordingListener.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java index 71879bd3..18e33b56 100644 --- a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java +++ b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java @@ -8,6 +8,7 @@ import me.jumper251.replay.replaysystem.data.types.*; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.LivingEntity; @@ -224,7 +225,9 @@ public void onQuit(PlayerQuitEvent e) { if (!this.replayLeft.contains(p.getName())) this.replayLeft.add(p.getName()); if(!ConfigManager.RECORD_CHAT || !ConfigManager.RECORD_PLUGIN_MESSAGES) { - this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getQuitMessage()))); + for (Player player : Bukkit.getOnlinePlayers()) { + this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(player.getName(), e.getQuitMessage()))); + } } } } @@ -237,7 +240,9 @@ public void onJoin(PlayerJoinEvent e) { this.recorder.getData().getWatchers().put(p.getName(), new PlayerWatcher(p.getName())); this.recorder.createSpawnAction(p, p.getLocation(), false); if(!ConfigManager.RECORD_CHAT || !ConfigManager.RECORD_PLUGIN_MESSAGES) { - this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getJoinMessage()))); + for (Player player : Bukkit.getOnlinePlayers()) { + this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(player.getName(), e.getJoinMessage()))); + } } } } @@ -248,8 +253,9 @@ public void onDeath(PlayerDeathEvent e) { if (this.recorder.getPlayers().contains(p.getName())) { this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(0, ActionType.DEATH, p.getName(), null)); if(!ConfigManager.RECORD_CHAT || !ConfigManager.RECORD_PLUGIN_MESSAGES) { - this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(e.getDeathMessage()))); - } + for (Player player : Bukkit.getOnlinePlayers()) { + this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(player.getName(), e.getDeathMessage()))); + } } } } From fe05d433d2d98e75d80a87c80e8088e78558c4e3 Mon Sep 17 00:00:00 2001 From: Iaiao Date: Mon, 3 May 2021 21:51:54 +0300 Subject: [PATCH 08/12] Get rid of message duplication so it compresses messages at recording time --- .../replay/replaysystem/data/ReplayData.java | 10 ++- .../replaysystem/data/types/ChatData.java | 17 +++-- .../recording/PacketRecorder.java | 9 +-- .../replaysystem/recording/Recorder.java | 14 ++++ .../recording/RecordingListener.java | 65 ++++++++++++++----- .../replaysystem/replaying/Replayer.java | 55 ++++++++-------- 6 files changed, 114 insertions(+), 56 deletions(-) diff --git a/src/me/jumper251/replay/replaysystem/data/ReplayData.java b/src/me/jumper251/replay/replaysystem/data/ReplayData.java index 066f99af..2a1e81ac 100644 --- a/src/me/jumper251/replay/replaysystem/data/ReplayData.java +++ b/src/me/jumper251/replay/replaysystem/data/ReplayData.java @@ -5,6 +5,7 @@ import java.util.List; import me.jumper251.replay.filesystem.ConfigManager; +import me.jumper251.replay.replaysystem.data.types.ChatData; import me.jumper251.replay.replaysystem.recording.PlayerWatcher; import me.jumper251.replay.replaysystem.recording.optimization.ReplayQuality; @@ -18,6 +19,8 @@ public class ReplayData implements Serializable{ private HashMap> actions; + + private HashMap> messages; private HashMap watchers; @@ -29,6 +32,7 @@ public class ReplayData implements Serializable{ public ReplayData() { this.actions = new HashMap>(); + this.messages = new HashMap>(); this.watchers = new HashMap(); this.quality = ConfigManager.QUALITY; @@ -57,7 +61,11 @@ public ReplayQuality getQuality() { public HashMap> getActions() { return actions; } - + + public HashMap> getMessages() { + return messages; + } + public HashMap getWatchers() { return watchers; } diff --git a/src/me/jumper251/replay/replaysystem/data/types/ChatData.java b/src/me/jumper251/replay/replaysystem/data/types/ChatData.java index 49d08ea4..f3578093 100644 --- a/src/me/jumper251/replay/replaysystem/data/types/ChatData.java +++ b/src/me/jumper251/replay/replaysystem/data/types/ChatData.java @@ -1,5 +1,8 @@ package me.jumper251.replay.replaysystem.data.types; +import java.util.HashSet; +import java.util.Set; + public class ChatData extends PacketData { @@ -8,7 +11,7 @@ public class ChatData extends PacketData { */ private static final long serialVersionUID = 6849586468365004854L; - private String recipient; + private Set recipients; private String message; /** @@ -17,23 +20,23 @@ public class ChatData extends PacketData { * @param message the message */ public ChatData(String message) { - this.recipient = ""; + this.recipients = new HashSet<>(); this.message = message; } /** * Constructs a ChatData with provided message and recipient. * - * @param recipient the recipient + * @param recipients the recipient * @param message the message */ - public ChatData(String recipient, String message) { - this.recipient = recipient; + public ChatData(Set recipients, String message) { + this.recipients = recipients; this.message = message; } - public String getRecipient() { - return recipient; + public Set getRecipients() { + return recipients; } public String getMessage() { diff --git a/src/me/jumper251/replay/replaysystem/recording/PacketRecorder.java b/src/me/jumper251/replay/replaysystem/recording/PacketRecorder.java index 145f3f50..dc43afae 100644 --- a/src/me/jumper251/replay/replaysystem/recording/PacketRecorder.java +++ b/src/me/jumper251/replay/replaysystem/recording/PacketRecorder.java @@ -13,7 +13,6 @@ import java.util.HashMap; import java.util.List; -import java.util.Arrays; import org.bukkit.Location; import org.bukkit.entity.Entity; @@ -63,7 +62,6 @@ import me.jumper251.replay.replaysystem.utils.NPCManager; import me.jumper251.replay.utils.VersionUtil; import me.jumper251.replay.utils.VersionUtil.VersionEnum; -import me.jumper251.replay.replaysystem.data.types.ChatData; @@ -316,11 +314,8 @@ public void onPacketSending(PacketEvent event) { WrapperPlayServerChat packet = new WrapperPlayServerChat(event.getPacket()); - String message = Arrays.stream(ComponentSerializer.parse(packet.getMessage().getJson())).reduce(new TextComponent(""), (a, b) -> { - a.addExtra(b); - return a; - }).toLegacyText(); - addData(p.getName(), new ChatData(p.getName(), message)); + String message = new TextComponent(ComponentSerializer.parse(packet.getMessage().getJson())).toLegacyText(); + recorder.recordChat(p.getName(), message); } } diff --git a/src/me/jumper251/replay/replaysystem/recording/Recorder.java b/src/me/jumper251/replay/replaysystem/recording/Recorder.java index b3c5bba1..8c817823 100644 --- a/src/me/jumper251/replay/replaysystem/recording/Recorder.java +++ b/src/me/jumper251/replay/replaysystem/recording/Recorder.java @@ -6,7 +6,9 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; +import com.google.common.collect.Sets; import me.jumper251.replay.replaysystem.data.types.*; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -203,6 +205,18 @@ public void run() { } } + public void recordChat(String player, String message) { + if(!data.getMessages().containsKey(currentTick)) { + data.getMessages().put(currentTick, new ArrayList<>()); + } + Optional chatData = data.getMessages().get(currentTick).stream().filter(c -> c.getMessage().equals(message)).findAny(); + if(chatData.isPresent()) { + chatData.get().getRecipients().add(player); + } else { + data.getMessages().get(currentTick).add(new ChatData(Sets.newHashSet(player), message)); + } + } + public List getPlayers() { return players; } diff --git a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java index 34b077f3..cf905733 100644 --- a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java +++ b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import me.jumper251.replay.replaysystem.data.types.*; @@ -193,9 +194,18 @@ public void onChat(AsyncPlayerChatEvent e) { Player p = e.getPlayer(); if(ConfigManager.RECORD_CHAT && !ConfigManager.RECORD_PLUGIN_MESSAGES) { if (recorder.getPlayers().contains(p.getName())) { - for (Player recipient : e.getRecipients()) { - this.packetRecorder.addData(p.getName(), new ChatData(recipient.getDisplayName(), String.format(e.getFormat(), e.getPlayer().getDisplayName(), e.getMessage()))); - } + this.recorder.addData( + this.recorder.getCurrentTick(), + new ActionData( + this.recorder.getCurrentTick(), + ActionType.MESSAGE, + p.getName(), + new ChatData( + e.getRecipients() + .stream() + .map(Player::getName) + .collect(Collectors.toSet()), + String.format(e.getFormat(), e.getPlayer().getDisplayName(), e.getMessage())))); } } @@ -230,10 +240,18 @@ public void onQuit(PlayerQuitEvent e) { this.recorder.getPlayers().remove(p.getName()); if (!this.replayLeft.contains(p.getName())) this.replayLeft.add(p.getName()); - if(!ConfigManager.RECORD_CHAT || !ConfigManager.RECORD_PLUGIN_MESSAGES) { - for (Player player : Bukkit.getOnlinePlayers()) { - this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(player.getName(), e.getQuitMessage()))); - } + if(ConfigManager.RECORD_CHAT && (!ConfigManager.RECORD_PLUGIN_MESSAGES || Bukkit.getOnlinePlayers().size() == 1)) { + this.recorder.addData( + this.recorder.getCurrentTick(), + new ActionData( + this.recorder.getCurrentTick(), + ActionType.MESSAGE, + p.getName(), + new ChatData( + Bukkit.getOnlinePlayers() + .stream() + .map(Player::getName) + .collect(Collectors.toSet()), e.getQuitMessage()))); } } } @@ -245,10 +263,18 @@ public void onJoin(PlayerJoinEvent e) { this.recorder.getPlayers().add(p.getName()); this.recorder.getData().getWatchers().put(p.getName(), new PlayerWatcher(p.getName())); this.recorder.createSpawnAction(p, p.getLocation(), false); - if(!ConfigManager.RECORD_CHAT || !ConfigManager.RECORD_PLUGIN_MESSAGES) { - for (Player player : Bukkit.getOnlinePlayers()) { - this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(player.getName(), e.getJoinMessage()))); - } + if(ConfigManager.RECORD_CHAT && !ConfigManager.RECORD_PLUGIN_MESSAGES) { + this.recorder.addData( + this.recorder.getCurrentTick(), + new ActionData( + this.recorder.getCurrentTick(), + ActionType.MESSAGE, + p.getName(), + new ChatData( + Bukkit.getOnlinePlayers() + .stream() + .map(Player::getName) + .collect(Collectors.toSet()), e.getJoinMessage()))); } } } @@ -258,10 +284,19 @@ public void onDeath(PlayerDeathEvent e) { Player p = e.getEntity(); if (this.recorder.getPlayers().contains(p.getName())) { this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(0, ActionType.DEATH, p.getName(), null)); - if(!ConfigManager.RECORD_CHAT || !ConfigManager.RECORD_PLUGIN_MESSAGES) { - for (Player player : Bukkit.getOnlinePlayers()) { - this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(this.recorder.getCurrentTick(), ActionType.MESSAGE, p.getName(), new ChatData(player.getName(), e.getDeathMessage()))); - } } + if(ConfigManager.RECORD_CHAT && !ConfigManager.RECORD_PLUGIN_MESSAGES) { + this.recorder.addData( + this.recorder.getCurrentTick(), + new ActionData( + this.recorder.getCurrentTick(), + ActionType.MESSAGE, + p.getName(), + new ChatData( + Bukkit.getOnlinePlayers() + .stream() + .map(Player::getName) + .collect(Collectors.toSet()), e.getDeathMessage()))); + } } } diff --git a/src/me/jumper251/replay/replaysystem/replaying/Replayer.java b/src/me/jumper251/replay/replaysystem/replaying/Replayer.java index 044f28ee..a4e687c9 100644 --- a/src/me/jumper251/replay/replaysystem/replaying/Replayer.java +++ b/src/me/jumper251/replay/replaysystem/replaying/Replayer.java @@ -13,8 +13,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.Set; -import java.util.Map; +import java.util.Collections; import org.bukkit.Location; import org.bukkit.entity.Entity; @@ -22,7 +21,6 @@ import org.bukkit.scheduler.BukkitRunnable; -import com.google.common.collect.Sets; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; @@ -147,20 +145,17 @@ public void executeTick(int tick, boolean reversed) { this.started = true; List list = data.getActions().get(tick); - Map> messageRecipients = new HashMap<>(); for (ActionData action : list) { - if(action.getType() == ActionType.PACKET && action.getPacketData() instanceof ChatData) { - ChatData chat = (ChatData) action.getPacketData(); - if(messageRecipients.containsKey(chat.getMessage())) { - messageRecipients.get(chat.getMessage()).add(chat.getRecipient()); - } else { - messageRecipients.put(chat.getMessage(), Sets.newHashSet(chat.getRecipient())); + if ((action.getType() == ActionType.PACKET || action.getType() == ActionType.MESSAGE) && action.getPacketData() instanceof ChatData) { + if (!reversed) { + ChatData chatData = (ChatData) action.getPacketData(); + sendMessage(chatData); } continue; } - + utils.handleAction(action, data, reversed); - + if (action.getType() == ActionType.CUSTOM) { if (ReplayAPI.getInstance().getHookManager().isRegistered()) { for (IReplayHook hook : ReplayAPI.getInstance().getHookManager().getHooks()) { @@ -171,22 +166,17 @@ public void executeTick(int tick, boolean reversed) { } - if(!reversed) { - messageRecipients.forEach((message, recipients) -> { - String hoverText = recipients.stream().allMatch(recipient -> recipient == null || recipient.isEmpty()) - ? "" - : "Received: " + String.join(", ", recipients); - TextComponent component = new TextComponent(ReplaySystem.PREFIX + "§r"); - for (BaseComponent baseComponent : TextComponent.fromLegacyText(message)) { - component.addExtra(baseComponent); - } - component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[] { new TextComponent(hoverText) })); - this.watcher.spigot().sendMessage(component); - }); - } - if (tick == 0) data.getActions().remove(tick); } + + // Don't display messages about the start of recording + if(tick != 0) { + for (ChatData chatData : data.getMessages().getOrDefault(tick, Collections.emptyList())) { + if (!reversed) { + sendMessage(chatData); + } + } + } } private void updateXPBar() { @@ -291,4 +281,17 @@ public void sendMessage(String message) { this.watcher.sendMessage(ReplaySystem.PREFIX + message); } } + + public void sendMessage(ChatData chatData) { + String hoverText = (chatData.getRecipients() == null + || chatData.getRecipients().stream().allMatch(recipient -> recipient == null || recipient.isEmpty())) + ? "" + : "Received: " + String.join(", ", chatData.getRecipients()); + TextComponent component = new TextComponent(ReplaySystem.PREFIX + "§r"); + for (BaseComponent baseComponent : TextComponent.fromLegacyText(chatData.getMessage())) { + component.addExtra(baseComponent); + } + component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[] { new TextComponent(hoverText) })); + this.watcher.spigot().sendMessage(component); + } } From bd75d38e70c4114b9bdf335064b84f937227e694 Mon Sep 17 00:00:00 2001 From: Iaiao Date: Sun, 9 May 2021 03:50:40 +0300 Subject: [PATCH 09/12] Restore WORLD_RESET in ConfigManager --- src/me/jumper251/replay/filesystem/ConfigManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/me/jumper251/replay/filesystem/ConfigManager.java b/src/me/jumper251/replay/filesystem/ConfigManager.java index 373ae844..1e59fd34 100644 --- a/src/me/jumper251/replay/filesystem/ConfigManager.java +++ b/src/me/jumper251/replay/filesystem/ConfigManager.java @@ -92,6 +92,7 @@ public static void loadData(boolean initial) { ADD_PLAYERS = cfg.getBoolean("general.add_new_players"); UPDATE_NOTIFY = cfg.getBoolean("general.update_notifications"); if (initial ) USE_DATABASE = cfg.getBoolean("general.use_mysql"); + WORLD_RESET = cfg.getBoolean("replaying.world.reset_changes", false); RECORD_BLOCKS = cfg.getBoolean("recording.blocks.enabled"); REAL_CHANGES = cfg.getBoolean("recording.blocks.real_changes"); RECORD_ITEMS = cfg.getBoolean("recording.entities.items.enabled"); From 06d429d68d88587a869c6f7f332187e4a926b019 Mon Sep 17 00:00:00 2001 From: Iaiao Date: Sun, 9 May 2021 04:34:14 +0300 Subject: [PATCH 10/12] Record messages in event listeners to messages --- .../recording/RecordingListener.java | 57 ++++--------------- 1 file changed, 12 insertions(+), 45 deletions(-) diff --git a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java index cf905733..9a10ee3e 100644 --- a/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java +++ b/src/me/jumper251/replay/replaysystem/recording/RecordingListener.java @@ -194,18 +194,9 @@ public void onChat(AsyncPlayerChatEvent e) { Player p = e.getPlayer(); if(ConfigManager.RECORD_CHAT && !ConfigManager.RECORD_PLUGIN_MESSAGES) { if (recorder.getPlayers().contains(p.getName())) { - this.recorder.addData( - this.recorder.getCurrentTick(), - new ActionData( - this.recorder.getCurrentTick(), - ActionType.MESSAGE, - p.getName(), - new ChatData( - e.getRecipients() - .stream() - .map(Player::getName) - .collect(Collectors.toSet()), - String.format(e.getFormat(), e.getPlayer().getDisplayName(), e.getMessage())))); + for(Player player : Bukkit.getOnlinePlayers()) { + this.recorder.recordChat(player.getName(), String.format(e.getFormat(), e.getPlayer().getDisplayName(), e.getMessage())); + } } } @@ -241,17 +232,9 @@ public void onQuit(PlayerQuitEvent e) { if (!this.replayLeft.contains(p.getName())) this.replayLeft.add(p.getName()); if(ConfigManager.RECORD_CHAT && (!ConfigManager.RECORD_PLUGIN_MESSAGES || Bukkit.getOnlinePlayers().size() == 1)) { - this.recorder.addData( - this.recorder.getCurrentTick(), - new ActionData( - this.recorder.getCurrentTick(), - ActionType.MESSAGE, - p.getName(), - new ChatData( - Bukkit.getOnlinePlayers() - .stream() - .map(Player::getName) - .collect(Collectors.toSet()), e.getQuitMessage()))); + for(Player player : Bukkit.getOnlinePlayers()) { + this.recorder.recordChat(player.getName(), e.getQuitMessage()); + } } } } @@ -264,17 +247,9 @@ public void onJoin(PlayerJoinEvent e) { this.recorder.getData().getWatchers().put(p.getName(), new PlayerWatcher(p.getName())); this.recorder.createSpawnAction(p, p.getLocation(), false); if(ConfigManager.RECORD_CHAT && !ConfigManager.RECORD_PLUGIN_MESSAGES) { - this.recorder.addData( - this.recorder.getCurrentTick(), - new ActionData( - this.recorder.getCurrentTick(), - ActionType.MESSAGE, - p.getName(), - new ChatData( - Bukkit.getOnlinePlayers() - .stream() - .map(Player::getName) - .collect(Collectors.toSet()), e.getJoinMessage()))); + for(Player player : Bukkit.getOnlinePlayers()) { + this.recorder.recordChat(player.getName(), e.getJoinMessage()); + } } } } @@ -285,17 +260,9 @@ public void onDeath(PlayerDeathEvent e) { if (this.recorder.getPlayers().contains(p.getName())) { this.recorder.addData(this.recorder.getCurrentTick(), new ActionData(0, ActionType.DEATH, p.getName(), null)); if(ConfigManager.RECORD_CHAT && !ConfigManager.RECORD_PLUGIN_MESSAGES) { - this.recorder.addData( - this.recorder.getCurrentTick(), - new ActionData( - this.recorder.getCurrentTick(), - ActionType.MESSAGE, - p.getName(), - new ChatData( - Bukkit.getOnlinePlayers() - .stream() - .map(Player::getName) - .collect(Collectors.toSet()), e.getDeathMessage()))); + for(Player player : Bukkit.getOnlinePlayers()) { + this.recorder.recordChat(player.getName(), e.getDeathMessage()); + } } } } From 649605f3a39fcb711da7ee10902cf2bc52a4e643 Mon Sep 17 00:00:00 2001 From: Iaiao Date: Sun, 9 May 2021 15:26:09 +0300 Subject: [PATCH 11/12] Remove messages with ActionType.PACKET as they are recorded in ReplayData#getMessages() --- src/me/jumper251/replay/replaysystem/replaying/Replayer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/me/jumper251/replay/replaysystem/replaying/Replayer.java b/src/me/jumper251/replay/replaysystem/replaying/Replayer.java index a4e687c9..8f2a448a 100644 --- a/src/me/jumper251/replay/replaysystem/replaying/Replayer.java +++ b/src/me/jumper251/replay/replaysystem/replaying/Replayer.java @@ -146,7 +146,8 @@ public void executeTick(int tick, boolean reversed) { List list = data.getActions().get(tick); for (ActionData action : list) { - if ((action.getType() == ActionType.PACKET || action.getType() == ActionType.MESSAGE) && action.getPacketData() instanceof ChatData) { + // Support older replays + if (action.getType() == ActionType.MESSAGE && action.getPacketData() instanceof ChatData) { if (!reversed) { ChatData chatData = (ChatData) action.getPacketData(); sendMessage(chatData); From 19da463b778e2f2f65d1aa738b9d12f4a5971eaa Mon Sep 17 00:00:00 2001 From: Iaiao Date: Sun, 9 May 2021 15:27:13 +0300 Subject: [PATCH 12/12] Fix NPE when replaying replays saved in older versions --- src/me/jumper251/replay/replaysystem/replaying/Replayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/me/jumper251/replay/replaysystem/replaying/Replayer.java b/src/me/jumper251/replay/replaysystem/replaying/Replayer.java index 8f2a448a..6d8d4703 100644 --- a/src/me/jumper251/replay/replaysystem/replaying/Replayer.java +++ b/src/me/jumper251/replay/replaysystem/replaying/Replayer.java @@ -171,7 +171,7 @@ public void executeTick(int tick, boolean reversed) { } // Don't display messages about the start of recording - if(tick != 0) { + if(tick != 0 && data.getMessages() != null) { for (ChatData chatData : data.getMessages().getOrDefault(tick, Collections.emptyList())) { if (!reversed) { sendMessage(chatData);