Skip to content

VonixGuardian — Developer API & Architecture

Candidate Line: 3.0.0-m1 Developer SpecificationsCurrent Dev/Test

VonixGuardian is architected around a pure-Java engine decoupled from Minecraft internal classes, surrounded by thin loader-specific event bridges.

┌─────────────────────────────────────────────────────────────┐
│ Third-Party Mods │
│ (Soft-dep via Reflection or PreLogEvent) │
└──────────────────────────────┬──────────────────────────────┘
┌──────────────────────────────▼──────────────────────────────┐
│ mc-<ver>/{fabric, forge, neoforge} Loader Glue │
│ (Event handlers, Mixins, WorldMutator, OpLevelFallback) │
└──────────────────────────────┬──────────────────────────────┘
┌──────────────────────────────▼──────────────────────────────┐
│ mc-<ver>/common Module │
│ (Mojmap command tree, NBT codecs, EntitySentinel) │
└──────────────────────────────┬──────────────────────────────┘
┌──────────────────────────────▼──────────────────────────────┐
│ core/ Pure-Java Engine │
│ (JDBC DAO, Ring-buffer Queue, QueryParser, Rollback) │
│ *Zero Minecraft or Loader Dependencies* │
└─────────────────────────────────────────────────────────────┘
  • core/: Pure-Java engine containing the JDBC connection manager, ring-buffer queue, audit logger, filter parser, and rollback mathematics. Contains zero Minecraft imports.
  • mc-<ver>/common/: Minecraft-specific code shared across all loaders for a given MC version. Uses official Mojang mappings (Mojmap).
  • mc-<ver>/{loader}/: Thin glue modules (~30–50 LOC per loader) that register loader event hooks and mixins.

Integrations interact through the public API package: network.vonix.guardian.core.api.

  • network.vonix.guardian.core.Guardian — Primary runtime singleton. Implements EventSubmitter and exposes the GuardianDao.
  • network.vonix.guardian.core.api.VonixGuardianAPI — Helper interface offering typed convenience lookups:
    • hasPlaced(world, x, y, z, timeWindow)
    • hasRemoved(world, x, y, z, timeWindow)
    • queueLookup(filter, callback)
    • logPlacement(player, blockState, world, x, y, z)
    • logRemoval(player, blockState, world, x, y, z)
    • logChat(player, message)
    • logCommand(player, commandString)

Query results are returned as strongly-typed result records:

  • BlockLookupResult
  • ContainerLookupResult
  • ItemLookupResult
  • InventoryLookupResult
  • SessionLookupResult
  • UsernameLookupResult
  • MessageLookupResult
  • SignLookupResult

To avoid creating a hard crash when VonixGuardian is not installed on a user’s server, interact via reflection:

package com.example.mymod.compat;
import java.lang.reflect.Method;
import java.util.UUID;
public final class GuardianCompat {
private static final boolean AVAILABLE;
private static Object GUARDIAN_INSTANCE;
private static Method SUBMIT_KILL_METHOD;
static {
boolean ok = false;
try {
// Check loader accessor (Fabric example)
Class<?> loaderCls = Class.forName("network.vonix.guardian.fabric.VonixGuardianFabric");
GUARDIAN_INSTANCE = loaderCls.getMethod("guardian").invoke(null);
if (GUARDIAN_INSTANCE != null) {
Class<?> submitterCls = Class.forName("network.vonix.guardian.core.event.EventSubmitter");
SUBMIT_KILL_METHOD = submitterCls.getMethod("submitEntityKill",
UUID.class, String.class, String.class,
int.class, int.class, int.class, String.class, String.class);
ok = true;
}
} catch (Throwable ignored) {
// VonixGuardian not installed or still booting
}
AVAILABLE = ok;
}
public static boolean isAvailable() {
return AVAILABLE;
}
public static void logCustomKill(UUID killer, String killerName, String world, int x, int y, int z, String victim, String tag) {
if (!AVAILABLE) return;
try {
SUBMIT_KILL_METHOD.invoke(GUARDIAN_INSTANCE, killer, killerName, world, x, y, z, victim, tag);
} catch (Throwable t) {
// Never allow an audit failure to interrupt game logic
}
}
}

Third-party mods can intercept, modify, or cancel audit actions before they are enqueued into the writer pipeline.

  • Fabric: Subscribed via PreLogCallback.EVENT.register((action) -> { ... }).
  • Forge / NeoForge: Standard @SubscribeEvent listener on PreLogEvent.
// Example: Cancel logging for a custom mini-game arena
@SubscribeEvent
public void onPreLog(PreLogEvent event) {
if (event.getAction().getWorldKey().equals("minigame:spleef_arena")) {
event.setCanceled(true); // Action dropped before reaching queue
}
}

When an entity causes damage or modifies blocks, the loader’s AttributionResolver walks this hierarchy to extract the true responsible player UUID:

  1. Direct Player: Source entity is already a ServerPlayer.
  2. Controlling Passenger: Inspects entity.getControllingPassenger(). Blames the player riding a dragon, horse, or vehicle.
  3. TamableAnimal Owner: Inspects animal.getOwnerUUID(). Catches modded tamed creatures.
  4. OwnableEntity Owner: Broad vanilla interface implemented by custom projectiles and summons.
  5. Projectile Shooter: Recursively walks projectile.getOwner() until a living source is found.
  6. Recent Interactor: Inspects the entity’s latest interaction cache.

The originating entity ID is stored in source_tag (e.g. #mob:dragonmounts:fire_dragon), while the discovered player UUID is stored in actor_uuid.