0.3.1: drop ToastPacket — client-only imports broke server-side load
Build / build (push) Has been cancelled

ToastPacket imported net.minecraft.client.gui.components.toasts.* and
net.minecraft.client.Minecraft at class scope. When BnsNetwork.onRegister
Payloads referenced ToastPacket::handle on the dedicated server,
NoClassDefFoundError fired (the client-only classes don't exist on
the dedicated server side).

Toast feedback wasn't load-bearing — KubeJS already chat-prints the
result of every /bns verb. Players see "Sold 8x diamond for 60 spurs"
in the chat as before, and the screens re-render off the snapshot
the bridge pushes after each routed verb.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Matt
2026-06-07 02:41:13 +00:00
parent 10e9980bfd
commit 14dc69f22f
4 changed files with 4 additions and 66 deletions
+1 -1
View File
@@ -19,5 +19,5 @@ loader_version_range=[1,)
mod_id=bnstoolkit
mod_name=Brass and Sigil Toolkit
mod_license=All Rights Reserved
mod_version=0.3.0
mod_version=0.3.1
mod_group_id=uk.sijbers.bnstoolkit
@@ -10,7 +10,6 @@ import uk.sijbers.bnstoolkit.network.s2c.BountySnapshotPacket;
import uk.sijbers.bnstoolkit.network.s2c.PlotSnapshotPacket;
import uk.sijbers.bnstoolkit.network.s2c.SellSnapshotPacket;
import uk.sijbers.bnstoolkit.network.s2c.TierStateUpdatePacket;
import uk.sijbers.bnstoolkit.network.s2c.ToastPacket;
/**
* Central registration for the toolkit's S2C and C2S packets.
@@ -25,7 +24,9 @@ import uk.sijbers.bnstoolkit.network.s2c.ToastPacket;
* - {@link BountySnapshotPacket} — daily pool + active + completed + cap
* - {@link PlotSnapshotPacket} — owners + cap + my owned ids
*
* Plus a fire-and-forget {@link ToastPacket} for command result UX.
* Player-visible feedback for routed verbs comes through the KubeJS
* chat messages that the /bns commands already emit — no separate
* toast channel needed.
*/
public final class BnsNetwork {
private BnsNetwork() {}
@@ -64,10 +65,6 @@ public final class BnsNetwork {
PlotSnapshotPacket.TYPE,
PlotSnapshotPacket.STREAM_CODEC,
PlotSnapshotPacket::handle);
reg.playToClient(
ToastPacket.TYPE,
ToastPacket.STREAM_CODEC,
ToastPacket::handle);
BnsToolkit.LOG.info("[bnstoolkit/net] registered payloads v{}", VERSION);
}
@@ -16,7 +16,6 @@ import uk.sijbers.bnstoolkit.network.s2c.BountySnapshotPacket;
import uk.sijbers.bnstoolkit.network.s2c.PlotSnapshotPacket;
import uk.sijbers.bnstoolkit.network.s2c.SellSnapshotPacket;
import uk.sijbers.bnstoolkit.network.s2c.TierStateUpdatePacket;
import uk.sijbers.bnstoolkit.network.s2c.ToastPacket;
import java.util.ArrayList;
import java.util.HashMap;
@@ -196,10 +195,6 @@ public final class ServerEconomyBridge {
PacketDistributor.sendToPlayer(sp, new PlotSnapshotPacket(owners, slotCap, ownedIds));
}
public static void toast(ServerPlayer sp, int status, String title, String body) {
PacketDistributor.sendToPlayer(sp, new ToastPacket(status, title, body));
}
// Defensive: bounties pool format uses the same shape we know about
@SuppressWarnings("unused")
private static Bounty resolveBounty(String id) { return Bounty.byId(id); }
@@ -1,54 +0,0 @@
package uk.sijbers.bnstoolkit.network.s2c;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.toasts.SystemToast;
import net.minecraft.network.chat.Component;
import uk.sijbers.bnstoolkit.BnsToolkit;
/**
* S2C: short toast notification to the player.
*
* Used by the server-side bridge to report results of routed /bns
* commands the player triggered from a screen (e.g. "Upgrade succeeded",
* "Insufficient funds", "Bounty turned in: +800 spurs").
*
* Status codes: 0=info, 1=success, 2=failure. The client maps these to
* SystemToast colour bands.
*/
public record ToastPacket(int status, String title, String body) implements CustomPacketPayload {
public static final Type<ToastPacket> TYPE = new Type<>(
ResourceLocation.fromNamespaceAndPath(BnsToolkit.MOD_ID, "toast"));
public static final StreamCodec<RegistryFriendlyByteBuf, ToastPacket> STREAM_CODEC =
StreamCodec.composite(
ByteBufCodecs.VAR_INT, ToastPacket::status,
ByteBufCodecs.STRING_UTF8, ToastPacket::title,
ByteBufCodecs.STRING_UTF8, ToastPacket::body,
ToastPacket::new);
@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
public static void handle(ToastPacket pkt, IPayloadContext ctx) {
ctx.enqueueWork(() -> {
Minecraft mc = Minecraft.getInstance();
if (mc == null) return;
SystemToast.SystemToastId id = switch (pkt.status) {
case 1 -> SystemToast.SystemToastId.PERIODIC_NOTIFICATION;
case 2 -> SystemToast.SystemToastId.PACK_LOAD_FAILURE;
default -> SystemToast.SystemToastId.NARRATOR_TOGGLE;
};
mc.getToasts().addToast(SystemToast.multiline(mc, id,
Component.literal(pkt.title),
Component.literal(pkt.body)));
});
}
}