From 78fef0b874b4a8fca32ad65702f2961e5125a116 Mon Sep 17 00:00:00 2001 From: TurboMaxe Date: Sun, 19 Apr 2026 08:26:56 +0500 Subject: [PATCH 1/7] initial commit --- .idea/.gitignore | 3 + .idea/compiler.xml | 15 ++ .idea/gradle.xml | 17 ++ .idea/inspectionProfiles/Project_Default.xml | 8 + .idea/misc.xml | 9 + .idea/modules.xml | 9 + .idea/modules/TuffXPlus.main.iml | 14 ++ .idea/modules/TuffXPlus.test.iml | 13 ++ .idea/vcs.xml | 6 + build.gradle | 82 --------- build.gradle.kts | 83 +++++++++ gradle/libs.version.toml | 19 ++ gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle | 1 - settings.gradle.kts | 1 + src/main/java/tf/tuff/TuffX.java | 170 +++++------------- .../java/tf/tuff/listeners/BlockListener.java | 60 +++++++ .../java/tf/tuff/listeners/ListenerBase.java | 21 +++ .../tf/tuff/listeners/PlayerListener.java | 56 ++++++ src/main/java/tf/tuff/netty/BaseInjector.java | 24 ++- .../java/tf/tuff/tuffactions/TuffActions.java | 142 ++++++++------- .../tuffactions/creative/CreativeMenu.java | 18 +- .../tf/tuff/tuffactions/creative/TabUtil.java | 12 +- .../tuff/tuffactions/swimming/Swimming.java | 9 +- .../tf/tuff/viablocks/ViaBlocksPlugin.java | 3 - .../viablocks/version/VersionAdapter.java | 4 + .../version/modern/ModernAdapter.java | 4 +- src/main/java/tf/tuff/y0/Y0Plugin.java | 122 ++++++------- 28 files changed, 546 insertions(+), 381 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/modules/TuffXPlus.main.iml create mode 100644 .idea/modules/TuffXPlus.test.iml create mode 100644 .idea/vcs.xml delete mode 100644 build.gradle create mode 100644 build.gradle.kts create mode 100644 gradle/libs.version.toml delete mode 100644 settings.gradle create mode 100644 settings.gradle.kts create mode 100644 src/main/java/tf/tuff/listeners/BlockListener.java create mode 100644 src/main/java/tf/tuff/listeners/ListenerBase.java create mode 100644 src/main/java/tf/tuff/listeners/PlayerListener.java diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..90a6016 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..7d3b3e8 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..1fcfd5c --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..a25b6db --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..c4e1060 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/TuffXPlus.main.iml b/.idea/modules/TuffXPlus.main.iml new file mode 100644 index 0000000..ad42100 --- /dev/null +++ b/.idea/modules/TuffXPlus.main.iml @@ -0,0 +1,14 @@ + + + + + + + SPIGOT + ADVENTURE + + 1 + + + + \ No newline at end of file diff --git a/.idea/modules/TuffXPlus.test.iml b/.idea/modules/TuffXPlus.test.iml new file mode 100644 index 0000000..a376b96 --- /dev/null +++ b/.idea/modules/TuffXPlus.test.iml @@ -0,0 +1,13 @@ + + + + + + + ADVENTURE + + 1 + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle deleted file mode 100644 index fe10c6e..0000000 --- a/build.gradle +++ /dev/null @@ -1,82 +0,0 @@ -plugins { - id 'java' - id 'com.gradleup.shadow' version '8.3.0' -} - -group = 'tf.tuff' -version = '1.0.0' - -java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 -} - -tasks.withType(JavaCompile).configureEach { - options.encoding = "UTF-8" -} - -repositories { - mavenCentral() - maven { url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' } - maven { url = 'https://repo.papermc.io/repository/maven-public/' } - maven { url = 'https://repo.viaversion.com/everything/' } - maven { url = 'https://repo.codemc.io/repository/maven-releases/' } - maven { url = 'https://repo.codemc.io/repository/maven-snapshots/' } - maven { url = 'https://jitpack.io' } - maven { url = 'https://repo.dmulloy2.net/repository/public/' } -} - -dependencies { - compileOnly 'org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT' - - implementation 'com.github.retrooper:packetevents-spigot:2.11.1' - - compileOnly 'com.viaversion:viabackwards:5.3.2' - compileOnly 'com.viaversion:viaversion:5.4.1' - - compileOnly 'it.unimi.dsi:fastutil:8.5.16' - - implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2' - - compileOnly 'io.netty:netty-all:4.1.97.Final' - - implementation 'org.java-websocket:Java-WebSocket:1.5.4' - - compileOnly 'org.projectlombok:lombok:1.18.30' - annotationProcessor 'org.projectlombok:lombok:1.18.30' -} - -processResources { - filesMatching('plugin.yml') { - expand( - 'version': project.version, - 'name': project.name - ) - } -} - -shadowJar { - archiveClassifier.set('') - archiveFileName.set("${project.name}-${project.version}.jar") - - relocate 'com.github.retrooper.packetevents', 'tf.tuff.packetevents' - relocate 'io.github.retrooper.packetevents', 'tf.tuff.packetevents' - relocate 'com.fasterxml.jackson', 'tf.tuff.jackson' - relocate 'org.java_websocket', 'tf.tuff.websocket' - - exclude 'META-INF/*.SF' - exclude 'META-INF/*.DSA' - exclude 'META-INF/*.RSA' - exclude 'META-INF/LICENSE' - exclude 'META-INF/NOTICE' - exclude 'META-INF/versions/**' - exclude 'module-info.class' -} - -tasks.named('jar') { - enabled = false -} - -tasks.named('build') { - dependsOn shadowJar -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..0823990 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,83 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +plugins { + java + id("com.gradleup.shadow") version "8.3.0" + id("io.papermc.paperweight.userdev") version "2.0.0-beta.19" +} + +group = "tf.tuff" +version = "1.0.0" + + +repositories { + mavenCentral() + maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") + maven("https://repo.papermc.io/repository/maven-public/") + maven("https://repo.viaversion.com/everything/") + maven("https://repo.codemc.io/repository/maven-releases/") + maven("https://repo.codemc.io/repository/maven-snapshots/") + maven("https://jitpack.io") + maven("https://repo.dmulloy2.net/repository/public/") +} + +dependencies { + implementation(libs.packetevents.spigot) + compileOnly(libs.viabackwards) + compileOnly(libs.viaversion) + compileOnly(libs.fastutil) + implementation(libs.jackson.databind) + compileOnly(libs.netty.all) + implementation(libs.java.websocket) + + compileOnly(libs.lombok) + annotationProcessor(libs.lombok) +} + + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +tasks { + + withType().configureEach { + options.encoding = "UTF-8" + } + + processResources { + filesMatching("plugin.yml") { + expand( + "version" to project.version, + "name" to project.name + ) + } + } + + withType { + archiveClassifier.set("") + archiveFileName.set("${project.name}-${project.version}.jar") + + relocate("com.github.retrooper.packetevents", "tf.tuff.packetevents") + relocate("io.github.retrooper.packetevents", "tf.tuff.packetevents") + relocate("com.fasterxml.jackson", "tf.tuff.jackson") + relocate("org.java_websocket", "tf.tuff.websocket") + + exclude("META-INF/*.SF") + exclude("META-INF/*.DSA") + exclude("META-INF/*.RSA") + exclude("META-INF/LICENSE") + exclude("META-INF/NOTICE") + exclude("META-INF/versions/**") + exclude("module-info.class") + } + + withType { + enabled = false + } + + named("build") { + dependsOn(shadowJar) + } +} \ No newline at end of file diff --git a/gradle/libs.version.toml b/gradle/libs.version.toml new file mode 100644 index 0000000..af18bab --- /dev/null +++ b/gradle/libs.version.toml @@ -0,0 +1,19 @@ +[versions] +packetevents = "2.11.1" +viabackwards = "5.3.2" +viaversion = "5.4.1" +fastutil = "8.5.16" +jackson = "2.15.2" +netty = "4.1.97.Final" +websocket = "1.5.4" +lombok = "1.18.30" + +[libraries] +packetevents-spigot = { module = "com.github.retrooper:packetevents-spigot", version.ref = "packetevents" } +viabackwards = { module = "com.viaversion:viabackwards", version.ref = "viabackwards" } +viaversion = { module = "com.viaversion:viaversion", version.ref = "viaversion" } +fastutil = { module = "it.unimi.dsi:fastutil", version.ref = "fastutil" } +jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } +netty-all = { module = "io.netty:netty-all", version.ref = "netty" } +java-websocket = { module = "org.java-websocket:Java-WebSocket", version.ref = "websocket" } +lombok = { module = "org.projectlombok:lombok", version.ref = "lombok" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e09..c61a118 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index e4ea97e..0000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'TuffXPlus' diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..873b2d7 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "TuffXPlus" diff --git a/src/main/java/tf/tuff/TuffX.java b/src/main/java/tf/tuff/TuffX.java index 92e14ab..79e21e2 100644 --- a/src/main/java/tf/tuff/TuffX.java +++ b/src/main/java/tf/tuff/TuffX.java @@ -1,5 +1,7 @@ package tf.tuff; +import lombok.Getter; +import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -27,26 +29,31 @@ import tf.tuff.viaentities.ViaEntitiesPlugin; import tf.tuff.y0.Y0Plugin; -public class TuffX extends JavaPlugin implements Listener, PluginMessageListener { +import java.util.List; - public ServerRegistry serverRegistry; +public class TuffX extends JavaPlugin implements PluginMessageListener { - public Y0Plugin y0Plugin; - public ViaBlocksPlugin viaBlocksPlugin; - public TuffActions tuffActions; - public ViaEntitiesPlugin viaEntitiesPlugin; - private ChunkInjector chunkInjector; + private ServerRegistry serverRegistry; + @Getter private static TuffX instance; + @Getter private Y0Plugin y0Plugin; + @Getter private ViaBlocksPlugin viaBlocksPlugin; + @Getter private TuffActions tuffActions; + @Getter private ViaEntitiesPlugin viaEntitiesPlugin; + + public TuffX() { + instance = this; + } @Override public void onLoad() { - this.y0Plugin = new Y0Plugin(this); + y0Plugin = new Y0Plugin(this); this.viaBlocksPlugin = new ViaBlocksPlugin(this); this.tuffActions = new TuffActions(this); this.viaEntitiesPlugin = new ViaEntitiesPlugin(this); PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this)); PacketEvents.getAPI().getSettings().reEncodeByDefault(false) - .checkForUpdates(false); + .checkForUpdates(false); PacketEvents.getAPI().load(); } @@ -55,16 +62,15 @@ public void onEnable() { PacketEvents.getAPI().init(); y0Plugin.onTuffXEnable(); - tuffActions.onTuffXEnable(); + tuffActions.load(); viaBlocksPlugin.onTuffXEnable(); viaEntitiesPlugin.onTuffXEnable(); - chunkInjector = new ChunkInjector(viaBlocksPlugin.blockListener, y0Plugin); + ChunkInjector chunkInjector = new ChunkInjector(viaBlocksPlugin.blockListener, y0Plugin); viaBlocksPlugin.blockListener.setChunkInjector(chunkInjector); y0Plugin.setChunkInjector(chunkInjector); saveDefaultConfig(); - PacketEvents.getAPI().getEventManager().registerListener( new NetworkListener(this), PacketListenerPriority.NORMAL ); @@ -158,120 +164,32 @@ public void onPluginMessageReceived(String channel, Player player, byte[] messag else getLogger().warning("Received plugin message on unknown channel '%s' from %s".formatted(channel, player.getName())); } - @EventHandler(priority = EventPriority.MONITOR) - public void onPlayerChangeWorld(PlayerChangedWorldEvent e) { - y0Plugin.handlePlayerChangeWorld(e); - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockForm(BlockFormEvent e) { - viaBlocksPlugin.blockListener.handleBlockForm(e); - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockFade(BlockFadeEvent e) { - viaBlocksPlugin.blockListener.handleBlockFade(e); - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onPlayerJoin(PlayerJoinEvent e) { - y0Plugin.handlePlayerJoin(e); - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockGrow(BlockGrowEvent e) { - viaBlocksPlugin.blockListener.handleBlockGrow(e); - } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent e) { - y0Plugin.handlePlayerQuit(e); - tuffActions.handlePlayerQuit(e); - viaBlocksPlugin.blockListener.handlePlayerQuit(e); - viaEntitiesPlugin.handlePlayerQuit(e); - } - - @EventHandler - public void onToggleSwim(EntityToggleSwimEvent e) { - tuffActions.handleToggleSwim(e); - } - - @EventHandler - public void onToggleGlide(EntityToggleGlideEvent e) { - tuffActions.handleToggleGlide(e); - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockSpread(BlockSpreadEvent e) { - viaBlocksPlugin.blockListener.handleBlockSpread(e); - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockBreak(BlockBreakEvent e) { - viaBlocksPlugin.blockListener.handleBlockBreak(e); - y0Plugin.handleBlockBreak(e); - } - - @EventHandler - public void onPlayerInventoryClick(InventoryClickEvent e) { - tuffActions.handlePlayerInventoryClick(e); - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockPlace(BlockPlaceEvent e) { - viaBlocksPlugin.blockListener.handleBlockPlace(e); - y0Plugin.handleBlockPlace(e); - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onBlockPhysics(BlockPhysicsEvent e) { - y0Plugin.handleBlockPhysics(e); - viaBlocksPlugin.blockListener.handleBlockPhysics(e); - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onChunkLoad(ChunkLoadEvent e) { - y0Plugin.handleChunkLoad(e); - viaBlocksPlugin.blockListener.handleChunkLoad(e); - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockExplode(BlockExplodeEvent e) { - viaBlocksPlugin.blockListener.handleBlockExplode(e); - y0Plugin.handleBlockExplode(e); - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onBlockFromTo(BlockFromToEvent e) { - viaBlocksPlugin.blockListener.handleBlockFromTo(e); - y0Plugin.handleBlockFromTo(e); - } - private void lfe() { - getLogger().info(""); - getLogger().info("████████╗██╗ ██╗███████╗ ███████╗ ██╗ ██╗"); - getLogger().info("╚══██╔══╝██║ ██║██╔════╝ ██╔════╝ ╚██╗██╔╝"); - getLogger().info(" ██║ ██║ ██║██████╗ ██████╗ ╚███╔╝ "); - getLogger().info(" ██║ ██║ ██║██╔═══╝ ██╔═══╝ ██╔██╗ "); - getLogger().info(" ██║ ╚██████╔╝██║ ██║ ██╔╝╚██╗"); - getLogger().info(" ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝"); - getLogger().info(""); - getLogger().info("CREDITS"); - getLogger().info(""); - getLogger().info("Y0 support:"); - getLogger().info("• Below y0 (client + plugin) programmed by Potato (@justatypicalpotato)"); - getLogger().info("• llucasandersen - plugin optimizations"); - getLogger().info(""); - getLogger().info("ViaBlocks:"); - getLogger().info("• ViaBlocks partial plugin and client rewrite by Potato"); - getLogger().info("• llucasandersen (Complex client models and texture fixes,"); - getLogger().info(" optimizations, PacketEvents migration and async safety fixes)"); - getLogger().info("• coleis1op, if ts is driving me crazy, im taking credit"); - getLogger().info(""); - getLogger().info("Other:"); - getLogger().info("• Swimming and creative items programmed by Potato (@justatypicalpotato)"); - getLogger().info("• shaded build, 1.14+ support (before merge) - llucasandersen"); - getLogger().info("• Restrictions - UplandJacob"); - getLogger().info("• Overall plugin merges by Potato"); + List.of( + "████████╗██╗ ██╗███████╗ ███████╗ ██╗ ██╗", + "╚══██╔══╝██║ ██║██╔════╝ ██╔════╝ ╚██╗██╔╝", + " ██║ ██║ ██║██████╗ ██████╗ ╚███╔╝ ", + " ██║ ██║ ██║██╔═══╝ ██╔═══╝ ██╔██╗ ", + " ██║ ╚██████╔╝██║ ██║ ██╔╝╚██╗", + " ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝", + "", + "CREDITS", + "", + "Y0 support:", + "• Below y0 (client + plugin) programmed by Potato (@justatypicalpotato)", + "• llucasandersen - plugin optimizations", + "", + "ViaBlocks:", + "• ViaBlocks partial plugin and client rewrite by Potato", + "• llucasandersen (Complex client models and texture fixes,", + " optimizations, PacketEvents migration and async safety fixes)", + "• coleis1op, if ts is driving me crazy, im taking credit", + "", + "Other:", + "• Swimming and creative items programmed by Potato (@justatypicalpotato)", + "• shaded build, 1.14+ support (before merge) - llucasandersen", + "• Restrictions - UplandJacob", + "• Overall plugin merges by Potato" + ).forEach(Bukkit.getConsoleSender()::sendMessage); } } diff --git a/src/main/java/tf/tuff/listeners/BlockListener.java b/src/main/java/tf/tuff/listeners/BlockListener.java new file mode 100644 index 0000000..b820d62 --- /dev/null +++ b/src/main/java/tf/tuff/listeners/BlockListener.java @@ -0,0 +1,60 @@ +package tf.tuff.listeners; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.*; + +public class BlockListener extends ListenerBase implements Listener { + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockForm(BlockFormEvent e) { + viaBlocksPlugin.blockListener.handleBlockForm(e); + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockFade(BlockFadeEvent e) { + viaBlocksPlugin.blockListener.handleBlockFade(e); + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockSpread(BlockSpreadEvent e) { + viaBlocksPlugin.blockListener.handleBlockSpread(e); + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent e) { + viaBlocksPlugin.blockListener.handleBlockBreak(e); + y0Plugin.handleBlockBreak(e); + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockGrow(BlockGrowEvent e) { + viaBlocksPlugin.blockListener.handleBlockGrow(e); + } + + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockPlace(BlockPlaceEvent e) { + viaBlocksPlugin.blockListener.handleBlockPlace(e); + y0Plugin.handleBlockPlace(e); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockPhysics(BlockPhysicsEvent e) { + y0Plugin.handleBlockPhysics(e); + viaBlocksPlugin.blockListener.handleBlockPhysics(e); + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockExplode(BlockExplodeEvent e) { + viaBlocksPlugin.blockListener.handleBlockExplode(e); + y0Plugin.handleBlockExplode(e); + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockFromTo(BlockFromToEvent e) { + viaBlocksPlugin.blockListener.handleBlockFromTo(e); + y0Plugin.handleBlockFromTo(e); + } +} diff --git a/src/main/java/tf/tuff/listeners/ListenerBase.java b/src/main/java/tf/tuff/listeners/ListenerBase.java new file mode 100644 index 0000000..678a752 --- /dev/null +++ b/src/main/java/tf/tuff/listeners/ListenerBase.java @@ -0,0 +1,21 @@ +package tf.tuff.listeners; + +import tf.tuff.TuffX; +import tf.tuff.tuffactions.TuffActions; +import tf.tuff.viablocks.ViaBlocksPlugin; +import tf.tuff.viaentities.ViaEntitiesPlugin; +import tf.tuff.y0.Y0Plugin; + +public abstract class ListenerBase { + protected final ViaBlocksPlugin viaBlocksPlugin; + protected final TuffActions tuffActions; + protected final ViaEntitiesPlugin viaEntitiesPlugin; + protected final Y0Plugin y0Plugin; + + public ListenerBase() { + viaBlocksPlugin = TuffX.getInstance().getViaBlocksPlugin(); + tuffActions = TuffX.getInstance().getTuffActions(); + viaEntitiesPlugin = TuffX.getInstance().getViaEntitiesPlugin(); + y0Plugin = TuffX.getInstance().getY0Plugin(); + } +} diff --git a/src/main/java/tf/tuff/listeners/PlayerListener.java b/src/main/java/tf/tuff/listeners/PlayerListener.java new file mode 100644 index 0000000..bac9095 --- /dev/null +++ b/src/main/java/tf/tuff/listeners/PlayerListener.java @@ -0,0 +1,56 @@ +package tf.tuff.listeners; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.*; +import org.bukkit.event.entity.EntityToggleGlideEvent; +import org.bukkit.event.entity.EntityToggleSwimEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerChangedWorldEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.world.ChunkLoadEvent; + +public class PlayerListener extends ListenerBase implements Listener { + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerChangeWorld(PlayerChangedWorldEvent e) { + y0Plugin.handlePlayerChangeWorld(e); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerJoin(PlayerJoinEvent e) { + y0Plugin.handlePlayerJoin(e); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent e) { + y0Plugin.handlePlayerQuit(e); + tuffActions.handlePlayerQuit(e); + viaBlocksPlugin.blockListener.handlePlayerQuit(e); + viaEntitiesPlugin.handlePlayerQuit(e); + } + + @EventHandler + public void onPlayerInventoryClick(InventoryClickEvent e) { + tuffActions.handlePlayerInventoryClick(e); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onChunkLoad(ChunkLoadEvent e) { + y0Plugin.handleChunkLoad(e); + viaBlocksPlugin.blockListener.handleChunkLoad(e); + } + + @EventHandler + public void onToggleSwim(EntityToggleSwimEvent e) { + tuffActions.handleToggleSwim(e); + } + + @EventHandler + public void onToggleGlide(EntityToggleGlideEvent e) { + tuffActions.handleToggleGlide(e); + } + +} diff --git a/src/main/java/tf/tuff/netty/BaseInjector.java b/src/main/java/tf/tuff/netty/BaseInjector.java index b2e521b..fbc7b08 100644 --- a/src/main/java/tf/tuff/netty/BaseInjector.java +++ b/src/main/java/tf/tuff/netty/BaseInjector.java @@ -1,9 +1,11 @@ package tf.tuff.netty; import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.connection.UserConnection; import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import java.util.UUID; @@ -36,12 +38,12 @@ public void inject(Player player) { String targetHandler = null; String[] anchors = {"packet_handler", "encoder", "via-encoder"}; - for (int i = 0; i < anchors.length; ++i) { - if (channel.pipeline().get(anchors[i]) != null) { - targetHandler = anchors[i]; - break; - } - } + for (String anchor : anchors) { + if (channel.pipeline().get(anchor) != null) { + targetHandler = anchor; + break; + } + } ChannelHandler handler = createHandler(player); if (targetHandler != null) { @@ -58,19 +60,15 @@ public void inject(Player player) { } public void eject(Player player) { - UUID uuid = player.getUniqueId(); - var viaConnection = Via.getAPI().getConnection(uuid); - if (viaConnection == null) return; - - Channel channel = viaConnection.getChannel(); + UserConnection viaConnection = Via.getAPI().getConnection(player.getUniqueId()); + Channel channel = viaConnection != null ? viaConnection.getChannel() : null; if (channel != null && channel.isOpen()) { channel.eventLoop().submit(() -> { try { if (channel.pipeline().get(handlerName) != null) { channel.pipeline().remove(handlerName); } - } catch (Exception e) { - } + } catch (Exception ignored) {} }); } } diff --git a/src/main/java/tf/tuff/tuffactions/TuffActions.java b/src/main/java/tf/tuff/tuffactions/TuffActions.java index bf90b04..f50b083 100644 --- a/src/main/java/tf/tuff/tuffactions/TuffActions.java +++ b/src/main/java/tf/tuff/tuffactions/TuffActions.java @@ -1,14 +1,7 @@ package tf.tuff.tuffactions; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Level; - +import com.github.retrooper.packetevents.PacketEvents; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPluginMessage; import org.bukkit.GameMode; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -17,15 +10,20 @@ import org.bukkit.event.entity.EntityToggleSwimEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.player.PlayerQuitEvent; - -import com.github.retrooper.packetevents.PacketEvents; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPluginMessage; - import tf.tuff.TuffX; import tf.tuff.tuffactions.creative.CreativeMenu; import tf.tuff.tuffactions.restrictions.Restrictions; import tf.tuff.tuffactions.swimming.Swimming; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; + public class TuffActions { public static final String CHANNEL = "eagler:tuffactions"; @@ -37,12 +35,12 @@ public class TuffActions { public static boolean swimmingEnabled = false; public static boolean creativeEnabled = false; public static boolean restrictionsEnabled = false; - + public final TuffX plugin; public static final Set tuffPlayers = ConcurrentHashMap.newKeySet(); - public TuffActions(TuffX plugin){ + public TuffActions(TuffX plugin) { this.plugin = plugin; } @@ -67,7 +65,7 @@ public void onTuffXReload() { info("Misc features reloaded."); } - public void onTuffXEnable() { + public void load() { loadConfig(); PacketEvents.getAPI().init(); @@ -75,13 +73,11 @@ public void onTuffXEnable() { this.creativeManager = new CreativeMenu(this); this.restrictions = new Restrictions(this); info("Finished enabling features."); - - plugin.getServer().getMessenger().registerOutgoingPluginChannel(plugin, "eagler:tuffactions"); - plugin.getServer().getMessenger().registerIncomingPluginChannel(plugin, "eagler:tuffactions", plugin); } public boolean onTuffXCommand(CommandSender sender, Command command, String label, String[] args) { - if (command.getName().equalsIgnoreCase("restrictions")) return this.restrictions.onTuffXCommand(sender, command, label, args); + if (command.getName().equalsIgnoreCase("restrictions")) + return this.restrictions.onTuffXCommand(sender, command, label, args); return true; } @@ -103,43 +99,58 @@ public void handlePacket(Player player, byte[] message) { tuffPlayers.add(player.getUniqueId()); - if ("swimming_state".equals(action) && swimmingEnabled) { - swimmingManager.handleSwimState(player, in.readBoolean()); - } else if ("elytra_state".equals(action) && swimmingEnabled) { - swimmingManager.handleElytraState(player, in.readBoolean()); - } else if ("creative_ready".equals(action) && creativeEnabled){ - creativeManager.handleCreativeReady(player); - } else if ("swim_ready".equals(action) && swimmingEnabled){ - swimmingManager.handleSwimReady(player); - } else if ("give_creative_item".equals(action) && creativeEnabled){ - if (player.getGameMode() != GameMode.CREATIVE) { - return; - } - int itemLength = in.readUnsignedByte(); - if (in.available() < itemLength + Integer.BYTES) { - return; - } - byte[] itemBytes = new byte[itemLength]; - in.readFully(itemBytes); - String item = new String(itemBytes, StandardCharsets.UTF_8); - int amount = in.readInt(); - creativeManager.handlePlaceholderTaken(player, item, amount); - } else if ("pick_viablock".equals(action) && creativeEnabled){ - if (player.getGameMode() != GameMode.CREATIVE) { - return; - } - int blockLength = in.readUnsignedByte(); - if (in.available() < blockLength + 1) { - return; - } - byte[] blockBytes = new byte[blockLength]; - in.readFully(blockBytes); - String blockName = new String(blockBytes, StandardCharsets.UTF_8); - int hotbarSlot = in.readUnsignedByte(); - creativeManager.handlePickViablock(player, blockName, hotbarSlot); - } else if ("restrictions_ready".equals(action)) { - restrictions.handleRestrictionsReady(player); + // This may or may not work - turbo + switch (action.toLowerCase()) { + case "swimming_state": + if (swimmingEnabled) { + swimmingManager.handleSwimState(player, in.readBoolean()); + break; + } + case "elytra_state": + if (swimmingEnabled) { + swimmingManager.handleElytraState(player, in.readBoolean()); + break; + } + case "creative-ready": + if (creativeEnabled) { + creativeManager.handleCreativeReady(player); + break; + } + case "swim_ready": + if (swimmingEnabled) { + swimmingManager.handleSwimReady(player); + break; + } + case "give_creative_item": + if (creativeEnabled) { + if (player.getGameMode() != GameMode.CREATIVE) return; + int itemLength = in.readUnsignedByte(); + if (in.available() < itemLength + Integer.BYTES) { + return; + } + byte[] itemBytes = new byte[itemLength]; + in.readFully(itemBytes); + String item = new String(itemBytes, StandardCharsets.UTF_8); + int amount = in.readInt(); + creativeManager.handlePlaceholderTaken(player, item, amount); + break; + } + case "pick_viablock": + if (creativeEnabled) { + if (player.getGameMode() != GameMode.CREATIVE) return; + int blockLength = in.readUnsignedByte(); + if (in.available() < blockLength + 1) return; + byte[] blockBytes = new byte[blockLength]; + in.readFully(blockBytes); + String blockName = new String(blockBytes, StandardCharsets.UTF_8); + int hotbarSlot = in.readUnsignedByte(); + creativeManager.handlePickViablock(player, blockName, hotbarSlot); + break; + } + case "restrictions_ready": + restrictions.handleRestrictionsReady(player); } + } catch (IOException e) { log(Level.WARNING, "Failed to read a plugin message from " + player.getName(), e); } @@ -150,17 +161,18 @@ public void sendPluginMessage(Player player, byte[] payload) { } public void sendPluginMessage(Player player, String channel, byte[] payload) { - if (player == null || payload == null || !player.isOnline() || !PacketEvents.getAPI().isInitialized()) { + if (player == null || payload == null || + !player.isOnline() || !PacketEvents.getAPI().isInitialized() + ) { return; } + WrapperPlayServerPluginMessage packet = new WrapperPlayServerPluginMessage(channel, payload); PacketEvents.getAPI().getPlayerManager().sendPacket(player, packet); } public void handlePlayerQuit(PlayerQuitEvent event) { - if (swimmingEnabled) { - swimmingManager.handleSwimQuit(event); - } + if (swimmingEnabled) swimmingManager.handleSwimQuit(event); tuffPlayers.remove(event.getPlayer().getUniqueId()); } @@ -177,17 +189,17 @@ public void handleToggleGlide(EntityToggleGlideEvent event) { } public void handlePlayerInventoryClick(InventoryClickEvent event) { - if (creativeEnabled) { - creativeManager.onPlayerInventoryClick(event); - } + if (creativeEnabled) creativeManager.onPlayerInventoryClick(event); } public void log(Level level, String msg, Throwable e) { - plugin.getLogger().log(level, "[TuffActions] "+msg, e); + plugin.getLogger().log(level, "[TuffActions] ".formatted(msg), e); } + public void log(Level level, String msg) { - plugin.getLogger().log(level, "[TuffActions] "+msg); + plugin.getLogger().log(level, "[TuffActions] %s".formatted(msg)); } + public void info(String msg) { log(Level.INFO, msg); } diff --git a/src/main/java/tf/tuff/tuffactions/creative/CreativeMenu.java b/src/main/java/tf/tuff/tuffactions/creative/CreativeMenu.java index 221f84b..c9c6652 100644 --- a/src/main/java/tf/tuff/tuffactions/creative/CreativeMenu.java +++ b/src/main/java/tf/tuff/tuffactions/creative/CreativeMenu.java @@ -12,10 +12,7 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; @@ -29,18 +26,13 @@ public class CreativeMenu { public CreativeMenu(TuffActions plugin) { this.plugin = plugin; this.tabUtil = new TabUtil(plugin); - - if (TuffActions.creativeEnabled) { - initializeMappings(); - } + if (TuffActions.creativeEnabled) initializeMappings(); } public void initializeMappings() { - for (Material m : Material.values()){ - if (m.isItem()){ - itemMapping.add(m.name()); - } - } + Arrays.stream(Material.values()).toList().forEach(m -> { + if (m.isItem()) itemMapping.add(m.name()); + }); } public void handleCreativeReady(Player player) { diff --git a/src/main/java/tf/tuff/tuffactions/creative/TabUtil.java b/src/main/java/tf/tuff/tuffactions/creative/TabUtil.java index 428990c..5b45c7d 100644 --- a/src/main/java/tf/tuff/tuffactions/creative/TabUtil.java +++ b/src/main/java/tf/tuff/tuffactions/creative/TabUtil.java @@ -10,6 +10,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import org.jetbrains.annotations.NotNull; import tf.tuff.tuffactions.TuffActions; public class TabUtil { @@ -20,9 +21,7 @@ public class TabUtil { public TabUtil(TuffActions plugin) { this.plugin = plugin; this.mappingFile = new File(plugin.plugin.getDataFolder(), "tab-mapping.json"); - setupMappingFile(); - loadMapping(); } @@ -37,7 +36,8 @@ private void loadMapping() { try { ObjectMapper mapper = new ObjectMapper(); - TypeReference> typeRef = new TypeReference>() {}; + TypeReference> typeRef = new TypeReference<>() { + }; this.creativeTabMap = mapper.readValue(mappingFile, typeRef); plugin.info("Successfully loaded " + creativeTabMap.size() + " creative tab mappings."); @@ -49,10 +49,8 @@ private void loadMapping() { } @Nullable - public String getCreativeCategory(String material) { - if (material == null || creativeTabMap.isEmpty()) { - return null; - } + public String getCreativeCategory(@NotNull String material) { + if (creativeTabMap.isEmpty()) return null; return creativeTabMap.get(material); } } \ No newline at end of file diff --git a/src/main/java/tf/tuff/tuffactions/swimming/Swimming.java b/src/main/java/tf/tuff/tuffactions/swimming/Swimming.java index 64ae9b2..9bd6883 100644 --- a/src/main/java/tf/tuff/tuffactions/swimming/Swimming.java +++ b/src/main/java/tf/tuff/tuffactions/swimming/Swimming.java @@ -46,16 +46,14 @@ public void handleElytraState(Player player, boolean isGliding) { } public void handleToggleSwim(EntityToggleSwimEvent event) { - if (!(event.getEntity() instanceof Player)) return; - Player player = (Player) event.getEntity(); + if (!(event.getEntity() instanceof Player player)) return; if (!event.isSwimming() && swimmingPlayers.contains(player.getUniqueId())) { event.setCancelled(true); } } public void handleToggleGlide(EntityToggleGlideEvent event) { - if (!(event.getEntity() instanceof Player)) return; - Player player = (Player) event.getEntity(); + if (!(event.getEntity() instanceof Player player)) return; if (!event.isGliding() && glidingPlayers.contains(player.getUniqueId())) { event.setCancelled(true); } @@ -97,12 +95,11 @@ private void sendSwimState(Player recipient, Player subject, boolean isSwimming) } public void handleSwimReady(Player player) { - Player newPlayer = player; plugin.plugin.getServer().getScheduler().runTaskLater(plugin.plugin, () -> { for (UUID swimmingPlayerId : swimmingPlayers) { Player swimmingPlayer = Bukkit.getPlayer(swimmingPlayerId); if (swimmingPlayer != null && swimmingPlayer.isOnline()) { - sendSwimState(newPlayer, swimmingPlayer, true); + sendSwimState(player, swimmingPlayer, true); } } }, 20L); diff --git a/src/main/java/tf/tuff/viablocks/ViaBlocksPlugin.java b/src/main/java/tf/tuff/viablocks/ViaBlocksPlugin.java index 9537d87..38122ce 100644 --- a/src/main/java/tf/tuff/viablocks/ViaBlocksPlugin.java +++ b/src/main/java/tf/tuff/viablocks/ViaBlocksPlugin.java @@ -82,11 +82,8 @@ public void onTuffXReload() { public void onTuffXEnable() { instance = this; - this.chunkExecutor = Executors.newFixedThreadPool(Math.max(1, Runtime.getRuntime().availableProcessors())); - this.versionAdapter = new ModernAdapter(); - this.paletteManager = new PaletteManager(this.versionAdapter); try { diff --git a/src/main/java/tf/tuff/viablocks/version/VersionAdapter.java b/src/main/java/tf/tuff/viablocks/version/VersionAdapter.java index 79b0cd0..0c9cfd8 100644 --- a/src/main/java/tf/tuff/viablocks/version/VersionAdapter.java +++ b/src/main/java/tf/tuff/viablocks/version/VersionAdapter.java @@ -7,8 +7,12 @@ public interface VersionAdapter { String getBlockDataString(Block block); + String getMaterialKey(Material material); + int getClientViewDistance(Player player); + void giveCustomBlocks(Player player); + EnumSet getModernMaterials(); } \ No newline at end of file diff --git a/src/main/java/tf/tuff/viablocks/version/modern/ModernAdapter.java b/src/main/java/tf/tuff/viablocks/version/modern/ModernAdapter.java index be8e691..f7c0acd 100644 --- a/src/main/java/tf/tuff/viablocks/version/modern/ModernAdapter.java +++ b/src/main/java/tf/tuff/viablocks/version/modern/ModernAdapter.java @@ -662,8 +662,6 @@ public void giveCustomBlocks(Player player) { private void addItemIfPresent(Player player, String materialName) { Material material = Material.matchMaterial(materialName); - if (material != null) { - player.getInventory().addItem(new ItemStack(material)); - } + if (material != null) player.getInventory().addItem(new ItemStack(material)); } } diff --git a/src/main/java/tf/tuff/y0/Y0Plugin.java b/src/main/java/tf/tuff/y0/Y0Plugin.java index a875f8b..75a8742 100644 --- a/src/main/java/tf/tuff/y0/Y0Plugin.java +++ b/src/main/java/tf/tuff/y0/Y0Plugin.java @@ -39,7 +39,7 @@ public class Y0Plugin { public static final String CH = "eagler:below_y0"; public ViaBlockIds v; - + private final ObjectOpenHashSet aib = new ObjectOpenHashSet<>(); private ObjectOpenHashSet ew; private volatile Cache> cc; @@ -52,7 +52,7 @@ public class Y0Plugin { private final ThreadLocal tlbd = ThreadLocal.withInitial(() -> new byte[12288]); private TuffX plugin; - + private static final int[] EMPTY_LEGACY = {1, 0}; private static final Map emissionCache = new ConcurrentHashMap<>(); @@ -71,30 +71,30 @@ public class Y0Plugin { } private static final Map legacy_light_map = Map.ofEntries( - Map.entry(Material.TORCH, 14), - Map.entry(Material.SOUL_TORCH, 10), - Map.entry(Material.LANTERN, 15), - Map.entry(Material.SOUL_LANTERN, 10), - Map.entry(Material.GLOWSTONE, 15), - Map.entry(Material.SEA_LANTERN, 15), - Map.entry(Material.REDSTONE_LAMP, 15), - Map.entry(Material.SHROOMLIGHT, 15), - Map.entry(Material.CAMPFIRE, 15), - Map.entry(Material.SOUL_CAMPFIRE, 10), - Map.entry(Material.END_ROD, 14), - Map.entry(Material.MAGMA_BLOCK, 3), - Map.entry(Material.FIRE, 15), - Map.entry(Material.SOUL_FIRE, 10), - Map.entry(Material.CANDLE, 3), - Map.entry(Material.WHITE_CANDLE, 3), - Map.entry(Material.CAKE, 0), - Map.entry(Material.CANDLE_CAKE, 3) + Map.entry(Material.TORCH, 14), + Map.entry(Material.SOUL_TORCH, 10), + Map.entry(Material.LANTERN, 15), + Map.entry(Material.SOUL_LANTERN, 10), + Map.entry(Material.GLOWSTONE, 15), + Map.entry(Material.SEA_LANTERN, 15), + Map.entry(Material.REDSTONE_LAMP, 15), + Map.entry(Material.SHROOMLIGHT, 15), + Map.entry(Material.CAMPFIRE, 15), + Map.entry(Material.SOUL_CAMPFIRE, 10), + Map.entry(Material.END_ROD, 14), + Map.entry(Material.MAGMA_BLOCK, 3), + Map.entry(Material.FIRE, 15), + Map.entry(Material.SOUL_FIRE, 10), + Map.entry(Material.CANDLE, 3), + Map.entry(Material.WHITE_CANDLE, 3), + Map.entry(Material.CAKE, 0), + Map.entry(Material.CANDLE_CAKE, 3) ); public Y0Plugin(TuffX plugin){ this.plugin = plugin; } - + private void debug(String m) { if (d) plugin.getLogger().info("[Y0-Debug] " + m); } @@ -116,11 +116,11 @@ public record WCK(String w, int x, int z) {} public void onTuffXReload() { d = plugin.getConfig().getBoolean("y0.debug-mode", false); - + ObjectArrayList ewList = new ObjectArrayList<>(plugin.getConfig().getStringList("y0.enabled-worlds")); ew = new ObjectOpenHashSet<>(ewList.size()); if (plugin.getConfig().getBoolean("y0.y0-enabled", false)) ew.addAll(ewList); - + if (cc != null) { cc.invalidateAll(); } @@ -131,17 +131,17 @@ public void onTuffXReload() { int cacheExp = plugin.getConfig().getInt("y0.cache-expiration", 5); int concLevel = Runtime.getRuntime().availableProcessors(); cc = CacheBuilder.newBuilder() - .maximumSize(cacheSize) - .expireAfterAccess(cacheExp, TimeUnit.MINUTES) - .concurrencyLevel(concLevel) - .initialCapacity(256) - .build(); + .maximumSize(cacheSize) + .expireAfterAccess(cacheExp, TimeUnit.MINUTES) + .concurrencyLevel(concLevel) + .initialCapacity(256) + .build(); ccCombined = CacheBuilder.newBuilder() - .maximumSize(cacheSize) - .expireAfterAccess(cacheExp, TimeUnit.MINUTES) - .concurrencyLevel(concLevel) - .initialCapacity(256) - .build(); + .maximumSize(cacheSize) + .expireAfterAccess(cacheExp, TimeUnit.MINUTES) + .concurrencyLevel(concLevel) + .initialCapacity(256) + .build(); if (cp != null) { cp.shutdown(); @@ -154,7 +154,7 @@ public void onTuffXReload() { Thread.currentThread().interrupt(); } } - + int ct = plugin.getConfig().getInt("y0.chunk-processor-threads", -1); int tc; if (ct <= 0) { @@ -162,13 +162,13 @@ public void onTuffXReload() { } else { tc = ct; } - + cp = Executors.newFixedThreadPool(tc, r -> { Thread t = new Thread(r, "TuffX-Chunk-" + System.nanoTime()); t.setDaemon(true); t.setPriority(Thread.NORM_PRIORITY - 1); return t; - }); + }); emissionCache.clear(); @@ -190,17 +190,17 @@ public void onTuffXEnable() { int cacheExp2 = plugin.getConfig().getInt("y0.cache-expiration", 5); int concLevel2 = Runtime.getRuntime().availableProcessors(); cc = CacheBuilder.newBuilder() - .maximumSize(cacheSize2) - .expireAfterAccess(cacheExp2, TimeUnit.MINUTES) - .concurrencyLevel(concLevel2) - .initialCapacity(256) - .build(); + .maximumSize(cacheSize2) + .expireAfterAccess(cacheExp2, TimeUnit.MINUTES) + .concurrencyLevel(concLevel2) + .initialCapacity(256) + .build(); ccCombined = CacheBuilder.newBuilder() - .maximumSize(cacheSize2) - .expireAfterAccess(cacheExp2, TimeUnit.MINUTES) - .concurrencyLevel(concLevel2) - .initialCapacity(256) - .build(); + .maximumSize(cacheSize2) + .expireAfterAccess(cacheExp2, TimeUnit.MINUTES) + .concurrencyLevel(concLevel2) + .initialCapacity(256) + .build(); plugin.getServer().getMessenger().registerOutgoingPluginChannel(plugin, CH); plugin.getServer().getMessenger().registerIncomingPluginChannel(plugin, CH, plugin); @@ -214,7 +214,7 @@ public void onTuffXEnable() { } else { tc = ct; } - + cp = Executors.newFixedThreadPool(tc, r -> { Thread t = new Thread(r, "TuffX-Chunk-" + System.nanoTime()); t.setDaemon(true); @@ -253,7 +253,7 @@ public void onTuffXDisable() { } aib.clear(); - + if (v != null) { v = null; } @@ -395,7 +395,7 @@ private void sendY0ChunksBatched(Player p, String worldName, List chunks, if (endIndex < chunks.size()) { final int nextStart = endIndex; plugin.getServer().getScheduler().runTaskLater(plugin, () -> - sendY0ChunksBatched(p, worldName, chunks, nextStart), 1); + sendY0ChunksBatched(p, worldName, chunks, nextStart), 1); } } @@ -641,7 +641,7 @@ public void cacheChunkWithCallback(Player p, int chunkX, int chunkZ, Consumer= 0) continue; stu.add(new CSC( - (bx + dx) >> 4, - ny >> 4, - (bz + dz) >> 4 + (bx + dx) >> 4, + ny >> 4, + (bz + dz) >> 4 )); } } @@ -856,7 +856,7 @@ private void slu(Location l) { for (CSC sc : stu) { if (!w.isChunkLoaded(sc.x, sc.z)) continue; ChunkSnapshot s = w.getChunkAt(sc.x, sc.z).getChunkSnapshot(true, false, false); - + if (cp != null && !cp.isShutdown()) { cp.submit(() -> { try { @@ -877,8 +877,8 @@ private void slu(Location l) { } private byte[] clp(ChunkSnapshot s, CSC sc) throws IOException { - try (ByteArrayOutputStream b = new ByteArrayOutputStream(4120); - DataOutputStream o = new DataOutputStream(b)) { + try (ByteArrayOutputStream b = new ByteArrayOutputStream(4120); + DataOutputStream o = new DataOutputStream(b)) { o.writeUTF("lighting_update"); o.writeInt(sc.x); o.writeInt(sc.z); From ebbb2cfe7e974bf0287ae83788c8fbfacc575a25 Mon Sep 17 00:00:00 2001 From: TurboMaxe Date: Sun, 19 Apr 2026 09:40:20 +0500 Subject: [PATCH 2/7] fix: listener super class constructor --- gradle/gradle-wrapper-shared-8.5.jar | Bin 32944 -> 0 bytes src/main/java/tf/tuff/NetworkListener.java | 21 +++++----- src/main/java/tf/tuff/ServerRegistry.java | 27 +++++-------- src/main/java/tf/tuff/TuffX.java | 6 ++- .../java/tf/tuff/listeners/BlockListener.java | 4 ++ .../tf/tuff/listeners/PlayerListener.java | 4 ++ .../restrictions/Restrictions.java | 6 ++- .../tuff/viablocks/CustomBlockListener.java | 33 +++++---------- src/main/java/tf/tuff/y0/ViaBlockIds.java | 38 +++++++----------- 9 files changed, 59 insertions(+), 80 deletions(-) delete mode 100644 gradle/gradle-wrapper-shared-8.5.jar diff --git a/gradle/gradle-wrapper-shared-8.5.jar b/gradle/gradle-wrapper-shared-8.5.jar deleted file mode 100644 index 54bc2d6ee93b1b998e1c542c31fc2d8643ee6b41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32944 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 q&Ofi6zouCKY()WU|CRgSCtOOhkT2IX5D doConnect(), 100L); - } + if (running) p.getServer().getScheduler().runTaskLaterAsynchronously(p, () -> doConnect(), 100L); } - @Override - public void onError(Exception e) { - } + public void onError(Exception e) {} }; client.setConnectionLostTimeout(30); client.connect(); } catch (Exception e) { - if (running) { - p.getServer().getScheduler().runTaskLaterAsynchronously(p, () -> doConnect(), 100L); - } + if (running) p.getServer().getScheduler().runTaskLaterAsynchronously(p, this::doConnect, 100L); } } public void disconnect() { running = false; - if (client != null) { - client.close(); - } + if (client != null) client.close(); } } diff --git a/src/main/java/tf/tuff/TuffX.java b/src/main/java/tf/tuff/TuffX.java index 79e21e2..86a35e6 100644 --- a/src/main/java/tf/tuff/TuffX.java +++ b/src/main/java/tf/tuff/TuffX.java @@ -23,6 +23,8 @@ import com.github.retrooper.packetevents.event.PacketListenerPriority; import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder; +import tf.tuff.listeners.BlockListener; +import tf.tuff.listeners.PlayerListener; import tf.tuff.netty.ChunkInjector; import tf.tuff.tuffactions.TuffActions; import tf.tuff.viablocks.ViaBlocksPlugin; @@ -75,8 +77,8 @@ public void onEnable() { new NetworkListener(this), PacketListenerPriority.NORMAL ); - getServer().getPluginManager().registerEvents(this, this); - + Bukkit.getPluginManager().registerEvents(new BlockListener(), this); + Bukkit.getPluginManager().registerEvents(new PlayerListener(), this); setupRegistry(); lfe(); } diff --git a/src/main/java/tf/tuff/listeners/BlockListener.java b/src/main/java/tf/tuff/listeners/BlockListener.java index b820d62..f9c90a6 100644 --- a/src/main/java/tf/tuff/listeners/BlockListener.java +++ b/src/main/java/tf/tuff/listeners/BlockListener.java @@ -7,6 +7,10 @@ public class BlockListener extends ListenerBase implements Listener { + public BlockListener() { + super(); + } + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onBlockForm(BlockFormEvent e) { viaBlocksPlugin.blockListener.handleBlockForm(e); diff --git a/src/main/java/tf/tuff/listeners/PlayerListener.java b/src/main/java/tf/tuff/listeners/PlayerListener.java index bac9095..c6cba48 100644 --- a/src/main/java/tf/tuff/listeners/PlayerListener.java +++ b/src/main/java/tf/tuff/listeners/PlayerListener.java @@ -14,6 +14,10 @@ public class PlayerListener extends ListenerBase implements Listener { + public PlayerListener() { + super(); + } + @EventHandler(priority = EventPriority.MONITOR) public void onPlayerChangeWorld(PlayerChangedWorldEvent e) { y0Plugin.handlePlayerChangeWorld(e); diff --git a/src/main/java/tf/tuff/tuffactions/restrictions/Restrictions.java b/src/main/java/tf/tuff/tuffactions/restrictions/Restrictions.java index 4b2ead5..65cb68c 100644 --- a/src/main/java/tf/tuff/tuffactions/restrictions/Restrictions.java +++ b/src/main/java/tf/tuff/tuffactions/restrictions/Restrictions.java @@ -34,6 +34,7 @@ public Restrictions(TuffActions plugin) { private void validateConfig() { boolean configUpdated = false; + if (!plugin.plugin.getConfig().contains("restrictions.enabled", true)) { plugin.plugin.getConfig().set("restrictions.enabled", false); configUpdated = true; @@ -90,11 +91,12 @@ public void sendSingleUpdateToAll(String key) { private void handleSingleUpdate(Player player, String key) { if (!TuffActions.restrictionsEnabled) return; plugin.info("Sending restriction update for '%s' to %s".formatted(key, player.getName())); - try (ByteArrayOutputStream bout = new ByteArrayOutputStream(); DataOutputStream out = new DataOutputStream(bout)) { + try (ByteArrayOutputStream bout = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bout) + ) { out.writeUTF("client_feature"); out.writeUTF(key); out.writeBoolean(!disallowed.contains(key)); - plugin.sendPluginMessage(player, bout.toByteArray()); } catch (IOException e) { plugin.log(Level.WARNING, "Failed to send Restriction "+key+" to " + player.getName(), e); diff --git a/src/main/java/tf/tuff/viablocks/CustomBlockListener.java b/src/main/java/tf/tuff/viablocks/CustomBlockListener.java index 2ac645a..21c8348 100644 --- a/src/main/java/tf/tuff/viablocks/CustomBlockListener.java +++ b/src/main/java/tf/tuff/viablocks/CustomBlockListener.java @@ -14,6 +14,7 @@ import java.util.function.Consumer; import javax.annotation.Nonnull; +import lombok.Setter; import org.bukkit.Chunk; import org.bukkit.ChunkSnapshot; import org.bukkit.Location; @@ -41,6 +42,7 @@ public class CustomBlockListener { private final VersionAdapter versionAdapter; private final PaletteManager paletteManager; private final EnumSet modernMaterials; + @Setter private tf.tuff.netty.ChunkInjector chunkInjector; private static final Map worldMinHeights = new ConcurrentHashMap<>(); private static final long X_MASK = (1L << 26) - 1L; @@ -82,10 +84,6 @@ public byte[] getCachedChunkData(String worldName, int x, int z) { return chunkPacketCache.getIfPresent(chunkKey(worldName, x, z)); } - public void setChunkInjector(tf.tuff.netty.ChunkInjector injector) { - this.chunkInjector = injector; - } - private @Nonnull String chunkKey(String worldName, int x, int z) { return worldName + "_" + x + "_" + z; } @@ -201,7 +199,7 @@ public void prepareChunkCache(Chunk chunk) { } else { chunkPacketCache.put(key, buildChunkPacket(foundBlocks)); } - } catch (Exception e) {} + } catch (Exception ignored) {} }); } @@ -284,11 +282,7 @@ private Map> findModernBlocksInChunk(ChunkSnapshot chunkSnap if (materialId != -1) { long packedLocation = packLocation(chunkX + x, y, chunkZ + z); - List locs = foundBlocks.get(materialId); - if (locs == null) { - locs = new ArrayList<>(); - foundBlocks.put(materialId, locs); - } + List locs = foundBlocks.computeIfAbsent(materialId, k -> new ArrayList<>()); locs.add(packedLocation); } } @@ -303,11 +297,7 @@ public byte[] getExtraDataForMultiBlock(World world, List locations) { for (long packedLoc : locations) { Integer cachedId = recentModernChanges.getIfPresent(packedLoc); if (cachedId != null) { - List locs = foundBlocks.get(cachedId); - if (locs == null) { - locs = new ArrayList<>(); - foundBlocks.put(cachedId, locs); - } + List locs = foundBlocks.computeIfAbsent(cachedId, k -> new ArrayList<>()); locs.add(packedLoc); continue; } @@ -324,11 +314,7 @@ public byte[] getExtraDataForMultiBlock(World world, List locations) { if (isModernMaterial(data.getMaterial())) { int id = getMaterialId(data); if (id != -1) { - List locs2 = foundBlocks.get(id); - if (locs2 == null) { - locs2 = new ArrayList<>(); - foundBlocks.put(id, locs2); - } + List locs2 = foundBlocks.computeIfAbsent(id, k -> new ArrayList<>()); locs2.add(packedLoc); } } @@ -382,8 +368,7 @@ public void handleBlockBreak(BlockBreakEvent event) { handleModernBlockChange(data, Material.AIR.createBlockData(), loc); - if (data instanceof Door) { - Door door = (Door) data; + if (data instanceof Door door) { Location otherHalf = door.getHalf() == Bisected.Half.BOTTOM ? loc.clone().add(0, 1, 0) : loc.clone().add(0, -1, 0); @@ -614,7 +599,7 @@ private void runSyncLater(Runnable task, long delay) { if (!plugin.plugin.isEnabled()) return; try { plugin.plugin.getServer().getScheduler().runTaskLater(plugin.plugin, task, delay); - } catch (Exception e) {} + } catch (Exception ignored) {} } private int getMinHeight(World world) { @@ -625,7 +610,7 @@ private int getMinHeight(World world) { if (value instanceof Integer) { return (Integer) value; } - } catch (Exception e) {} + } catch (Exception ignored) {} return 0; }); } diff --git a/src/main/java/tf/tuff/y0/ViaBlockIds.java b/src/main/java/tf/tuff/y0/ViaBlockIds.java index c3e2a9c..4312649 100644 --- a/src/main/java/tf/tuff/y0/ViaBlockIds.java +++ b/src/main/java/tf/tuff/y0/ViaBlockIds.java @@ -31,7 +31,7 @@ public class ViaBlockIds { public ViaBlockIds(TuffX pl) { p = pl; - plugin = pl.y0Plugin; + plugin = pl.getY0Plugin(); serverVersion = getServerMCVersion(); mappingsFile = new File(pl.getDataFolder(), serverVersion + "-mappings.json"); @@ -49,7 +49,7 @@ private void initializeMappings() { if (!mappingsFile.exists()) { plugin.info("Mapping file not found, generating..."); if (!p.getDataFolder().exists()) { - p.getDataFolder().mkdirs(); + if (p.getDataFolder().mkdirs()) plugin.info("Generated plugin data folder."); } generateMappings(mappingsFile); } else { @@ -160,22 +160,12 @@ private void generateMappings(File f) { String k = s.get(i).replace("minecraft:", ""); String blockName = k.contains("[") ? k.substring(0, k.indexOf("[")) : k; - int[] legacy; - - switch (blockName) { - case "chest": - legacy = new int[]{54, 0}; - break; - case "ender_chest": - legacy = new int[]{130, 0}; - break; - case "trapped_chest": - legacy = new int[]{146, 0}; - break; - default: - legacy = ctl(i); - break; - } + int[] legacy = switch (blockName) { + case "chest" -> new int[]{54, 0}; + case "ender_chest" -> new int[]{130, 0}; + case "trapped_chest" -> new int[]{146, 0}; + default -> ctl(i); + }; nlm.put(k, legacy); } @@ -259,17 +249,17 @@ public int[] ctl(int mbsi) { ProtocolPathEntry e = protoPath.get(i); Protocol pr = e.protocol(); - if (pr instanceof BackwardsProtocol) { - BackwardsMappingData md = ((BackwardsProtocol) pr).getMappingData(); + if (pr instanceof BackwardsProtocol backwardsProtocol) { + BackwardsMappingData md = backwardsProtocol.getMappingData(); if (md != null && md.getBlockStateMappings() != null) { int ni = md.getBlockStateMappings().getNewId(csi); - if (ni != -1) csi = ni; } } } - int bi = csi >> 4; - int mt = csi & 0xF; - return new int[]{bi, mt}; + return new int[] { + csi >> 4, + csi & 0xF + }; } } \ No newline at end of file From 5886d450663d3803d1c23b647b28ebf339841468 Mon Sep 17 00:00:00 2001 From: TurboMaxe Date: Sun, 19 Apr 2026 09:41:57 +0500 Subject: [PATCH 3/7] fix: build tooling and listeners --- build.gradle.kts | 22 +++++++++++++++++++--- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 0823990..9b7185b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,9 +19,24 @@ repositories { maven("https://repo.codemc.io/repository/maven-snapshots/") maven("https://jitpack.io") maven("https://repo.dmulloy2.net/repository/public/") + maven("https://repo.codemc.io/repository/maven-releases/") } dependencies { + paperweight.paperDevBundle("1.21.8-R0.1-SNAPSHOT") + + /* + implementation("com.github.retrooper:packetevents-spigot:2.11.1") + compileOnly("com.viaversion:viabackwards:5.3.2") + compileOnly("com.viaversion:viaversion:5.4.1") + compileOnly("it.unimi.dsi:fastutil:8.5.16") + implementation("com.fasterxml.jackson.core:jackson-databind:2.15.2") + compileOnly("io.netty:netty-all:4.1.97.Final") + implementation("org.java-websocket:Java-WebSocket:1.5.4") + compileOnly("org.projectlombok:lombok:1.18.30") + annotationProcessor("org.projectlombok:lombok:1.18.30") + */ + implementation(libs.packetevents.spigot) compileOnly(libs.viabackwards) compileOnly(libs.viaversion) @@ -31,19 +46,20 @@ dependencies { implementation(libs.java.websocket) compileOnly(libs.lombok) - annotationProcessor(libs.lombok) + annotationProcessor(libs.lombok) } java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } tasks { withType().configureEach { options.encoding = "UTF-8" + } processResources { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c61a118..37f78a6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From a91404bd627e4ea73ef868a204d65f974f3ec028 Mon Sep 17 00:00:00 2001 From: TurboMaxe Date: Sun, 19 Apr 2026 10:56:59 +0500 Subject: [PATCH 4/7] update: logic in tuffx for plugin messages, tested tuffactions --- .idea/codeStyles/codeStyleConfig.xml | 5 ++ .idea/jarRepositories.xml | 70 +++++++++++++++++++ .../{libs.version.toml => libs.versions.toml} | 2 + src/main/java/tf/tuff/TuffX.java | 56 ++++++--------- src/main/java/tf/tuff/netty/BaseInjector.java | 3 +- .../java/tf/tuff/tuffactions/TuffActions.java | 1 - .../tuffactions/creative/CreativeMenu.java | 11 +-- 7 files changed, 107 insertions(+), 41 deletions(-) create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/jarRepositories.xml rename gradle/{libs.version.toml => libs.versions.toml} (99%) diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..8a911c2 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gradle/libs.version.toml b/gradle/libs.versions.toml similarity index 99% rename from gradle/libs.version.toml rename to gradle/libs.versions.toml index af18bab..e6503f4 100644 --- a/gradle/libs.version.toml +++ b/gradle/libs.versions.toml @@ -1,4 +1,5 @@ [versions] + packetevents = "2.11.1" viabackwards = "5.3.2" viaversion = "5.4.1" @@ -9,6 +10,7 @@ websocket = "1.5.4" lombok = "1.18.30" [libraries] + packetevents-spigot = { module = "com.github.retrooper:packetevents-spigot", version.ref = "packetevents" } viabackwards = { module = "com.viaversion:viabackwards", version.ref = "viabackwards" } viaversion = { module = "com.viaversion:viaversion", version.ref = "viaversion" } diff --git a/src/main/java/tf/tuff/TuffX.java b/src/main/java/tf/tuff/TuffX.java index 86a35e6..9626148 100644 --- a/src/main/java/tf/tuff/TuffX.java +++ b/src/main/java/tf/tuff/TuffX.java @@ -1,28 +1,16 @@ package tf.tuff; +import com.github.retrooper.packetevents.PacketEvents; +import com.github.retrooper.packetevents.event.PacketListenerPriority; +import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.*; -import org.bukkit.event.entity.EntityToggleGlideEvent; -import org.bukkit.event.entity.EntityToggleSwimEvent; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.player.PlayerChangedWorldEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.messaging.PluginMessageListener; - -import com.github.retrooper.packetevents.PacketEvents; -import com.github.retrooper.packetevents.event.PacketListenerPriority; - -import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder; +import org.jetbrains.annotations.NotNull; import tf.tuff.listeners.BlockListener; import tf.tuff.listeners.PlayerListener; import tf.tuff.netty.ChunkInjector; @@ -33,7 +21,7 @@ import java.util.List; -public class TuffX extends JavaPlugin implements PluginMessageListener { +public final class TuffX extends JavaPlugin implements PluginMessageListener { private ServerRegistry serverRegistry; @Getter private static TuffX instance; @@ -55,7 +43,7 @@ public void onLoad() { PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this)); PacketEvents.getAPI().getSettings().reEncodeByDefault(false) - .checkForUpdates(false); + .checkForUpdates(false); PacketEvents.getAPI().load(); } @@ -109,6 +97,20 @@ public void onDisable() { PacketEvents.getAPI().terminate(); } + @Override + public void onPluginMessageReceived(@NotNull String channel, Player player, byte[] message) { + if (!player.isOnline()) return; + + switch (channel) { + case "eagler:below_y0" -> y0Plugin.handlePacket(player, message); + case "viablocks:handshake" -> viaBlocksPlugin.handlePacket(player, message); + case "eagler:tuffactions" -> tuffActions.handlePacket(player, message); + case "entities:handshake" -> viaEntitiesPlugin.handlePacket(player, message); + default -> + getLogger().warning("Received plugin message on unknown channel '%s' from %s".formatted(channel, player.getName())); + } + } + public void reloadTuffX(){ reloadConfig(); saveDefaultConfig(); @@ -119,22 +121,19 @@ public void reloadTuffX(){ } setupRegistry(); - viaBlocksPlugin.onTuffXReload(); y0Plugin.onTuffXReload(); tuffActions.onTuffXReload(); viaEntitiesPlugin.onTuffXReload(); - getLogger().info("TuffX reloaded."); } public boolean TuffXCommand(CommandSender sender, Command command, String label, String[] args){ if (args.length > 0) { if (args[0].equalsIgnoreCase("reload")) { - if (!(sender instanceof Player)) { + if (!(sender instanceof Player player)) { reloadTuffX(); } else { - Player player = (Player) sender; if (!player.hasPermission("tuffx.reload")) { player.sendMessage("§cYou do not have permission to use this command."); return false; @@ -148,24 +147,13 @@ public boolean TuffXCommand(CommandSender sender, Command command, String label, } @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + public boolean onCommand(@NotNull CommandSender sender, Command command, @NotNull String label, String @NotNull [] args) { if (command.getName().equalsIgnoreCase("tuffx")) return TuffXCommand(sender, command, label, args); if (command.getName().equalsIgnoreCase("viablocks")) return viaBlocksPlugin.onTuffXCommand(sender, command, label, args); if (command.getName().equalsIgnoreCase("restrictions")) return tuffActions.onTuffXCommand(sender, command, label, args); return true; } - @Override - public void onPluginMessageReceived(String channel, Player player, byte[] message) { - if (!player.isOnline()) return; - - if (channel.equals("eagler:below_y0")) y0Plugin.handlePacket(player,message); - else if (channel.equals("viablocks:handshake")) viaBlocksPlugin.handlePacket(player,message); - else if (channel.equals("eagler:tuffactions")) tuffActions.handlePacket(player,message); - else if (channel.equals("entities:handshake")) viaEntitiesPlugin.handlePacket(player,message); - else getLogger().warning("Received plugin message on unknown channel '%s' from %s".formatted(channel, player.getName())); - } - private void lfe() { List.of( "████████╗██╗ ██╗███████╗ ███████╗ ██╗ ██╗", diff --git a/src/main/java/tf/tuff/netty/BaseInjector.java b/src/main/java/tf/tuff/netty/BaseInjector.java index fbc7b08..e933929 100644 --- a/src/main/java/tf/tuff/netty/BaseInjector.java +++ b/src/main/java/tf/tuff/netty/BaseInjector.java @@ -5,7 +5,6 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; import java.util.UUID; @@ -43,7 +42,7 @@ public void inject(Player player) { targetHandler = anchor; break; } - } + } ChannelHandler handler = createHandler(player); if (targetHandler != null) { diff --git a/src/main/java/tf/tuff/tuffactions/TuffActions.java b/src/main/java/tf/tuff/tuffactions/TuffActions.java index f50b083..e285574 100644 --- a/src/main/java/tf/tuff/tuffactions/TuffActions.java +++ b/src/main/java/tf/tuff/tuffactions/TuffActions.java @@ -99,7 +99,6 @@ public void handlePacket(Player player, byte[] message) { tuffPlayers.add(player.getUniqueId()); - // This may or may not work - turbo switch (action.toLowerCase()) { case "swimming_state": if (swimmingEnabled) { diff --git a/src/main/java/tf/tuff/tuffactions/creative/CreativeMenu.java b/src/main/java/tf/tuff/tuffactions/creative/CreativeMenu.java index c9c6652..0ab0ade 100644 --- a/src/main/java/tf/tuff/tuffactions/creative/CreativeMenu.java +++ b/src/main/java/tf/tuff/tuffactions/creative/CreativeMenu.java @@ -1,23 +1,26 @@ package tf.tuff.tuffactions.creative; -import tf.tuff.tuffactions.TuffActions; - import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryAction; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; +import tf.tuff.tuffactions.TuffActions; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; -import java.util.*; +import java.util.Arrays; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; public class CreativeMenu { - private final TuffActions plugin; + private final TuffActions plugin; private final Set itemMapping = ConcurrentHashMap.newKeySet(); private final Map playerHoldingPlaceholder = new ConcurrentHashMap<>(); From bdf30d6f865917525205a3810411e47e76c9d19b Mon Sep 17 00:00:00 2001 From: TurboMaxe Date: Sun, 19 Apr 2026 11:44:11 +0500 Subject: [PATCH 5/7] update: main class plugin msg logic & actions switch block --- .../java/tf/tuff/tuffactions/TuffActions.java | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/main/java/tf/tuff/tuffactions/TuffActions.java b/src/main/java/tf/tuff/tuffactions/TuffActions.java index e285574..23a5a40 100644 --- a/src/main/java/tf/tuff/tuffactions/TuffActions.java +++ b/src/main/java/tf/tuff/tuffactions/TuffActions.java @@ -100,27 +100,29 @@ public void handlePacket(Player player, byte[] message) { tuffPlayers.add(player.getUniqueId()); switch (action.toLowerCase()) { - case "swimming_state": + case "swimming_state" -> { if (swimmingEnabled) { swimmingManager.handleSwimState(player, in.readBoolean()); break; } - case "elytra_state": + } + case "elytra_state" -> { if (swimmingEnabled) { swimmingManager.handleElytraState(player, in.readBoolean()); break; } - case "creative-ready": + } + case "creative-ready" -> { if (creativeEnabled) { creativeManager.handleCreativeReady(player); - break; } - case "swim_ready": - if (swimmingEnabled) { - swimmingManager.handleSwimReady(player); - break; + } + case "swim_ready" -> { + if (swimmingEnabled) { + swimmingManager.handleSwimReady(player); + } } - case "give_creative_item": + case "give_creative_item" -> { if (creativeEnabled) { if (player.getGameMode() != GameMode.CREATIVE) return; int itemLength = in.readUnsignedByte(); @@ -132,9 +134,9 @@ public void handlePacket(Player player, byte[] message) { String item = new String(itemBytes, StandardCharsets.UTF_8); int amount = in.readInt(); creativeManager.handlePlaceholderTaken(player, item, amount); - break; } - case "pick_viablock": + } + case "pick_viablock" -> { if (creativeEnabled) { if (player.getGameMode() != GameMode.CREATIVE) return; int blockLength = in.readUnsignedByte(); @@ -144,10 +146,10 @@ public void handlePacket(Player player, byte[] message) { String blockName = new String(blockBytes, StandardCharsets.UTF_8); int hotbarSlot = in.readUnsignedByte(); creativeManager.handlePickViablock(player, blockName, hotbarSlot); - break; } - case "restrictions_ready": - restrictions.handleRestrictionsReady(player); + } + case "restrictions_ready" -> + restrictions.handleRestrictionsReady(player); } } catch (IOException e) { @@ -176,15 +178,11 @@ public void handlePlayerQuit(PlayerQuitEvent event) { } public void handleToggleSwim(EntityToggleSwimEvent event) { - if (swimmingEnabled) { - swimmingManager.handleToggleSwim(event); - } + if (swimmingEnabled) swimmingManager.handleToggleSwim(event); } public void handleToggleGlide(EntityToggleGlideEvent event) { - if (swimmingEnabled) { - swimmingManager.handleToggleGlide(event); - } + if (swimmingEnabled) swimmingManager.handleToggleGlide(event); } public void handlePlayerInventoryClick(InventoryClickEvent event) { From f955362d578f105dfec0a73e2ff3414029b6cfa4 Mon Sep 17 00:00:00 2001 From: TurboMaxe Date: Sun, 19 Apr 2026 22:55:30 +0500 Subject: [PATCH 6/7] refactor: some collecting logic --- .gitignore | 3 +- build.gradle.kts | 16 +--- src/main/java/tf/tuff/netty/BaseInjector.java | 2 +- .../tuffactions/creative/CreativeMenu.java | 7 +- .../tf/tuff/tuffactions/creative/TabUtil.java | 23 +++--- .../restrictions/Restrictions.java | 15 ++-- .../restrictions/RestrictionsCommand.java | 18 ++--- .../tuff/viablocks/CustomBlockListener.java | 79 +++++++++---------- .../tf/tuff/viablocks/PaletteManager.java | 31 +++----- .../version/modern/ModernAdapter.java | 4 +- .../tuff/viaentities/EntityDataHandler.java | 75 +++++++++--------- 11 files changed, 122 insertions(+), 151 deletions(-) diff --git a/.gitignore b/.gitignore index e1425cb..4938411 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build/ .gradle/ -bin/ \ No newline at end of file +bin/ +.idea/ \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 9b7185b..5f29b14 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,18 +25,6 @@ repositories { dependencies { paperweight.paperDevBundle("1.21.8-R0.1-SNAPSHOT") - /* - implementation("com.github.retrooper:packetevents-spigot:2.11.1") - compileOnly("com.viaversion:viabackwards:5.3.2") - compileOnly("com.viaversion:viaversion:5.4.1") - compileOnly("it.unimi.dsi:fastutil:8.5.16") - implementation("com.fasterxml.jackson.core:jackson-databind:2.15.2") - compileOnly("io.netty:netty-all:4.1.97.Final") - implementation("org.java-websocket:Java-WebSocket:1.5.4") - compileOnly("org.projectlombok:lombok:1.18.30") - annotationProcessor("org.projectlombok:lombok:1.18.30") - */ - implementation(libs.packetevents.spigot) compileOnly(libs.viabackwards) compileOnly(libs.viaversion) @@ -56,10 +44,8 @@ java { } tasks { - withType().configureEach { options.encoding = "UTF-8" - } processResources { @@ -71,7 +57,7 @@ tasks { } } - withType { + named("shadowJar") { archiveClassifier.set("") archiveFileName.set("${project.name}-${project.version}.jar") diff --git a/src/main/java/tf/tuff/netty/BaseInjector.java b/src/main/java/tf/tuff/netty/BaseInjector.java index e933929..dc77096 100644 --- a/src/main/java/tf/tuff/netty/BaseInjector.java +++ b/src/main/java/tf/tuff/netty/BaseInjector.java @@ -23,7 +23,7 @@ protected void onPostInject(Player player) { public void inject(Player player) { UUID uuid = player.getUniqueId(); - var viaConnection = Via.getAPI().getConnection(uuid); + UserConnection viaConnection = Via.getAPI().getConnection(uuid); if (viaConnection == null) return; Channel channel = viaConnection.getChannel(); diff --git a/src/main/java/tf/tuff/tuffactions/creative/CreativeMenu.java b/src/main/java/tf/tuff/tuffactions/creative/CreativeMenu.java index 0ab0ade..af74561 100644 --- a/src/main/java/tf/tuff/tuffactions/creative/CreativeMenu.java +++ b/src/main/java/tf/tuff/tuffactions/creative/CreativeMenu.java @@ -68,10 +68,7 @@ public void handlePickViablock(Player player, String blockName, int hotbarSlot) if (material == null || !material.isItem()) { return; } - if (hotbarSlot < 0 || hotbarSlot > 8) { - hotbarSlot = 0; - } - player.getInventory().setItem(hotbarSlot, new ItemStack(material, 1)); + player.getInventory().setItem(hotbarSlot > 8 || hotbarSlot < 0 ? 0 : hotbarSlot, new ItemStack(material, 1)); } public void onPlayerInventoryClick(InventoryClickEvent event) { @@ -82,7 +79,7 @@ public void onPlayerInventoryClick(InventoryClickEvent event) { InventoryAction action = event.getAction(); if (action == InventoryAction.PLACE_ALL || action == InventoryAction.PLACE_ONE || action == InventoryAction.SWAP_WITH_CURSOR) { - Bukkit.getScheduler().runTaskLater(this.plugin.plugin, () -> { + Bukkit.getScheduler().runTaskLater(this.plugin.getPlugin(), () -> { ItemStack realItemStack = playerHoldingPlaceholder.get(playerUUID); if (realItemStack != null && event.getClickedInventory() != null) { diff --git a/src/main/java/tf/tuff/tuffactions/creative/TabUtil.java b/src/main/java/tf/tuff/tuffactions/creative/TabUtil.java index 5b45c7d..c6ff551 100644 --- a/src/main/java/tf/tuff/tuffactions/creative/TabUtil.java +++ b/src/main/java/tf/tuff/tuffactions/creative/TabUtil.java @@ -1,17 +1,16 @@ package tf.tuff.tuffactions.creative; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.jetbrains.annotations.NotNull; +import tf.tuff.tuffactions.TuffActions; + +import javax.annotation.Nullable; import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.Map; import java.util.logging.Level; -import javax.annotation.Nullable; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; - -import org.jetbrains.annotations.NotNull; -import tf.tuff.tuffactions.TuffActions; public class TabUtil { private final TuffActions plugin; @@ -33,15 +32,13 @@ private void setupMappingFile() { } private void loadMapping() { + + ObjectMapper mapper = new ObjectMapper(); + TypeReference> typeRef = new TypeReference<>() {}; + try { - ObjectMapper mapper = new ObjectMapper(); - - TypeReference> typeRef = new TypeReference<>() { - }; - this.creativeTabMap = mapper.readValue(mappingFile, typeRef); plugin.info("Successfully loaded " + creativeTabMap.size() + " creative tab mappings."); - } catch (IOException e) { plugin.log(Level.SEVERE, "Failed to load creative tab mapping from file!", e); this.creativeTabMap = Collections.emptyMap(); diff --git a/src/main/java/tf/tuff/tuffactions/restrictions/Restrictions.java b/src/main/java/tf/tuff/tuffactions/restrictions/Restrictions.java index 65cb68c..f482fdb 100644 --- a/src/main/java/tf/tuff/tuffactions/restrictions/Restrictions.java +++ b/src/main/java/tf/tuff/tuffactions/restrictions/Restrictions.java @@ -1,5 +1,11 @@ package tf.tuff.tuffactions.restrictions; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import tf.tuff.tuffactions.TuffActions; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -9,13 +15,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; -import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import tf.tuff.tuffactions.TuffActions; - public class Restrictions { private final TuffActions plugin; private RestrictionsCommand commandHandler; @@ -47,7 +46,7 @@ private void validateConfig() { plugin.plugin.saveConfig(); plugin.info("Restrictions config updated"); } - } + } public void loadConfig() { disallowed.clear(); if (!TuffActions.restrictionsEnabled) return; diff --git a/src/main/java/tf/tuff/tuffactions/restrictions/RestrictionsCommand.java b/src/main/java/tf/tuff/tuffactions/restrictions/RestrictionsCommand.java index efe082d..9fb05c0 100644 --- a/src/main/java/tf/tuff/tuffactions/restrictions/RestrictionsCommand.java +++ b/src/main/java/tf/tuff/tuffactions/restrictions/RestrictionsCommand.java @@ -1,13 +1,12 @@ package tf.tuff.tuffactions.restrictions; -import java.util.List; -import java.util.logging.Level; - import org.bukkit.command.Command; import org.bukkit.command.CommandSender; - import tf.tuff.TuffX; +import java.util.List; +import java.util.logging.Level; + public class RestrictionsCommand { private final TuffX tuffx; private final Restrictions restrictions; @@ -54,16 +53,17 @@ public boolean onCommand(CommandSender sender, Command command, String label, St } else if (args[0].equalsIgnoreCase("allow")) { if (!sender.hasPermission("tuffx.restrictions.command.allow")) return noPermission(sender); if (args.length < 2) return invalidUsage(sender, "Module name required."); + List config = null; try { - @SuppressWarnings("unchecked") - List config = (List)tuffx.getConfig().getList("restrictions.disallow"); - if (!config.contains(args[1])) return error(sender, "Module '%s' not in disallow list. No change.".formatted(args[1])); - config.remove(args[1]); + + config = (List) tuffx.getConfig().getList("restrictions.disallow"); + if (config != null && !config.contains(args[1])) return error(sender, "Module '%s' not in disallow list. No change.".formatted(args[1])); + if (config != null) config.remove(args[1]); tuffx.getConfig().set("restrictions.disallow", config); tuffx.saveConfig(); restrictions.loadConfig(); restrictions.sendSingleUpdateToAll(args[1]); - } catch(Exception e) { + } catch (Exception e) { return unknownError(sender, e); } sender.sendMessage("\u00A7aModule '%s' removed from disallow list.".formatted(args[1])); diff --git a/src/main/java/tf/tuff/viablocks/CustomBlockListener.java b/src/main/java/tf/tuff/viablocks/CustomBlockListener.java index 21c8348..32ef7ca 100644 --- a/src/main/java/tf/tuff/viablocks/CustomBlockListener.java +++ b/src/main/java/tf/tuff/viablocks/CustomBlockListener.java @@ -1,19 +1,9 @@ package tf.tuff.viablocks; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; -import javax.annotation.Nonnull; - +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; import lombok.Setter; import org.bukkit.Chunk; import org.bukkit.ChunkSnapshot; @@ -21,21 +11,38 @@ import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; -import org.bukkit.block.data.type.Door; import org.bukkit.block.data.Bisected; import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.Door; import org.bukkit.entity.Player; -import org.bukkit.event.block.*; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockExplodeEvent; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockGrowEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.BlockSpreadEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.world.ChunkLoadEvent; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.io.ByteArrayDataOutput; -import com.google.common.io.ByteStreams; - import tf.tuff.viablocks.version.VersionAdapter; +import javax.annotation.Nonnull; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + public class CustomBlockListener { public final ViaBlocksPlugin plugin; @@ -140,7 +147,7 @@ private void sendInitialChunks(Player player) { } } - chunks.sort((a, b) -> Integer.compare(a[2], b[2])); + chunks.sort(Comparator.comparingInt(a -> a[2])); sendChunksBatched(player, world.getName(), chunks, 0); } @@ -511,16 +518,8 @@ private void invalidateChunkCache(Chunk chunk) { private void sendPacket(Player player, int stateId, Location location) { if (!player.isOnline()) return; UUID playerId = player.getUniqueId(); - Map> updateData = pendingUpdates.get(playerId); - if (updateData == null) { - updateData = new HashMap<>(); - pendingUpdates.put(playerId, updateData); - } - List stateList = updateData.get(stateId); - if (stateList == null) { - stateList = new ArrayList<>(); - updateData.put(stateId, stateList); - } + Map> updateData = pendingUpdates.computeIfAbsent(playerId, k -> new HashMap<>()); + List stateList = updateData.computeIfAbsent(stateId, k -> new ArrayList<>()); stateList.add(packLocation(location)); if (pendingFlush.add(playerId)) { runSyncLater(() -> flushPendingUpdates(playerId), plugin.getUpdateBatchDelayTicks()); @@ -540,7 +539,6 @@ private void flushPendingUpdates(UUID playerId) { } private int getMaterialId(BlockData data) { - @SuppressWarnings("null") Integer cachedId = blockDataIdCache.getIfPresent(data); if (cachedId != null) return cachedId; @@ -551,14 +549,12 @@ private int getMaterialId(BlockData data) { private byte[] buildChunkPacket(Map> blockData) { ByteArrayDataOutput out = ByteStreams.newDataOutput(); - out.writeUTF("ADD_CHUNK"); + out.writeUTF("ADD_CHUNK"); out.writeInt(blockData.size()); for (Map.Entry> entry : blockData.entrySet()) { out.writeInt(entry.getKey()); out.writeInt(entry.getValue().size()); - for (Long loc : entry.getValue()) { - out.writeLong(loc); - } + entry.getValue().forEach(out::writeLong); } return out.toByteArray(); } @@ -568,9 +564,7 @@ public void sendPaletteToClient(Player player) { out.writeUTF("INIT_PALETTE"); List palette = this.paletteManager.getPalette(); out.writeInt(palette.size()); - for (String state : palette) { - out.writeUTF(state); - } + palette.forEach(out::writeUTF); player.sendPluginMessage(plugin.plugin, ViaBlocksPlugin.CLIENTBOUND_CHANNEL, out.toByteArray()); } @@ -579,7 +573,8 @@ public boolean isModernMaterial(Material material) { } public void processChunkForSinglePlayer(Chunk chunk, Player player) { - if (!chunk.isLoaded() || !plugin.isPlayerEnabled(player)) return; + if (!chunk.isLoaded() || + !plugin.isPlayerEnabled(player)) return; prepareChunkCache(chunk); byte[] data = getExtraDataForChunk(chunk.getWorld().getName(), chunk.getX(), chunk.getZ()); if (data != null && data.length > 0) { diff --git a/src/main/java/tf/tuff/viablocks/PaletteManager.java b/src/main/java/tf/tuff/viablocks/PaletteManager.java index 2e56d0f..26e4c7b 100644 --- a/src/main/java/tf/tuff/viablocks/PaletteManager.java +++ b/src/main/java/tf/tuff/viablocks/PaletteManager.java @@ -1,20 +1,17 @@ package tf.tuff.viablocks; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import tf.tuff.viablocks.version.VersionAdapter; + import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Player; - -import com.google.common.io.ByteArrayDataOutput; -import com.google.common.io.ByteStreams; - -import tf.tuff.viablocks.version.VersionAdapter; - public class PaletteManager { ViaBlocksPlugin plugin; @@ -32,7 +29,9 @@ private void generate(VersionAdapter versionAdapter) { plugin.info("Generating ViaBlocks Pre-Defined Palette..."); List initialPalette = new ArrayList<>(); - + versionAdapter.getModernMaterials().stream().filter(Material::isBlock).forEach( + mat -> addEntryInternal(initialPalette, versionAdapter.getMaterialKey(mat) + )); for (Material material : versionAdapter.getModernMaterials()) { if (material.isBlock()) { addEntryInternal(initialPalette, versionAdapter.getMaterialKey(material)); @@ -109,15 +108,12 @@ private void broadcastNewPaletteEntry(String state) { ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeUTF("NEW_PALETTE_ENTRY"); out.writeUTF(state); - byte[] data = out.toByteArray(); Bukkit.getScheduler().runTask(plugin.plugin, () -> { if (!plugin.plugin.isEnabled() || !plugin.isEnabled()) return; - for (Player player : Bukkit.getOnlinePlayers()) { - if (plugin.isPlayerEnabled(player)) { - player.sendPluginMessage(plugin.plugin, ViaBlocksPlugin.CLIENTBOUND_CHANNEL, data); - } - } + Bukkit.getOnlinePlayers().stream().filter(player -> plugin.isPlayerEnabled(player)).forEach( + player -> player.sendPluginMessage(plugin.plugin, ViaBlocksPlugin.CLIENTBOUND_CHANNEL, out.toByteArray()) + ); }); } @@ -128,8 +124,7 @@ public synchronized int getId(String state) { public synchronized List getPalette() { List snapshot = paletteSnapshot; if (snapshot == null) { - snapshot = new ArrayList<>(palette); - paletteSnapshot = snapshot; + paletteSnapshot = new ArrayList<>(palette); } return snapshot; } diff --git a/src/main/java/tf/tuff/viablocks/version/modern/ModernAdapter.java b/src/main/java/tf/tuff/viablocks/version/modern/ModernAdapter.java index f7c0acd..50d6ad6 100644 --- a/src/main/java/tf/tuff/viablocks/version/modern/ModernAdapter.java +++ b/src/main/java/tf/tuff/viablocks/version/modern/ModernAdapter.java @@ -644,8 +644,8 @@ public int getClientViewDistance(Player player) { if (clientViewDistanceMethod != null) { try { Object value = clientViewDistanceMethod.invoke(player); - if (value instanceof Integer) { - return (Integer) value; + if (value instanceof Integer integer) { + return integer; } } catch (Exception e) { return player.getServer().getViewDistance(); diff --git a/src/main/java/tf/tuff/viaentities/EntityDataHandler.java b/src/main/java/tf/tuff/viaentities/EntityDataHandler.java index b8f90d2..cd60797 100644 --- a/src/main/java/tf/tuff/viaentities/EntityDataHandler.java +++ b/src/main/java/tf/tuff/viaentities/EntityDataHandler.java @@ -1,12 +1,13 @@ package tf.tuff.viaentities; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import org.bukkit.entity.Player; -import com.google.common.io.ByteArrayDataOutput; -import com.google.common.io.ByteStreams; +import java.util.List; public class EntityDataHandler extends ChannelOutboundHandlerAdapter { @@ -20,6 +21,7 @@ public EntityDataHandler(ViaEntitiesPlugin plugin, Player player) { this.entityMappingManager = plugin.entityMappingManager; } + @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { String className = msg.getClass().getName(); @@ -66,7 +68,7 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) } } } - } catch (Exception e) { + } catch (Exception ignored) { } } @@ -80,21 +82,17 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) try { java.lang.reflect.Method getTypeMethod = msg.getClass().getMethod("getType"); java.lang.reflect.Method getIdMethod = msg.getClass().getMethod("getId"); - if (getTypeMethod != null && getIdMethod != null) { - Object typeResult = getTypeMethod.invoke(msg); - if (typeResult != null && typeResult.toString().contains("entity")) { - isSpawnPacket = true; - } + Object typeResult = getTypeMethod.invoke(msg); + if (typeResult != null && typeResult.toString().contains("entity")) { + isSpawnPacket = true; } - } catch (NoSuchMethodException e) { - } catch (Exception e) { - } + } catch (Exception ignored) {} } if (isSpawnPacket) { try { handleSpawnPacket(msg); - } catch (Exception e) { + } catch (Exception ignored) { } } else if (className.contains("EntityMetadata") || className.contains("SetEntityData") || simpleClassName.equals("PacketPlayOutEntityMetadata") || @@ -104,7 +102,7 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) if (entityId != -1) { sendEntityMetadata(entityId, null); } - } catch (Exception e) { + } catch (Exception ignored) { } } else if (className.contains("Animation") || simpleClassName.equals("PacketPlayOutAnimation") || @@ -115,14 +113,14 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) if (entityId != -1) { sendEntityAnimation(entityId, animationType); } - } catch (Exception e) { + } catch (Exception ignored) { } } else if (className.contains("EntityDestroy") || className.contains("RemoveEntities") || simpleClassName.equals("PacketPlayOutEntityDestroy") || simpleClassName.equals("ClientboundRemoveEntitiesPacket")) { try { handleDestroyPacket(msg); - } catch (Exception e) { + } catch (Exception ignored) { } } @@ -182,8 +180,7 @@ private void handleDestroyPacket(Object msg) throws Exception { for (java.lang.reflect.Field field : msg.getClass().getDeclaredFields()) { field.setAccessible(true); Object value = field.get(msg); - if (value instanceof it.unimi.dsi.fastutil.ints.IntList) { - it.unimi.dsi.fastutil.ints.IntList idList = (it.unimi.dsi.fastutil.ints.IntList) value; + if (value instanceof it.unimi.dsi.fastutil.ints.IntList idList) { for (int i = 0; i < idList.size(); i++) { sendEntityDestroy(idList.getInt(i)); } @@ -332,8 +329,7 @@ private void sendEntityMetadata(int entityId, Object packedItems) { out.writeUTF("ENTITY_METADATA"); out.writeInt(entityId); - if (packedItems instanceof java.util.List) { - java.util.List items = (java.util.List) packedItems; + if (packedItems instanceof List items) { out.writeInt(items.size()); for (Object item : items) { @@ -344,23 +340,28 @@ private void sendEntityMetadata(int entityId, Object packedItems) { java.lang.reflect.Method getValueMethod = item.getClass().getMethod("value"); Object value = getValueMethod.invoke(item); - if (value instanceof Boolean) { - out.writeByte(0); - out.writeBoolean((Boolean) value); - } else if (value instanceof Integer) { - out.writeByte(1); - out.writeInt((Integer) value); - } else if (value instanceof Float) { - out.writeByte(2); - out.writeFloat((Float) value); - } else if (value instanceof String) { - out.writeByte(3); - out.writeUTF((String) value); - } else if (value instanceof Byte) { - out.writeByte(4); - out.writeByte((Byte) value); - } else { - out.writeByte(-1); + switch (value) { + case Boolean b -> { + out.writeByte(0); + out.writeBoolean(b); + } + case Integer i -> { + out.writeByte(1); + out.writeInt(i); + } + case Float v -> { + out.writeByte(2); + out.writeFloat(v); + } + case String s -> { + out.writeByte(3); + out.writeUTF(s); + } + case Byte b -> { + out.writeByte(4); + out.writeByte(b); + } + case null, default -> out.writeByte(-1); } } } else { @@ -369,7 +370,7 @@ private void sendEntityMetadata(int entityId, Object packedItems) { byte[] data = out.toByteArray(); player.sendPluginMessage(plugin.plugin, ViaEntitiesPlugin.CLIENTBOUND_CHANNEL, data); - } catch (Exception e) { + } catch (Exception ignored) { } } From ff14b745761bcbd561345e7668267d07dea0278f Mon Sep 17 00:00:00 2001 From: TurboMaxe Date: Wed, 22 Apr 2026 15:30:07 +0500 Subject: [PATCH 7/7] update: remove redundant method --- src/main/java/tf/tuff/TuffX.java | 51 +++++++++++++------------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/src/main/java/tf/tuff/TuffX.java b/src/main/java/tf/tuff/TuffX.java index 9626148..9ed99c0 100644 --- a/src/main/java/tf/tuff/TuffX.java +++ b/src/main/java/tf/tuff/TuffX.java @@ -68,7 +68,27 @@ public void onEnable() { Bukkit.getPluginManager().registerEvents(new BlockListener(), this); Bukkit.getPluginManager().registerEvents(new PlayerListener(), this); setupRegistry(); - lfe(); + List.of( + "████████╗██╗ ██╗███████╗ ███████╗ ██╗ ██╗", + "╚══██╔══╝██║ ██║██╔════╝ ██╔════╝ ╚██╗██╔╝", + " ██║ ██║ ██║██████╗ ██████╗ ╚███╔╝ ", + " ██║ ██║ ██║██╔═══╝ ██╔═══╝ ██╔██╗ ", + " ██║ ╚██████╔╝██║ ██║ ██╔╝╚██╗", + " ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝", + "", + "CREDITS", + "Y0 support:", + "• Below y0 (client + plugin) programmed by Potato (@justatypicalpotato)", + "• llucasandersen - plugin optimizations", + "• ViaBlocks partial plugin and client rewrite by Potato", + "• llucasandersen (Complex client models and texture fixes,", + " optimizations, PacketEvents migration and async safety fixes)", + "• coleis1op, if ts is driving me crazy, im taking credit", + "• Swimming and creative items programmed by Potato (@justatypicalpotato)", + "• shaded build, 1.14+ support (before merge) - llucasandersen", + "• Restrictions - UplandJacob", + "• Overall plugin merges by Potato" + ).forEach(Bukkit.getConsoleSender()::sendMessage); } private void setupRegistry() { @@ -153,33 +173,4 @@ public boolean onCommand(@NotNull CommandSender sender, Command command, @NotNul if (command.getName().equalsIgnoreCase("restrictions")) return tuffActions.onTuffXCommand(sender, command, label, args); return true; } - - private void lfe() { - List.of( - "████████╗██╗ ██╗███████╗ ███████╗ ██╗ ██╗", - "╚══██╔══╝██║ ██║██╔════╝ ██╔════╝ ╚██╗██╔╝", - " ██║ ██║ ██║██████╗ ██████╗ ╚███╔╝ ", - " ██║ ██║ ██║██╔═══╝ ██╔═══╝ ██╔██╗ ", - " ██║ ╚██████╔╝██║ ██║ ██╔╝╚██╗", - " ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝", - "", - "CREDITS", - "", - "Y0 support:", - "• Below y0 (client + plugin) programmed by Potato (@justatypicalpotato)", - "• llucasandersen - plugin optimizations", - "", - "ViaBlocks:", - "• ViaBlocks partial plugin and client rewrite by Potato", - "• llucasandersen (Complex client models and texture fixes,", - " optimizations, PacketEvents migration and async safety fixes)", - "• coleis1op, if ts is driving me crazy, im taking credit", - "", - "Other:", - "• Swimming and creative items programmed by Potato (@justatypicalpotato)", - "• shaded build, 1.14+ support (before merge) - llucasandersen", - "• Restrictions - UplandJacob", - "• Overall plugin merges by Potato" - ).forEach(Bukkit.getConsoleSender()::sendMessage); - } }