### Install and Restart ZenithProxy Plugin Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt To install the plugin, copy the built JAR file into the `plugins/` directory of your ZenithProxy installation. After placing the JAR, restart ZenithProxy for the plugin to be loaded. Hot reloading of plugins is not supported. ```bash # Place plugin jar in plugins/ folder next to ZenithProxy launcher cp build/libs/ZenithProxyExamplePlugin-1.0.0.jar /path/to/zenith/plugins/ # Restart ZenithProxy to load plugins # Hot reloading is not supported ``` -------------------------------- ### Gradle Build Configuration for ZenithProxy Plugin Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt This Kotlin script configures the Gradle build for a ZenithProxy plugin. It utilizes the 'zenithproxy.plugin.dev' Gradle plugin for simplified setup, defines Java toolchain versions, specifies Maven repositories for dependencies, and includes ZenithProxy as a core dependency. Optional dependency shading is also commented out. ```kotlin plugins { id("zenithproxy.plugin.dev") version "1.0.0-SNAPSHOT" } group = properties["maven_group"] as String version = properties["plugin_version"] as String val mc = properties["mc"] as String java { toolchain { languageVersion = JavaLanguageVersion.of(25) } } zenithProxyPlugin { templateProperties = mapOf( "version" to project.version ) javaReleaseVersion = JavaLanguageVersion.of(21) } repositories { maven("https://maven.2b2t.vc/releases") { description = "ZenithProxy Releases and Dependencies" } maven("https://maven.2b2t.vc/remote") { description = "Dependencies used by ZenithProxy" } } dependencies { zenithProxy("com.zenith:ZenithProxy:$mc-SNAPSHOT") // Optional: include dependencies into plugin jar // shade("com.github.ben-manes.caffeine:caffeine:3.2.0") } tasks { shadowJar { // Optional: relocate shaded dependencies to avoid conflicts // val basePackage = "${project.group}.shadow" // relocate("com.github.benmanes.caffeine", "$basePackage.caffeine") // Optional: remove unneeded transitive dependencies // dependencies { // exclude(dependency(":error_prone_annotations:.*")) // exclude(dependency(":jspecify:.*")) // } } } ``` -------------------------------- ### Interact with ZenithProxy Plugin via In-Game Commands Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt Plugins can expose commands for in-game interaction. Examples include displaying module status, toggling modules on/off, configuring parameters like delay and radius, and enabling visual effects like entity ESP. ```console # Display module status examplePlugin # Toggle module on/off examplePlugin on examplePlugin off # Configure delay examplePlugin delay 500 # Enable wandering with custom radius wander on wander radius 5000 wander minRadius 200 # Enable entity ESP effect esp on esp off ``` -------------------------------- ### Register ZenithProxy Plugin Components Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt Main plugin class implementing ZenithProxyPlugin, responsible for loading and registering all plugin components such as configuration, modules, and commands. It uses annotations to define plugin metadata and receives a PluginAPI instance for registration. ```java package org.example; import com.zenith.plugin.api.Plugin; import com.zenith.plugin.api.PluginAPI; import com.zenith.plugin.api.ZenithProxyPlugin; import net.kyori.adventure.text.logger.slf4j.ComponentLogger; @Plugin( id = "example-plugin", version = BuildConstants.VERSION, description = "ZenithProxy Example Plugin", url = "https://github.com/rfresh2/ZenithProxyExamplePlugin", authors = {"rfresh2"}, mcVersions = {"1.21.4"} // or use "*" for any version ) public class ExamplePlugin implements ZenithProxyPlugin { public static ExampleConfig PLUGIN_CONFIG; public static ComponentLogger LOG; @Override public void onLoad(PluginAPI pluginAPI) { LOG = pluginAPI.getLogger(); LOG.info("Example Plugin loading..."); // Register config first so modules/commands can access it PLUGIN_CONFIG = pluginAPI.registerConfig("example-plugin", ExampleConfig.class); // Register modules pluginAPI.registerModule(new ExampleModule()); pluginAPI.registerModule(new ExampleESPModule()); pluginAPI.registerModule(new ExampleWanderModule()); // Register commands pluginAPI.registerCommand(new ExampleCommand()); pluginAPI.registerCommand(new ExampleESPCommand()); pluginAPI.registerCommand(new ExampleWanderCommand()); LOG.info("Example Plugin loaded!"); } } ``` -------------------------------- ### Build, Run, and Check ZenithProxy Plugin with Gradle Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt Standard Gradle tasks for plugin development: `build` compiles and packages the plugin into a JAR file. `run` launches ZenithProxy with the plugin loaded for testing. `check` performs static analysis and type checking without full compilation. ```bash # Build plugin jar ./gradlew build # Output: build/libs/ZenithProxyExamplePlugin-1.0.0.jar # Run ZenithProxy with plugin loaded for testing ./gradlew run # Creates run/ directory with test environment # Type checking without compilation ./gradlew check ``` -------------------------------- ### Implement ZenithProxy Event-Driven Module Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt A simple event-driven module for ZenithProxy that extends the base Module class. It registers consumers for game events, such as `ClientBotTick`, and uses a Timer for delayed actions, with its enabled state controlled by configuration. ```java package org.example.module; import com.github.rfresh2.EventConsumer; import com.zenith.event.client.ClientBotTick; import com.zenith.module.api.Module; import com.zenith.util.timer.Timer; import com.zenith.util.timer.Timers; import org.example.ExamplePlugin; import java.util.List; import static com.github.rfresh2.EventConsumer.of; public class ExampleModule extends Module { final Timer timer = Timers.tickTimer(); @Override public boolean enabledSetting() { return ExamplePlugin.PLUGIN_CONFIG.exampleModule.enabled; } @Override public List> registerEvents() { return List.of( of(ClientBotTick.class, this::handleBotTick) ); } private void handleBotTick(ClientBotTick event) { if (timer.tick(ExamplePlugin.PLUGIN_CONFIG.exampleModule.delayTicks)) { info("Hello from ExampleModule!"); } } } ``` -------------------------------- ### Configure Plugin Properties with Gradle Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt Plugin metadata and build configurations are managed in the `gradle.properties` file. This file allows for easy customization of version, name, Minecraft version compatibility, Maven group, and Gradle daemon settings. ```properties plugin_version=1.0.0 plugin_name=ZenithProxyExamplePlugin mc=1.21.4 maven_group=org.example org.gradle.configuration-cache=true org.gradle.parallel=true org.gradle.caching=true ``` -------------------------------- ### Implement ESP Module for Entity Highlighting (Java) Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt This Java code defines an ESP module that intercepts `ClientboundSetEntityDataPacket` to add glowing effects to entities. It modifies entity metadata by setting the 'glowing' bit. Dependencies include the Zenith API and Minecraft protocol library. ```java package org.example.module; import com.zenith.module.api.Module; import com.zenith.network.codec.PacketHandler; import com.zenith.network.codec.PacketHandlerCodec; import com.zenith.network.codec.PacketHandlerStateCodec; import com.zenith.network.server.ServerSession; import org.example.ExamplePlugin; import org.geysermc.mcprotocollib.protocol.data.ProtocolState; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataTypes; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityDataPacket; import java.util.ArrayList; public class ExampleESPModule extends Module { @Override public boolean enabledSetting() { return ExamplePlugin.PLUGIN_CONFIG.esp; } @Override public PacketHandlerCodec registerServerPacketHandlerCodec() { return PacketHandlerCodec.serverBuilder() .setId("esp") .setPriority(1000) .state(ProtocolState.GAME, PacketHandlerStateCodec.serverBuilder() .inbound(ClientboundSetEntityDataPacket.class, new GlowingEntityMetadataPacketHandler()) .build()) .build(); } public static class GlowingEntityMetadataPacketHandler implements PacketHandler { @Override public ClientboundSetEntityDataPacket apply(final ClientboundSetEntityDataPacket packet, final ServerSession session) { var metadata = packet.getMetadata(); for (int i = 0; i < metadata.size(); i++) { final EntityMetadata entityMetadata = metadata.get(i); // https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Entity_metadata#Entity if (entityMetadata.getId() == 0 && entityMetadata instanceof ByteEntityMetadata byteMetadata) { // Found the metadata id we want to edit - set glowing bit (0x40) var newMetadata = new ByteEntityMetadata(0, MetadataTypes.BYTE, (byte) (byteMetadata.getPrimitiveValue() | 0x40)); var newMetadataList = new ArrayList<>(metadata); newMetadataList.set(i, newMetadata); return packet.withMetadata(newMetadataList); } } // Metadata id wasn't present, add it var newMetadata = new ArrayList<>(packet.getMetadata()); newMetadata.addFirst(new ByteEntityMetadata(0, MetadataTypes.BYTE, (byte) 0x40)); return packet.withMetadata(newMetadata); } } } ``` -------------------------------- ### Define ZenithProxy Plugin Configuration Structure Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt Configuration POJO for the ZenithProxy plugin, using public mutable fields to enable JSON serialization. Nested static classes define nested JSON structures for organizing settings like ESP and wander module configurations. ```java package org.example; public class ExampleConfig { public boolean esp = false; public final ExampleModuleConfig exampleModule = new ExampleModuleConfig(); public static class ExampleModuleConfig { public boolean enabled = true; public int delayTicks = 250; } public final ExampleWanderConfig wander = new ExampleWanderConfig(); public static final class ExampleWanderConfig { public boolean enabled = false; public int radius = 2000; public int minRadius = 100; } } ``` -------------------------------- ### Java Baritone Pathfinding for Bot Wandering Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt This Java module utilizes Baritone to enable a bot to wander within a defined radius. It calculates random destinations, sets a pathfinding goal using Baritone, and includes timers to detect and warn if the bot appears stuck. Dependencies include Zenith and Baritone APIs. ```java package org.example.module; import com.github.rfresh2.EventConsumer; import com.zenith.event.client.ClientBotTick; import com.zenith.feature.pathfinder.goals.GoalXZ; import com.zenith.module.api.Module; import com.zenith.util.math.MathHelper; import com.zenith.util.timer.Timer; import com.zenith.util.timer.Timers; import java.util.List; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import static com.github.rfresh2.EventConsumer.of; import static com.zenith.Globals.BARITONE; import static com.zenith.Globals.CACHE; import static org.example.ExamplePlugin.PLUGIN_CONFIG; public class ExampleWanderModule extends Module { private final Timer pathTimer = Timers.tickTimer(); private long lastPathTime = 0L; private long lastStuckWarning = 0L; public GoalXZ goal = new GoalXZ(0, 0); @Override public List> registerEvents() { return List.of( of(ClientBotTick.class, this::handleBotTick), of(ClientBotTick.Starting.class, this::handleBotTickStarting) ); } @Override public boolean enabledSetting() { return PLUGIN_CONFIG.wander.enabled; } @Override public void onDisable() { if (BARITONE.isGoalActive(goal)) { debug("Stopping active pathing goal"); BARITONE.stop(); } lastPathTime = 0L; lastStuckWarning = 0L; } private void handleBotTickStarting(ClientBotTick.Starting event) { lastPathTime = 0L; lastStuckWarning = 0L; } private void handleBotTick(ClientBotTick event) { if (!BARITONE.isActive() && pathTimer.tick(20L)) { if (System.currentTimeMillis() - lastPathTime < TimeUnit.MINUTES.toMillis(1)) { if (System.currentTimeMillis() - lastStuckWarning > TimeUnit.MINUTES.toMillis(5)) { warn("we are likely stuck :("); lastStuckWarning = System.currentTimeMillis(); } return; } int currentX = MathHelper.floorI(CACHE.getPlayerCache().getX()); int currentZ = MathHelper.floorI(CACHE.getPlayerCache().getZ()); int radius = PLUGIN_CONFIG.wander.radius; int minRadius = PLUGIN_CONFIG.wander.minRadius; int bound = radius - minRadius; int goalX = ThreadLocalRandom.current().nextInt(currentX - bound, currentX + bound); goalX += goalX < currentX ? -minRadius : minRadius; int goalZ = ThreadLocalRandom.current().nextInt(currentZ - bound, currentZ + bound); goalZ += goalZ < currentZ ? -minRadius : minRadius; goal = new GoalXZ(goalX, goalZ); info("Pathing to goal: [{}, {}]", goalX, goalZ); BARITONE.pathTo(goal).addExecutedListener(f -> { info("Reached wander goal! [{}, {}]", goal.x(), goal.z()); pathTimer.skip(); }); lastPathTime = System.currentTimeMillis(); } } } ``` -------------------------------- ### Implement Advanced Wander Command with Validation in Java Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt This Java code defines the 'wander' command for the ZenithProxyExamplePlugin. It includes validation for radius and minRadius parameters, error handling for invalid inputs, and toggling functionality for the associated module. Dependencies include Zenith command API classes and Mojang Brigadier arguments. ```java package org.example.command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.zenith.command.api.Command; import com.zenith.command.api.CommandCategory; import com.zenith.command.api.CommandContext; import com.zenith.command.api.CommandUsage; import com.zenith.discord.Embed; import org.example.module.ExampleWanderModule; import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger; import static com.mojang.brigadier.arguments.IntegerArgumentType.integer; import static com.zenith.Globals.MODULE; import static com.zenith.command.brigadier.ToggleArgumentType.getToggle; import static com.zenith.command.brigadier.ToggleArgumentType.toggle; import static org.example.ExamplePlugin.PLUGIN_CONFIG; public class ExampleWanderCommand extends Command { @Override public CommandUsage commandUsage() { return CommandUsage.builder() .name("wander") .category(CommandCategory.MODULE) .description("Randomly moves the player around in the world") .usageLines( "on/off", "radius ", "minRadius " ) .build(); } @Override public LiteralArgumentBuilder register() { return command("wander") .then(argument("toggle", toggle()).executes(c -> { PLUGIN_CONFIG.wander.enabled = getToggle(c, "toggle"); c.getSource().getEmbed() .title("Wander " + toggleStrCaps(PLUGIN_CONFIG.wander.enabled)); MODULE.get(ExampleWanderModule.class).syncEnabledFromConfig(); })) .then(literal("radius").then(argument("blocks", integer(1)).executes(c -> { int radius = getInteger(c, "blocks"); if (radius < PLUGIN_CONFIG.wander.minRadius) { c.getSource().getEmbed() .title("Error") .description("Radius must be greater than minRadius"); return ERROR; } PLUGIN_CONFIG.wander.radius = radius; c.getSource().getEmbed() .title("Radius Set"); return OK; }))) .then(literal("minRadius").then(argument("blocks", integer(1)).executes(c -> { int radius = getInteger(c, "blocks"); if (radius > PLUGIN_CONFIG.wander.radius) { c.getSource().getEmbed() .title("Error") .description("Min Radius must be less than radius"); return ERROR; } PLUGIN_CONFIG.wander.minRadius = radius; c.getSource().getEmbed() .title("Min Radius Set"); return OK; }))); } @Override public void defaultEmbed(Embed embed) { embed .addField("Wander", toggleStr(PLUGIN_CONFIG.wander.enabled)) .addField("Radius", PLUGIN_CONFIG.wander.radius) .addField("Min Radius", PLUGIN_CONFIG.wander.minRadius) .primaryColor(); } } ``` -------------------------------- ### Java Brigadier Command for ZenithProxy Plugin Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt This Java code defines a basic command for the ZenithProxy plugin using Mojang's Brigadier library. It handles argument parsing for a toggle (on/off) and an integer delay, updating plugin configuration and returning Discord embeds as responses. Dependencies include Brigadier and the Zenith command API. ```java package org.example.command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.zenith.command.api.Command; import com.zenith.command.api.CommandCategory; import com.zenith.command.api.CommandContext; import com.zenith.command.api.CommandUsage; import com.zenith.discord.Embed; import org.example.module.ExampleModule; import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger; import static com.mojang.brigadier.arguments.IntegerArgumentType.integer; import static com.zenith.Globals.MODULE; import static com.zenith.command.brigadier.ToggleArgumentType.getToggle; import static com.zenith.command.brigadier.ToggleArgumentType.toggle; import static org.example.ExamplePlugin.PLUGIN_CONFIG; public class ExampleCommand extends Command { @Override public CommandUsage commandUsage() { return CommandUsage.builder() .name("examplePlugin") .category(CommandCategory.MODULE) .description("Example plugin command") .usageLines( "on/off", "delay " ) .build(); } @Override public LiteralArgumentBuilder register() { return command("examplePlugin") .then(argument("toggle", toggle()).executes(c -> { PLUGIN_CONFIG.exampleModule.enabled = getToggle(c, "toggle"); MODULE.get(ExampleModule.class).syncEnabledFromConfig(); c.getSource().getEmbed() .title("Example Plugin " + toggleStrCaps(PLUGIN_CONFIG.exampleModule.enabled)); })) .then(literal("delay").then(argument("ticks", integer(0)).executes(c -> { PLUGIN_CONFIG.exampleModule.delayTicks = getInteger(c, "ticks"); c.getSource().getEmbed() .title("Delay Set"); }))); } @Override public void defaultEmbed(Embed embed) { embed .primaryColor() .addField("Enabled", toggleStr(PLUGIN_CONFIG.exampleModule.enabled)) .addField("Delay", PLUGIN_CONFIG.exampleModule.delayTicks + " ticks"); } } ``` -------------------------------- ### Java Command for Entity Cache Interaction and Packet Sending Source: https://context7.com/rfresh2/zenithproxyexampleplugin/llms.txt This Java command allows toggling an ESP effect for entities. It interacts with ZenithProxy's entity cache to retrieve entity metadata and sends updated packets to connected clients. Dependencies include ZenithProxy command API and GeyserMC protocol library. ```java package org.example.command; import com.google.common.collect.Lists; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.zenith.Proxy; import com.zenith.command.api.Command; import com.zenith.command.api.CommandCategory; import com.zenith.command.api.CommandContext; import com.zenith.command.api.CommandUsage; import org.example.ExamplePlugin; import org.example.module.ExampleESPModule; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataTypes; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityDataPacket; import static com.zenith.Globals.CACHE; import static com.zenith.Globals.MODULE; import static com.zenith.command.brigadier.ToggleArgumentType.getToggle; import static com.zenith.command.brigadier.ToggleArgumentType.toggle; public class ExampleESPCommand extends Command { @Override public CommandUsage commandUsage() { return CommandUsage.builder() .name("esp") .category(CommandCategory.MODULE) .description("Renders the spectral effect around all entities") .usageLines("on/off") .build(); } @Override public LiteralArgumentBuilder register() { return command("esp") .then(argument("toggle", toggle()).executes(c -> { ExamplePlugin.PLUGIN_CONFIG.esp = getToggle(c, "toggle"); MODULE.get(ExampleESPModule.class).syncEnabledFromConfig(); // Get all active sessions (controlling player + spectators) var sessions = Proxy.getInstance().getActiveConnections().getArray(); if (sessions.length > 0) { // Resend entity metadata for every cached entity // If module is enabled, packet handler modifies packets to add glowing // Otherwise, this resyncs original metadata (removes effect) CACHE.getEntityCache().getEntities().values().forEach(e -> { EntityMetadata toSend; toSend = e.getMetadata().get(0); if (toSend == null) toSend = new ByteEntityMetadata(0, MetadataTypes.BYTE, (byte) 0); for (int i = 0; i < sessions.length; i++) { sessions[i].sendAsync(new ClientboundSetEntityDataPacket(e.getEntityId(), Lists.newArrayList(toSend))); } }); } c.getSource().getEmbed() .title("ESP " + toggleStrCaps(ExamplePlugin.PLUGIN_CONFIG.esp)) .primaryColor(); })); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.