From b1a8721c1341f32225ca8ba71acb9731c979d406 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Tue, 21 Jun 2022 22:16:16 +0200 Subject: [PATCH 1/7] Add cache invalidation --- SpigotCore_Main/src/de/steamwar/core/Core.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SpigotCore_Main/src/de/steamwar/core/Core.java b/SpigotCore_Main/src/de/steamwar/core/Core.java index d52f779..d759b3d 100644 --- a/SpigotCore_Main/src/de/steamwar/core/Core.java +++ b/SpigotCore_Main/src/de/steamwar/core/Core.java @@ -22,6 +22,7 @@ package de.steamwar.core; import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.command.SWCommandUtils; import de.steamwar.command.SWTypeMapperCreator; +import de.steamwar.command.TabCompletionCache; import de.steamwar.command.TypeMapper; import de.steamwar.core.authlib.AuthlibInjector; import de.steamwar.core.events.ChattingEvent; @@ -111,6 +112,7 @@ public class Core extends JavaPlugin{ return tabCompleter.apply(sender, s); } }); + Bukkit.getScheduler().runTaskTimer(this, TabCompletionCache::invalidateOldEntries, 20, 20); setSqlConfig(); errorHandler = new ErrorHandler(); From aed99fec0eb0d0620815ac0f35a7e754835aaa27 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Tue, 21 Jun 2022 22:17:26 +0200 Subject: [PATCH 2/7] Update CommonCore --- CommonCore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CommonCore b/CommonCore index 6879d3c..21e77c5 160000 --- a/CommonCore +++ b/CommonCore @@ -1 +1 @@ -Subproject commit 6879d3cc2a08c19ca62aae32fbeb3c1e1813cea4 +Subproject commit 21e77c55f023261d3a63d5c6200d28b2f6f6fc4c From a5748f6a1bde8f7a372e38d8f3b963063bb3c610 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Wed, 22 Jun 2022 18:05:34 +0200 Subject: [PATCH 3/7] Reduce error spam --- SpigotCore_Main/src/de/steamwar/core/ErrorHandler.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SpigotCore_Main/src/de/steamwar/core/ErrorHandler.java b/SpigotCore_Main/src/de/steamwar/core/ErrorHandler.java index 94fe313..7486d40 100644 --- a/SpigotCore_Main/src/de/steamwar/core/ErrorHandler.java +++ b/SpigotCore_Main/src/de/steamwar/core/ErrorHandler.java @@ -144,6 +144,8 @@ public class ErrorHandler extends Handler { startsWith.add("This version of Minecraft is extremely outdated"); startsWith.add("Custom worlds heights are NOT SUPPORTED for 1.16 players and older"); startsWith.add("You have min/max set to -64/384"); + startsWith.add("You have min/max set to -64/256"); + startsWith.add("Biome with id"); ignoreStartsWith = Collections.unmodifiableList(startsWith); List contains = new ArrayList<>(); From 2583c2835d26e37ebec59a70cea712947ac6d033 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Thu, 23 Jun 2022 09:49:28 +0200 Subject: [PATCH 4/7] New TinyProtocol filter handling, partial fix for 1.17> ViaVersion sign translation --- SpigotCore_Main/build.gradle | 1 + .../comphenix/tinyprotocol/TinyProtocol.java | 34 ++++++++++- .../src/de/steamwar/core/Core.java | 5 ++ .../steamwar/core/events/ChunkListener.java | 33 ----------- .../core/events/PartialChunkFixer.java | 56 +++++++++++++++++++ SpigotCore_Main/src/plugin.yml | 1 + build.gradle | 4 ++ 7 files changed, 99 insertions(+), 35 deletions(-) delete mode 100644 SpigotCore_Main/src/de/steamwar/core/events/ChunkListener.java create mode 100644 SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java diff --git a/SpigotCore_Main/build.gradle b/SpigotCore_Main/build.gradle index fe306ca..4122646 100644 --- a/SpigotCore_Main/build.gradle +++ b/SpigotCore_Main/build.gradle @@ -47,6 +47,7 @@ dependencies { compileOnly 'io.netty:netty-all:4.1.68.Final' compileOnly 'com.mojang:authlib:1.5.25' compileOnly 'mysql:mysql-connector-java:5.1.49' + compileOnly 'com.viaversion:viaversion-api:4.3.1' compileOnly files("${project.rootDir}/lib/WorldEdit-1.12.jar") implementation 'net.wesjd:anvilgui:1.5.3-SNAPSHOT' diff --git a/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java b/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java index 6951a9a..82a4afb 100644 --- a/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java +++ b/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java @@ -20,6 +20,7 @@ import org.bukkit.scheduler.BukkitRunnable; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiFunction; import java.util.logging.Level; /** @@ -71,7 +72,12 @@ public class TinyProtocol { private volatile boolean closed; private final Plugin plugin; + private final Map, List>> packetFilters = new HashMap<>(); + + @Deprecated private PacketFilter inFilter = (player, channel, packet) -> packet; + + @Deprecated private PacketFilter outFilter = (player, channel, packet) -> packet; public static final TinyProtocol instance = new TinyProtocol(Core.getInstance()); @@ -245,18 +251,41 @@ public class TinyProtocol { } } + public void addFilter(Class packetType, BiFunction filter) { + packetFilters.computeIfAbsent(packetType, c -> new ArrayList<>(1)).add(filter); + } + + public void removeFilter(Class packetType, BiFunction filter) { + packetFilters.getOrDefault(packetType, Collections.emptyList()).remove(filter); + } + public Object onPacketOutAsync(Player receiver, Channel channel, Object packet) { - return outFilter.onPacket(receiver, channel, packet); + return filterPacket(outFilter, receiver, channel, packet); } public Object onPacketInAsync(Player sender, Channel channel, Object packet) { - return inFilter.onPacket(sender, channel, packet); + return filterPacket(inFilter, sender, channel, packet); } + private Object filterPacket(PacketFilter handler, Player player, Channel channel, Object packet) { + List> filters = packetFilters.getOrDefault(packet.getClass(), Collections.emptyList()); + + for(BiFunction filter : filters) { + packet = filter.apply(player, packet); + + if(packet == null) + return packet; + } + + return handler.onPacket(player, channel, packet); + } + + @Deprecated public void setInFilter(PacketFilter filter) { inFilter = filter; } + @Deprecated public void setOutFilter(PacketFilter filter) { outFilter = filter; } @@ -363,6 +392,7 @@ public class TinyProtocol { } } + @Deprecated public interface PacketFilter { Object onPacket(Player player, Channel channel, Object packet); } diff --git a/SpigotCore_Main/src/de/steamwar/core/Core.java b/SpigotCore_Main/src/de/steamwar/core/Core.java index d759b3d..ab7da7a 100644 --- a/SpigotCore_Main/src/de/steamwar/core/Core.java +++ b/SpigotCore_Main/src/de/steamwar/core/Core.java @@ -26,6 +26,7 @@ import de.steamwar.command.TabCompletionCache; import de.steamwar.command.TypeMapper; import de.steamwar.core.authlib.AuthlibInjector; import de.steamwar.core.events.ChattingEvent; +import de.steamwar.core.events.PartialChunkFixer; import de.steamwar.core.events.PlayerJoinedEvent; import de.steamwar.core.events.WorldLoadEvent; import de.steamwar.message.Message; @@ -127,6 +128,10 @@ public class Core extends JavaPlugin{ if(Core.getVersion() < 19) AuthlibInjector.inject(); TinyProtocol.init(); + + if(Core.getVersion() < 17 && Bukkit.getPluginManager().getPlugin("ViaVersion") != null) + new PartialChunkFixer(); + try { getLogger().log(Level.INFO, "Running on: " + new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec("hostname").getInputStream())).readLine()); } catch (IOException e) { diff --git a/SpigotCore_Main/src/de/steamwar/core/events/ChunkListener.java b/SpigotCore_Main/src/de/steamwar/core/events/ChunkListener.java deleted file mode 100644 index 9e51366..0000000 --- a/SpigotCore_Main/src/de/steamwar/core/events/ChunkListener.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - 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.core.events; - -import de.steamwar.core.CraftbukkitWrapper; -import org.bukkit.entity.Player; - -@Deprecated -public class ChunkListener { - private ChunkListener(){} - - @Deprecated - public static void sendChunk(Player p, int chunkX, int chunkZ) { - CraftbukkitWrapper.impl.sendChunk(p, chunkX, chunkZ); - } -} diff --git a/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java b/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java new file mode 100644 index 0000000..07a879d --- /dev/null +++ b/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java @@ -0,0 +1,56 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.core.events; + +import com.comphenix.tinyprotocol.Reflection; +import com.comphenix.tinyprotocol.TinyProtocol; +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.ViaAPI; +import de.steamwar.core.CraftbukkitWrapper; +import org.bukkit.entity.Player; + +/** + * TinyProtocol can't translate BlockEntities during 1.16 to 1.17 conversions du to removed partial chunk update support. This class cancels PartialChunkUpdates for this players and sends them a complete chunk instead. + * This class can only be loaded on 1.9 to 1.15 with active ViaVersion. + **/ +public class PartialChunkFixer { + + private static final int PROTOCOL1_17 = 755; + private static final Class mapChunk = Reflection.getClass("{nms}.PacketPlayOutMapChunk"); + private static final Reflection.FieldAccessor fullChunkFlag = Reflection.getField(mapChunk, boolean.class, 0); + private static final Reflection.FieldAccessor chunkX = Reflection.getField(mapChunk, int.class, 0); + private static final Reflection.FieldAccessor chunkZ = Reflection.getField(mapChunk, int.class, 1); + + private final ViaAPI via = Via.getAPI(); + + public PartialChunkFixer() { + TinyProtocol.instance.addFilter(mapChunk, this::chunkFilter); + } + + private Object chunkFilter(Player player, Object packet) { + if(via.getPlayerVersion(player) >= PROTOCOL1_17 && !fullChunkFlag.get(packet)) { + // partial chunk update + System.out.println("Partial chunk at " + chunkX.get(packet) + " " + chunkZ.get(packet)); + CraftbukkitWrapper.impl.sendChunk(player, chunkX.get(packet), chunkZ.get(packet)); + return null; + } + return packet; + } +} diff --git a/SpigotCore_Main/src/plugin.yml b/SpigotCore_Main/src/plugin.yml index a29249d..7565266 100644 --- a/SpigotCore_Main/src/plugin.yml +++ b/SpigotCore_Main/src/plugin.yml @@ -4,6 +4,7 @@ author: Lixfel api-version: "1.13" load: STARTUP softdepend: + - ViaVersion - WorldEdit main: de.steamwar.core.Core diff --git a/build.gradle b/build.gradle index 11b9180..fba0534 100644 --- a/build.gradle +++ b/build.gradle @@ -81,6 +81,10 @@ allprojects { maven { url = uri('https://libraries.minecraft.net') } + + maven { + url = uri('https://repo.viaversion.com') + } } } From 5e6e1eeada613b33d2de6f0e98d6b940e1afc231 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Thu, 23 Jun 2022 09:52:39 +0200 Subject: [PATCH 5/7] Remove debug message --- .../src/de/steamwar/core/events/PartialChunkFixer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java b/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java index 07a879d..cd34c99 100644 --- a/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java +++ b/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java @@ -47,7 +47,6 @@ public class PartialChunkFixer { private Object chunkFilter(Player player, Object packet) { if(via.getPlayerVersion(player) >= PROTOCOL1_17 && !fullChunkFlag.get(packet)) { // partial chunk update - System.out.println("Partial chunk at " + chunkX.get(packet) + " " + chunkZ.get(packet)); CraftbukkitWrapper.impl.sendChunk(player, chunkX.get(packet), chunkZ.get(packet)); return null; } From 6d0d3e143726a96b2d080b1d375622e867757593 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Thu, 23 Jun 2022 17:01:24 +0200 Subject: [PATCH 6/7] Fix packet receiver --- .../steamwar/network/handlers/InventoryHandler.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SpigotCore_Main/src/de/steamwar/network/handlers/InventoryHandler.java b/SpigotCore_Main/src/de/steamwar/network/handlers/InventoryHandler.java index 0f3ee52..a8a378a 100644 --- a/SpigotCore_Main/src/de/steamwar/network/handlers/InventoryHandler.java +++ b/SpigotCore_Main/src/de/steamwar/network/handlers/InventoryHandler.java @@ -28,28 +28,28 @@ import de.steamwar.network.packets.client.InventoryCallbackPacket; import de.steamwar.network.packets.server.InventoryPacket; import de.steamwar.sql.SteamwarUser; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryType; import java.util.HashMap; import java.util.Map; -import java.util.UUID; public class InventoryHandler extends PacketHandler { @Handler public static void handleInventoryPacket(InventoryPacket packet) { + Player player = Bukkit.getPlayer(SteamwarUser.get(packet.getPlayer()).getUUID()); Map items = new HashMap<>(); packet.getItems().forEach((i, item) -> { @SuppressWarnings("deprecation") SWItem it = SWItem.getItemFromJson(new JsonParser().parse(item).getAsJsonObject()); - it.setCallback(click -> NetworkSender.send(InventoryCallbackPacket.builder().owner(packet.getPlayer()).position(i).type(InventoryCallbackPacket.CallbackType.CLICK).clickType(InventoryCallbackPacket.ClickType.getByName(click.name())).build())); + it.setCallback(click -> NetworkSender.send(InventoryCallbackPacket.builder().owner(packet.getPlayer()).position(i).type(InventoryCallbackPacket.CallbackType.CLICK).clickType(InventoryCallbackPacket.ClickType.getByName(click.name())).build(), player)); items.put(i, it); }); - UUID player = SteamwarUser.get(packet.getPlayer()).getUUID(); - SWInventory inventory = new SWInventory(Bukkit.getPlayer(player), packet.getSize(), packet.getTitle(), items); + SWInventory inventory = new SWInventory(player, packet.getSize(), packet.getTitle(), items); inventory.addCloseCallback(click -> { - if(Bukkit.getPlayer(player).getOpenInventory().getType() != InventoryType.CHEST) - NetworkSender.send(InventoryCallbackPacket.builder().owner(packet.getPlayer()).type(InventoryCallbackPacket.CallbackType.CLOSE).build()); + if(player.getOpenInventory().getType() != InventoryType.CHEST) + NetworkSender.send(InventoryCallbackPacket.builder().owner(packet.getPlayer()).type(InventoryCallbackPacket.CallbackType.CLOSE).build(), player); }); inventory.open(); } From a46fbbbedb967736b1a1a8b7d797c418849df708 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Thu, 23 Jun 2022 22:08:58 +0200 Subject: [PATCH 7/7] Fix chunk fixer --- .../core/events/PartialChunkFixer.java | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java b/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java index cd34c99..6efab3c 100644 --- a/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java +++ b/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java @@ -23,9 +23,14 @@ import com.comphenix.tinyprotocol.Reflection; import com.comphenix.tinyprotocol.TinyProtocol; import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.ViaAPI; +import de.steamwar.core.Core; import de.steamwar.core.CraftbukkitWrapper; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import java.util.ArrayList; +import java.util.List; + /** * TinyProtocol can't translate BlockEntities during 1.16 to 1.17 conversions du to removed partial chunk update support. This class cancels PartialChunkUpdates for this players and sends them a complete chunk instead. * This class can only be loaded on 1.9 to 1.15 with active ViaVersion. @@ -40,16 +45,40 @@ public class PartialChunkFixer { private final ViaAPI via = Via.getAPI(); + private final List chunksToResend = new ArrayList<>(); + public PartialChunkFixer() { TinyProtocol.instance.addFilter(mapChunk, this::chunkFilter); + Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> { + synchronized (chunksToResend) { + for(ResendChunk chunk : chunksToResend) { + CraftbukkitWrapper.impl.sendChunk(chunk.player, chunk.x, chunk.z); + } + chunksToResend.clear(); + } + }, 1, 1); } private Object chunkFilter(Player player, Object packet) { if(via.getPlayerVersion(player) >= PROTOCOL1_17 && !fullChunkFlag.get(packet)) { // partial chunk update - CraftbukkitWrapper.impl.sendChunk(player, chunkX.get(packet), chunkZ.get(packet)); + synchronized (chunksToResend) { + chunksToResend.add(new ResendChunk(player, chunkX.get(packet), chunkZ.get(packet))); + } return null; } return packet; } + + private static class ResendChunk { + private final Player player; + private final int x; + private final int z; + + private ResendChunk(Player player, int x, int z) { + this.player = player; + this.x = x; + this.z = z; + } + } }