-
Notifications
You must be signed in to change notification settings - Fork 1
Shading VGui
Shading embeds VGui inside another Velocity plugin. Use it only when a shared standalone installation is unsuitable.
A shaded integration must:
- include VGui and its required runtime classes;
- relocate
me.agent.vguito avoid collisions; - decide how PacketEvents is supplied;
- call
VGuiBootstrap.loadPacketEventsfrom the plugin constructor; - call
VGuiBootstrap.initduringProxyInitializeEvent; - call
shutdownduringProxyShutdownEvent; - avoid also depending on the standalone
vguiplugin unless the copies are deliberately isolated.
Use normal compile scope when shading:
<dependency>
<groupId>com.github.AgentNoobff</groupId>
<artifactId>VGUI</artifactId>
<version>main-SNAPSHOT</version>
</dependency>Pin a release tag for production.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>YOUR_CURRENT_VERSION</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>me.agent.vgui</pattern>
<shadedPattern>your.plugin.libs.vgui</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>Select the current stable Shade plugin release in your own build. The placeholder avoids copying a stale plugin version from documentation.
private final boolean managePacketEvents;
@Inject
public MyPlugin(
ProxyServer server,
PluginContainer container,
Logger logger,
@DataDirectory Path dataDirectory
) {
this.server = server;
this.logger = logger;
this.managePacketEvents = VGuiBootstrap.loadPacketEvents(
server,
container,
logger,
dataDirectory.resolve("packetevents")
);
}The constructor timing matters because PacketEvents must load before proxy initialization.
private VGuiBootstrap vgui;
@Subscribe
public void onInitialize(ProxyInitializeEvent event) {
vgui = VGuiBootstrap.init(server, this, logger, managePacketEvents);
}
@Subscribe
public void onShutdown(ProxyShutdownEvent event) {
if (vgui != null) {
vgui.shutdown();
}
}Pass the result of loadPacketEvents to init. It records whether this integration owns the PacketEvents lifecycle.
The published VGui artifact already contains the PacketEvents API, Velocity adapter,
and common runtime modules, so shading it as-is also embeds those classes. Do not add a
second copy. If an integration deliberately filters them out to use another provider,
it must make the compatible classes visible before VGuiBootstrap loads.
Relocating PacketEvents is a separate design decision. A relocated copy cannot share the ordinary singleton with other plugins, and relocation also changes PacketEvents types present in VGui's public signatures. Test ownership, linkage, and class loading carefully.
When shading VGui, exclude its velocity-plugin.json from the final jar so Velocity sees only your plugin descriptor. Configure the shade resource filters accordingly:
<filters>
<filter>
<artifact>com.github.AgentNoobff:VGUI</artifact>
<excludes>
<exclude>velocity-plugin.json</exclude>
</excludes>
</filter>
</filters>JitPack may expose resolved coordinates differently inside the local dependency graph. Inspect mvn dependency:tree and the final jar to confirm the filter matches.
- exactly one
velocity-plugin.jsonexists; - VGui classes appear only under the relocated package;
- the dependent plugin loads on a clean Velocity proxy;
- PacketEvents initializes once;
- shutdown removes sessions and listeners;
- no standalone VGui jar is needed;
- a backend switch closes the old menu with
OVERRIDDEN, and menus reopen cleanly afterward.
Shaded deployment has more failure modes than the standalone plugin. Prefer standalone unless self-containment is a real requirement.
- View Types and Builders
- Layouts and Slots
- Items and Skulls
- Click Handling
- Contents and Updates
- Context and State
- Navigation
- Pagination
- Anvil Input
- Lifecycle and Listeners
- API Reference