From dfc940d2d4ce4fa0c570e4d3977bff726e64991b Mon Sep 17 00:00:00 2001 From: LiukRast Date: Mon, 24 Nov 2025 15:44:02 +0100 Subject: [PATCH 1/2] Fixed bidirectional packet on neoforge --- .../igoodie/twitchspawn/TwitchSpawn.java | 6 +- .../twitchspawn/client/TwitchSpawnClient.java | 4 +- .../client/screens/TwitchAuthScreen.java | 4 +- .../command/TwitchSpawnCommand.java | 4 +- .../packet/SyncStreamerDataPacket.java | 65 +++++++++++++------ 5 files changed, 53 insertions(+), 30 deletions(-) diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java index 126e4e2..762348b 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java @@ -86,8 +86,8 @@ public static void init() }); NetworkManager.registerReceiver(NetworkManager.Side.C2S, - SyncStreamerDataPacket.ID, - SyncStreamerDataPacket.STREAM_CODEC, + SyncStreamerDataPacket.C2S.ID, + SyncStreamerDataPacket.C2S.STREAM_CODEC, SyncStreamerDataPacket::handle); try @@ -112,7 +112,7 @@ public static void initServer() NetworkManager.registerS2CPayloadType(GlobalChatCooldownPacket.ID, GlobalChatCooldownPacket.STREAM_CODEC); NetworkManager.registerS2CPayloadType(OsRunPacket.ID, OsRunPacket.STREAM_CODEC); NetworkManager.registerS2CPayloadType(StatusChangedPacket.ID, StatusChangedPacket.STREAM_CODEC); - NetworkManager.registerS2CPayloadType(SyncStreamerDataPacket.ID, SyncStreamerDataPacket.STREAM_CODEC); + NetworkManager.registerS2CPayloadType(SyncStreamerDataPacket.S2C.ID, SyncStreamerDataPacket.S2C.STREAM_CODEC); // Do stuff on player joining the server. PlayerEvent.PLAYER_JOIN.register(player -> diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/client/TwitchSpawnClient.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/TwitchSpawnClient.java index 4e4ca7d..d42439e 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/client/TwitchSpawnClient.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/TwitchSpawnClient.java @@ -58,8 +58,8 @@ public static void init() StatusChangedPacket::handle); NetworkManager.registerReceiver(NetworkManager.Side.S2C, - SyncStreamerDataPacket.ID, - SyncStreamerDataPacket.STREAM_CODEC, + SyncStreamerDataPacket.S2C.ID, + SyncStreamerDataPacket.S2C.STREAM_CODEC, SyncStreamerDataPacket::handle); } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/client/screens/TwitchAuthScreen.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/screens/TwitchAuthScreen.java index addcf13..db431a7 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/client/screens/TwitchAuthScreen.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/screens/TwitchAuthScreen.java @@ -192,7 +192,7 @@ private void disconnect() } }); - NetworkManager.sendToServer(new SyncStreamerDataPacket( + NetworkManager.sendToServer(new SyncStreamerDataPacket.C2S( Minecraft.getInstance().player.getName().getString(), "", "", @@ -365,7 +365,7 @@ private void startPolling() private void saveTokensAndEvents(String accessToken, String refreshToken, List selectedEvents) { // send token to server - NetworkManager.sendToServer(new SyncStreamerDataPacket( + NetworkManager.sendToServer(new SyncStreamerDataPacket.C2S( Minecraft.getInstance().player.getName().getString(), accessToken, refreshToken, diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java index 740f9de..0c08122 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java @@ -99,11 +99,11 @@ public static int authModule(CommandContext context) filter(streamer -> streamer.minecraftNick.equalsIgnoreCase(player.getName().getString())). findAny(). map(streamer -> - new SyncStreamerDataPacket(player.getName().getString(), + new SyncStreamerDataPacket.S2C(player.getName().getString(), streamer.twitchAccessToken, streamer.twitchRefreshToken, streamer.twitchScopes)). - orElse(new SyncStreamerDataPacket(player.getName().getString(), + orElse(new SyncStreamerDataPacket.S2C(player.getName().getString(), "", "", "")); diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/SyncStreamerDataPacket.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/SyncStreamerDataPacket.java index 8521aea..6c8ed77 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/SyncStreamerDataPacket.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/SyncStreamerDataPacket.java @@ -3,10 +3,10 @@ // Copyright - 2025 // - package net.programmer.igoodie.twitchspawn.network.packet; +import com.mojang.datafixers.util.Function4; import org.jetbrains.annotations.NotNull; import dev.architectury.networking.NetworkManager; @@ -24,11 +24,16 @@ import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; -public record SyncStreamerDataPacket(String playerName, - String twitchToken, - String twitchRefreshToken, - String subscribeScopes) implements CustomPacketPayload -{ +public abstract class SyncStreamerDataPacket implements CustomPacketPayload { + protected final String playerName, twitchToken, twitchRefreshToken, subscribeScopes; + + protected SyncStreamerDataPacket(String playerName, String twitchToken, String twitchRefreshToken, String subscribeScopes) { + this.playerName = playerName; + this.twitchToken = twitchToken; + this.twitchRefreshToken = twitchRefreshToken; + this.subscribeScopes = subscribeScopes; + } + public static void handle(SyncStreamerDataPacket data, NetworkManager.PacketContext packetContext) { packetContext.queue(() -> @@ -69,24 +74,42 @@ public static void handle(SyncStreamerDataPacket data, NetworkManager.PacketCont }); } - - @Override - @NotNull - public Type type() - { - return SyncStreamerDataPacket.ID; + public static StreamCodec streamCodec(Function4 constructor) { + return StreamCodec.composite( + ByteBufCodecs.STRING_UTF8, p -> p.playerName, + ByteBufCodecs.STRING_UTF8, p -> p.twitchToken, + ByteBufCodecs.STRING_UTF8, p -> p.twitchRefreshToken, + ByteBufCodecs.STRING_UTF8, p -> p.subscribeScopes, + constructor + ); } + public static class C2S extends SyncStreamerDataPacket { + public static final StreamCodec STREAM_CODEC = streamCodec(C2S::new); - public static final Type ID = - new Type<>(ResourceLocation.fromNamespaceAndPath(TwitchSpawn.MOD_ID, "sync_data_packet")); + public C2S(String playerName, String twitchToken, String twitchRefreshToken, String subscribeScopes) { + super(playerName, twitchToken, twitchRefreshToken, subscribeScopes); + } + @Override + @NotNull + public Type type() { + return ID; + } + public static final Type ID = new Type<>(ResourceLocation.fromNamespaceAndPath(TwitchSpawn.MOD_ID, "serverbound_sync_data_packet")); + } - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - ByteBufCodecs.STRING_UTF8, SyncStreamerDataPacket::playerName, - ByteBufCodecs.STRING_UTF8, SyncStreamerDataPacket::twitchToken, - ByteBufCodecs.STRING_UTF8, SyncStreamerDataPacket::twitchRefreshToken, - ByteBufCodecs.STRING_UTF8, SyncStreamerDataPacket::subscribeScopes, - SyncStreamerDataPacket::new - ); + public static class S2C extends SyncStreamerDataPacket { + public static final StreamCodec STREAM_CODEC = streamCodec(S2C::new); + public S2C(String playerName, String twitchToken, String twitchRefreshToken, String subscribeScopes) { + super(playerName, twitchToken, twitchRefreshToken, subscribeScopes); + } + + @Override + @NotNull + public Type type() { + return ID; + } + public static final Type ID = new Type<>(ResourceLocation.fromNamespaceAndPath(TwitchSpawn.MOD_ID, "clientbound_sync_data_packet")); + } } From 7f8f9f6a929a1f78923ff9933f743b200c90ae8f Mon Sep 17 00:00:00 2001 From: LiukRast Date: Sun, 14 Dec 2025 15:37:27 +0100 Subject: [PATCH 2/2] Removed GitHub release configuration and improved exception handling in commands. --- build.gradle | 24 ----------------- .../command/TwitchSpawnCommand.java | 27 ++++++------------- 2 files changed, 8 insertions(+), 43 deletions(-) diff --git a/build.gradle b/build.gradle index e27f4e5..3874a3d 100644 --- a/build.gradle +++ b/build.gradle @@ -56,27 +56,3 @@ subprojects { } } - -githubRelease { - token = project.findProperty('github.token') ?: System.getenv('GITHUB_TOKEN') - owner = 'BONNePlayground' - repo = 'TwitchSpawn' - tagName = "${project.version}-${rootProject.minecraft_version}" - targetCommitish = "architectury-${rootProject.minecraft_version}" - releaseName = "${rootProject.archives_name} for ${rootProject.minecraft_version} v${project.version}" - body = { - def changelogFile = file('CHANGELOG_LATEST.md') - if (changelogFile.exists()) { - return changelogFile.text - } else { - return "Release ${project.version}" - } - } - releaseAssets = [ - files("fabric/build/libs/${rootProject.archives_name}-fabric-${rootProject.minecraft_version}-${project.version}.jar"), - files("neoforge/build/libs/${rootProject.archives_name}-neoforge-${rootProject.minecraft_version}-${project.version}.jar") - ] - - draft = true - prerelease = false -} diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java index 0c08122..5cbf8d2 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java @@ -32,10 +32,7 @@ import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLTokenizer; import net.programmer.igoodie.twitchspawn.util.MCPHelpers; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.stream.Stream; public class TwitchSpawnCommand { @@ -110,9 +107,8 @@ public static int authModule(CommandContext context) NetworkManager.sendToPlayer(player, syncStreamerDataPacket); } - catch (CommandSyntaxException e) - { - TwitchSpawn.LOGGER.error("AUTH is available only for players."); + catch (CommandSyntaxException e) { + TwitchSpawn.LOGGER.error("AUTH is available only for players.", e); return 0; } @@ -131,8 +127,6 @@ public static int statusModule(CommandContext context) { public static int startModule(CommandContext context) { String sourceNickname = context.getSource().getTextName(); - - // If has no permission if (!ConfigManager.CREDENTIALS.hasPermission(sourceNickname)) { context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.start.no_perm"), true); @@ -153,8 +147,6 @@ public static int startModule(CommandContext context) { public static int stopModule(CommandContext context) { String sourceNickname = context.getSource().getTextName(); - - // If has no permission if (!ConfigManager.CREDENTIALS.hasPermission(sourceNickname)) { context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.stop.no_perm"), true); @@ -179,9 +171,8 @@ public static int reloadModule(CommandContext context) { boolean isOp = TwitchSpawn.SERVER.isSingleplayer() || Stream.of(TwitchSpawn.SERVER.getPlayerList().getOpNames()) - .anyMatch(oppedPlayerName -> oppedPlayerName.equalsIgnoreCase(sourceNickname)); + .anyMatch(op -> op.equalsIgnoreCase(sourceNickname)); - // If is not OP or has no permission if (!isOp && !ConfigManager.CREDENTIALS.hasPermission(sourceNickname)) { context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.reloadcfg.no_perm"), true); @@ -260,8 +251,6 @@ public static int simulateModule(CommandContext context, Str try { String sourceName = context.getSource().getTextName(); String streamerName = streamerNick != null ? streamerNick : sourceName; - - // If has no permission if (!ConfigManager.CREDENTIALS.hasPermission(sourceName)) { context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.simulate.no_perm"), true); @@ -311,11 +300,11 @@ public static int simulateModule(CommandContext context, Str ConfigManager.RULESET_COLLECTION.handleEvent(simulatedEvent); context.getSource().sendSuccess(() -> Component.translatable( - "commands.twitchspawn.simulate.success", nbt), true); + "commands.twitchspawn.simulate.success", nbt.toString()), true); return 1; } catch (Exception e) { - e.printStackTrace(); + TwitchSpawn.LOGGER.error("Caught exception while simulating event", e); return 0; } } @@ -325,7 +314,7 @@ public static int executeModule(CommandContext context) thro String words = TSLWordsArgumentType.getWords(context, "tsl_action"); List wordTokens = TSLTokenizer.intoWords(words); - String actionName = wordTokens.remove(0); + String actionName = wordTokens.removeFirst(); TSLAction tslAction = TSLParser.parseAction(actionName, wordTokens); EventArguments eventArguments = EventArguments.createRandom(context.getSource().getTextName()); @@ -361,7 +350,7 @@ public static int testModule(CommandContext context, String while (eventIterator.hasNext()) { event = eventIterator.next(); - TSLEventPair eventPair = TSLEventKeyword.toPairs(event.getName()).iterator().next(); + TSLEventPair eventPair = Objects.requireNonNull(TSLEventKeyword.toPairs(event.getName())).iterator().next(); EventArguments eventArguments = new EventArguments(eventPair); eventArguments.randomize(); eventArguments.streamerNickname = streamerPlayer.getName().getString();