From 76cf5c54abe54b339dfca6c142a9e14aa7dc4172 Mon Sep 17 00:00:00 2001 From: BONNe Date: Thu, 21 Dec 2023 22:44:12 +0200 Subject: [PATCH 01/15] Upgrade to Forge 1.20.2 All these changes were made to allow TwitchSpawn to run on 1.20.2. - Update gradle version - add settings.gradle as it is new standard for projects - add sound event registry and augment type registry - rework item parsing, as it is changed - rework network manager and usage to apply 1.20 changes - switch from performCommand to performPrefixedCommand - fix some gui rendering to reflect 1.20 changes - Replace TranslatableComponent to the new Component#translatable --- build.gradle | 72 ++--- gradle.properties | 8 +- gradle/wrapper/gradle-wrapper.jar | Bin 59536 -> 62076 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 276 +++++++++++------- gradlew.bat | 15 +- settings.gradle | 13 + .../igoodie/twitchspawn/TwitchSpawn.java | 46 ++- .../client/gui/GlobalChatCooldownOverlay.java | 51 ++-- .../client/gui/StatusIndicatorOverlay.java | 37 ++- .../twitchspawn/command/CommandArguments.java | 12 +- .../command/StreamerArgumentType.java | 6 +- .../command/TwitchSpawnCommand.java | 57 ++-- .../RulesetNameArgumentSerializer.java | 25 -- .../StreamerArgumentSerializer.java | 25 -- .../twitchspawn/eventqueue/EventQueue.java | 7 +- .../twitchspawn/network/NetworkManager.java | 69 +++-- .../packet/GlobalChatCooldownPacket.java | 30 +- .../network/packet/OsRunPacket.java | 32 +- .../network/packet/StatusChangedPacket.java | 30 +- .../registries/TwitchSpawnAugmentTypes.java | 41 +++ .../registries/TwitchSpawnSoundEvent.java | 36 +++ .../twitchspawn/tracer/TraceManager.java | 25 +- .../tslanguage/action/ChangeAction.java | 95 +++--- .../tslanguage/action/ClearAction.java | 4 +- .../tslanguage/action/DropAction.java | 49 ++-- .../tslanguage/action/ExecuteAction.java | 8 +- .../tslanguage/action/OsRunAction.java | 5 +- .../tslanguage/action/ShuffleAction.java | 4 +- .../tslanguage/action/SummonAction.java | 6 +- .../tslanguage/action/TSLAction.java | 29 +- .../tslanguage/action/ThrowAction.java | 4 +- .../util/ItemProcessingHelper.java | 40 +++ 33 files changed, 640 insertions(+), 520 deletions(-) create mode 100644 settings.gradle delete mode 100644 src/main/java/net/programmer/igoodie/twitchspawn/command/serializer/RulesetNameArgumentSerializer.java delete mode 100644 src/main/java/net/programmer/igoodie/twitchspawn/command/serializer/StreamerArgumentSerializer.java create mode 100644 src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java create mode 100644 src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java create mode 100644 src/main/java/net/programmer/igoodie/twitchspawn/util/ItemProcessingHelper.java diff --git a/build.gradle b/build.gradle index 7d6ec5c..d7912bb 100644 --- a/build.gradle +++ b/build.gradle @@ -1,20 +1,17 @@ buildscript { - repositories { - maven { url = 'https://maven.minecraftforge.net' } - mavenCentral() - gradlePluginPortal() - } dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true classpath 'gradle.plugin.com.github.johnrengelman:shadow:7.1.2' } } -apply plugin: 'net.minecraftforge.gradle' +plugins { + id 'java' + id 'idea' + id 'maven-publish' + id 'net.minecraftforge.gradle' version '[6.0.16,6.2)' +} + apply plugin: 'com.github.johnrengelman.shadow' -apply plugin: 'java' -apply plugin: 'idea' -apply plugin: 'maven-publish' version = mod_version group = "igoodie.twitchspawn" @@ -33,65 +30,54 @@ minecraft { mappings channel: mcpMappings_channel, version: mcpMappings_version // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. - // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') + copyIdeResources = true // Default run configurations. // These can be tweaked, removed, or duplicated as needed. runs { - client { - workingDirectory project.file('run') - + // applies to all the run configs below + configureEach { // Recommended logging data for a userdev environment - property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + property 'forge.logging.markers', 'REGISTRIES' // Recommended logging level for the console property 'forge.logging.console.level', 'debug' mods { - examplemod { + "${mod_id}" { source sourceSets.main } } } - server { - workingDirectory project.file('run') - - // Recommended logging data for a userdev environment - property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + client { + workingDirectory project.file('run/client') + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + property 'forge.enabledGameTestNamespaces', mod_id + } - // Recommended logging level for the console - property 'forge.logging.console.level', 'debug' + server { + workingDirectory project.file('run/server') + property 'forge.enabledGameTestNamespaces', mod_id + args '--nogui' + } - mods { - examplemod { - source sourceSets.main - } - } + // This run config launches GameTestServer and runs all registered gametests, then exits. + gameTestServer { + property 'forge.enabledGameTestNamespaces', mod_id } data { - workingDirectory project.file('run') - - // Recommended logging data for a userdev environment - property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' - - // Recommended logging level for the console - property 'forge.logging.console.level', 'debug' + // example of overriding the workingDirectory set in configureEach above + workingDirectory project.file('run-data') - args '--mod', 'examplemod', '--all', '--output', file('src/generated/resources/') - - mods { - examplemod { - source sourceSets.main - } - } + // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. + args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') } } } repositories { - jcenter() mavenCentral() } diff --git a/gradle.properties b/gradle.properties index 9c090b9..50c0639 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,10 +5,10 @@ org.gradle.daemon=false mod_id=twitchspawn mod_group=net.programmer.igoodie -mod_version=1.9.4 +mod_version=1.9.5 -minecraft_version=1.18.2 -forge_version=40.0.52 +minecraft_version=1.20.2 +forge_version=48.1.0 mcpMappings_channel=official -mcpMappings_version=1.18.2 +mcpMappings_version=1.20.2 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f2ae8848c63b8b4dea2cb829da983f2fa..c1962a79e29d3e0ab67b14947c167a862655af9b 100644 GIT binary patch delta 40133 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 \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MSYS* | MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +118,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,7 +129,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -106,80 +137,109 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 107acd3..93e3f59 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..0077fa7 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,13 @@ +pluginManagement { + repositories { + gradlePluginPortal() + maven { + name = 'MinecraftForge' + url = 'https://maven.minecraftforge.net/' + } + } +} + +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0' +} diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java b/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java index 84c4d79..2973e0c 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java @@ -1,19 +1,20 @@ package net.programmer.igoodie.twitchspawn; -import net.minecraft.commands.synchronization.ArgumentTypes; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.resources.ResourceLocation; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.sounds.SoundEvent; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegisterCommandsEvent; -import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.server.ServerAboutToStartEvent; import net.minecraftforge.event.server.ServerStartingEvent; import net.minecraftforge.event.server.ServerStoppingEvent; +import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.ModLoadingStage; import net.minecraftforge.fml.common.Mod; @@ -22,22 +23,17 @@ import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.loading.FMLEnvironment; -import net.minecraftforge.network.NetworkDirection; import net.programmer.igoodie.twitchspawn.client.gui.GlobalChatCooldownOverlay; import net.programmer.igoodie.twitchspawn.client.gui.StatusIndicatorOverlay; -import net.programmer.igoodie.twitchspawn.command.RulesetNameArgumentType; -import net.programmer.igoodie.twitchspawn.command.StreamerArgumentType; import net.programmer.igoodie.twitchspawn.command.TwitchSpawnCommand; -import net.programmer.igoodie.twitchspawn.command.serializer.RulesetNameArgumentSerializer; -import net.programmer.igoodie.twitchspawn.command.serializer.StreamerArgumentSerializer; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; import net.programmer.igoodie.twitchspawn.configuration.PreferencesConfig; import net.programmer.igoodie.twitchspawn.network.NetworkManager; import net.programmer.igoodie.twitchspawn.network.packet.StatusChangedPacket; +import net.programmer.igoodie.twitchspawn.registries.TwitchSpawnAugmentTypes; +import net.programmer.igoodie.twitchspawn.registries.TwitchSpawnSoundEvent; import net.programmer.igoodie.twitchspawn.tracer.TraceManager; import net.programmer.igoodie.twitchspawn.udl.NotepadUDLUpdater; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; @Mod(TwitchSpawn.MOD_ID) public class TwitchSpawn { @@ -54,18 +50,16 @@ public TwitchSpawn() { FMLJavaModLoadingContext.get().getModEventBus().addListener(this::dedicatedServerSetup); MinecraftForge.EVENT_BUS.register(this); + + IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); + TwitchSpawnSoundEvent.REGISTRY.register(modEventBus); + TwitchSpawnAugmentTypes.REGISTRY.register(modEventBus); } private void commonSetup(final FMLCommonSetupEvent event) { try { ConfigManager.loadConfigs(); NetworkManager.initialize(); - - ArgumentTypes.register("twitchspawn:streamer", StreamerArgumentType.class, - new StreamerArgumentSerializer()); - ArgumentTypes.register("twitchspawn:ruleset", RulesetNameArgumentType.class, - new RulesetNameArgumentSerializer()); - } catch (TwitchSpawnLoadingErrors e) { e.bindFMLWarnings(ModLoadingStage.COMMON_SETUP); if (FMLEnvironment.dist == Dist.DEDICATED_SERVER) { @@ -82,11 +76,6 @@ private void clientSetup(final FMLClientSetupEvent event) { private void dedicatedServerSetup(final FMLDedicatedServerSetupEvent event) {} - @SubscribeEvent - public void registerSounds(RegistryEvent.Register event) { - event.getRegistry().register(new SoundEvent(new ResourceLocation(TwitchSpawn.MOD_ID, "pop_in"))); - event.getRegistry().register(new SoundEvent(new ResourceLocation(TwitchSpawn.MOD_ID, "pop_out"))); - } @SubscribeEvent public void onRegisterCommands(RegisterCommandsEvent event) { @@ -119,24 +108,23 @@ public void onServerStopping(ServerStoppingEvent event) { @SubscribeEvent public void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) { - ServerPlayer entity = (ServerPlayer) event.getPlayer(); + ServerPlayer entity = (ServerPlayer) event.getEntity(); String translationKey = TRACE_MANAGER.isRunning() ? "commands.twitchspawn.status.on" : "commands.twitchspawn.status.off"; - entity.sendMessage(new TranslatableComponent(translationKey), entity.getUUID()); + entity.sendSystemMessage(Component.translatable(translationKey)); if (TRACE_MANAGER.isRunning()) TRACE_MANAGER.connectStreamer(entity.getName().getString()); - NetworkManager.CHANNEL.sendTo(new StatusChangedPacket(TRACE_MANAGER.isRunning()), - entity.connection.connection, - NetworkDirection.PLAY_TO_CLIENT); + NetworkManager.CHANNEL.send(new StatusChangedPacket(TRACE_MANAGER.isRunning()), + entity.connection.getConnection()); } @SubscribeEvent public void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) { - ServerPlayer entity = (ServerPlayer) event.getPlayer(); + ServerPlayer entity = (ServerPlayer) event.getEntity(); if (TRACE_MANAGER.isRunning()) TRACE_MANAGER.disconnectStreamer(entity.getName().getString()); diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java b/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java index b8a3a42..a48c4bd 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java @@ -2,12 +2,11 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.client.event.RenderGameOverlayEvent; -import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; +import net.minecraftforge.client.event.RenderGuiOverlayEvent; +import net.minecraftforge.client.gui.overlay.VanillaGuiOverlay; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; @@ -27,13 +26,13 @@ public static void setCooldownTimestamp(long timestamp) { } @SubscribeEvent - public static void onRenderGuiPre(RenderGameOverlayEvent.Pre event) { + public static void onRenderGuiPre(RenderGuiOverlayEvent.Pre event) { drew = false; } @SubscribeEvent - public static void onRenderGuiPost(RenderGameOverlayEvent.Post event) { - if (event.getType() != ElementType.TEXT) + public static void onRenderGuiPost(RenderGuiOverlayEvent.Post event) { + if (event.getOverlay() != VanillaGuiOverlay.HOTBAR.type()) return; // Render only on HOTBAR // Already drew, stop here @@ -61,23 +60,20 @@ public static void onRenderGuiPost(RenderGameOverlayEvent.Post event) { y = 5; } - PoseStack matrixStack = event.getMatrixStack(); - + PoseStack matrixStack = event.getGuiGraphics().pose(); matrixStack.pushPose(); matrixStack.scale(scale, scale, scale); - renderGlyph(matrixStack, String.format("%02d", minutes), x, (int) (y / scale)); - renderGlyph(matrixStack, ":", x + 32, (int) (y / scale)); - renderGlyph(matrixStack, String.format("%02d", seconds), (x + 10 + 2 * 18), (int) (y / scale)); - renderGlyph(matrixStack, "i", (int) (x + 10 + 4.25f * 18), (int) ((y - 2) / scale)); + renderGlyph(event.getGuiGraphics(), matrixStack, String.format("%02d", minutes), x, (int) (y / scale)); + renderGlyph(event.getGuiGraphics(), matrixStack, ":", x + 32, (int) (y / scale)); + renderGlyph(event.getGuiGraphics(), matrixStack, String.format("%02d", seconds), (x + 10 + 2 * 18), (int) (y / scale)); + renderGlyph(event.getGuiGraphics(), matrixStack, "i", (int) (x + 10 + 4.25f * 18), (int) ((y - 2) / scale)); matrixStack.popPose(); } drew = true; } - public static void renderGlyph(PoseStack ms, String number, int x, int y) { - Minecraft minecraft = Minecraft.getInstance(); - + public static void renderGlyph(GuiGraphics guiGraphics, PoseStack ms, String number, int x, int y) { RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.setShaderTexture(0, cooldownGlyphs); @@ -92,30 +88,27 @@ public static void renderGlyph(PoseStack ms, String number, int x, int y) { int w = 28; int h = 25; - minecraft.gui.blit( - ms, - x, y, - ux, uy, - w, h + guiGraphics.blit(VanillaGuiOverlay.HOTBAR.id(), + x, y, + ux, uy, + w, h ); } else { char[] chars = number.toCharArray(); for (int i = 0, offset = 0; i < chars.length; i++) { - int digit = number.equals(":") ? 10 - : Character.digit(number.charAt(i), 10); + int digit = number.equals(":") ? 10 : Character.digit(number.charAt(i), 10); int ux = 18 * digit; int uy = 0; int w = 18; int h = 18; - minecraft.gui.blit( - ms, - x + offset, y, - ux, uy, - w, h + guiGraphics.blit(VanillaGuiOverlay.HOTBAR.id(), + x + offset, y, + ux, uy, + w, h ); offset += w; @@ -127,7 +120,7 @@ public static void renderGlyph(PoseStack ms, String number, int x, int y) { RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.setShaderTexture(0, Gui.GUI_ICONS_LOCATION); + RenderSystem.setShaderTexture(0, new ResourceLocation("hud/hotbar")); } } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java b/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java index f9aec20..d43c01c 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java @@ -1,20 +1,23 @@ package net.programmer.igoodie.twitchspawn.client.gui; + import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; + import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; -import net.minecraftforge.client.event.RenderGameOverlayEvent; -import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; +import net.minecraftforge.client.event.CustomizeGuiOverlayEvent; +import net.minecraftforge.client.event.RenderGuiOverlayEvent; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; import net.programmer.igoodie.twitchspawn.configuration.PreferencesConfig; +import net.programmer.igoodie.twitchspawn.registries.TwitchSpawnSoundEvent; + public class StatusIndicatorOverlay { @@ -27,13 +30,14 @@ public class StatusIndicatorOverlay { public static void setRunning(boolean running) { StatusIndicatorOverlay.running = running; - String soundName = running ? "pop_in" : "pop_out"; + ResourceLocation soundEvent = running ? + TwitchSpawnSoundEvent.POP_IN.getId() : TwitchSpawnSoundEvent.POP_OUT.getId(); Minecraft minecraft = Minecraft.getInstance(); LocalPlayer self = minecraft.player; if (self != null) { // Here to hopefully fix an obscure Null Pointer (From UNKNOWN PENGUIN's log) - self.playSound(new SoundEvent(new ResourceLocation(TwitchSpawn.MOD_ID, soundName)), 1f, 1f); + self.playSound(SoundEvent.createVariableRangeEvent(soundEvent), 1f, 1f); } } @@ -44,21 +48,15 @@ public static void onClientTick(TickEvent.ClientTickEvent event) { } @SubscribeEvent - public static void onRenderGuiPre(RenderGameOverlayEvent.Pre event) { + public static void onRenderGuiPre(RenderGuiOverlayEvent.Pre event) { drew = false; } @SubscribeEvent - public static void onRenderGuiPost(RenderGameOverlayEvent.Post event) { + public static void onRenderGuiPost(CustomizeGuiOverlayEvent.DebugText event) { if (ConfigManager.PREFERENCES.indicatorDisplay == PreferencesConfig.IndicatorDisplay.DISABLED) return; // The display is disabled, stop here - Minecraft minecraft = Minecraft.getInstance(); - PoseStack matrixStack = event.getMatrixStack(); - - if (event.getType() != ElementType.TEXT) - return; // Render only on HOTBAR - // Already drew, stop here if (drew) return; @@ -68,7 +66,8 @@ public static void onRenderGuiPost(RenderGameOverlayEvent.Post event) { RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderTexture(0, indicatorIcons); - matrixStack.pushPose(); + GuiGraphics gui = event.getGuiGraphics(); + gui.pose().pushPose(); int x = 5, y = 5; int ux = -1, uy = -1; @@ -86,15 +85,15 @@ public static void onRenderGuiPost(RenderGameOverlayEvent.Post event) { h = 12; } - matrixStack.scale(1f, 1f, 1f); - minecraft.gui.blit(matrixStack, x, y, ux, uy, w, h); + gui.pose().scale(1f, 1f, 1f); + gui.blit(indicatorIcons, x, y, ux, uy, w, h); - matrixStack.popPose(); + gui.pose().popPose(); RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.disableBlend(); - RenderSystem.setShaderTexture(0, Gui.GUI_ICONS_LOCATION); +// RenderSystem.setShaderTexture(0, Gui.GUI_ICONS_LOCATION); drew = true; } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/command/CommandArguments.java b/src/main/java/net/programmer/igoodie/twitchspawn/command/CommandArguments.java index 933f0c6..99e8afc 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/command/CommandArguments.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/command/CommandArguments.java @@ -1,14 +1,14 @@ package net.programmer.igoodie.twitchspawn.command; + import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.RequiredArgumentBuilder; + import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.CompoundTagArgument; import net.minecraft.commands.arguments.EntityArgument; -import net.minecraft.commands.arguments.item.ItemArgument; -import net.minecraft.commands.arguments.item.ItemInput; import net.minecraft.commands.arguments.selector.EntitySelector; import net.minecraft.nbt.CompoundTag; @@ -26,9 +26,11 @@ public static RequiredArgumentBuilder integer(Strin return Commands.argument(name, IntegerArgumentType.integer(min, max)); } - public static RequiredArgumentBuilder item(String name) { - return Commands.argument(name, ItemArgument.item()); - } +// I just commented out, as it is not used. ItemArgument.item() requires CommandBuildContext that +// I do not know how to provide here. +// public static RequiredArgumentBuilder item(String name) { +// return Commands.argument(name, ItemArgument.item()); +// } public static RequiredArgumentBuilder player(String name) { return Commands.argument(name, EntityArgument.player()); diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java b/src/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java index 358b2bc..1c7b78e 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java @@ -1,15 +1,16 @@ package net.programmer.igoodie.twitchspawn.command; + import com.mojang.brigadier.StringReader; import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; - import java.util.concurrent.CompletableFuture; +import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; + public class StreamerArgumentType implements ArgumentType { public static StreamerArgumentType streamerNick() { @@ -46,5 +47,4 @@ public CompletableFuture listSuggestions(CommandContext cont public String toString() { return "streamer()"; } - } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java b/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java index 8f2024b..58e5bdd 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java @@ -1,16 +1,21 @@ package net.programmer.igoodie.twitchspawn.command; + import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.BuiltInExceptions; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import net.minecraft.commands.CommandRuntimeException; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.stream.Stream; + import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; @@ -31,12 +36,6 @@ 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.stream.Stream; - public class TwitchSpawnCommand { public static final String[] COMMAND_NAMES = {"twitchspawn", "ts"}; @@ -86,7 +85,7 @@ public static int statusModule(CommandContext context) { String translationKey = TwitchSpawn.TRACE_MANAGER.isRunning() ? "commands.twitchspawn.status.on" : "commands.twitchspawn.status.off"; - context.getSource().sendSuccess(new TranslatableComponent(translationKey), false); + context.getSource().sendSuccess(() -> Component.translatable(translationKey), false); return 1; } @@ -96,7 +95,7 @@ public static int startModule(CommandContext context) { // If has no permission if (!ConfigManager.CREDENTIALS.hasPermission(sourceNickname)) { - context.getSource().sendSuccess(new TranslatableComponent( + context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.start.no_perm"), true); TwitchSpawn.LOGGER.info("{} tried to run TwitchSpawn, but no permission", sourceNickname); return 0; @@ -107,7 +106,7 @@ public static int startModule(CommandContext context) { return 1; } catch (IllegalStateException e) { - context.getSource().sendSuccess(new TranslatableComponent( + context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.start.illegal_state"), true); return 0; } @@ -118,7 +117,7 @@ public static int stopModule(CommandContext context) { // If has no permission if (!ConfigManager.CREDENTIALS.hasPermission(sourceNickname)) { - context.getSource().sendSuccess(new TranslatableComponent( + context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.stop.no_perm"), true); TwitchSpawn.LOGGER.info("{} tried to stop TwitchSpawn, but no permission", sourceNickname); return 0; @@ -129,7 +128,7 @@ public static int stopModule(CommandContext context) { return 1; } catch (IllegalStateException e) { - context.getSource().sendSuccess(new TranslatableComponent( + context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.stop.illegal_state"), true); return 0; } @@ -145,27 +144,27 @@ public static int reloadModule(CommandContext context) { // If is not OP or has no permission if (!isOp && !ConfigManager.CREDENTIALS.hasPermission(sourceNickname)) { - context.getSource().sendSuccess(new TranslatableComponent( + context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.reloadcfg.no_perm"), true); TwitchSpawn.LOGGER.info("{} tried to reload TwitchSpawn configs, but no permission", sourceNickname); return 0; } if (TwitchSpawn.TRACE_MANAGER.isRunning()) { - source.sendSuccess(new TranslatableComponent( + source.sendSuccess(() -> Component.translatable( "commands.twitchspawn.reloadcfg.already_started"), false); return 0; } try { ConfigManager.loadConfigs(); - source.sendSuccess(new TranslatableComponent( + source.sendSuccess(() -> Component.translatable( "commands.twitchspawn.reloadcfg.success"), false); return 1; } catch (TwitchSpawnLoadingErrors e) { String errorLog = "• " + e.toString().replace("\n", "\n• "); - source.sendSuccess(new TranslatableComponent( + source.sendSuccess(() -> Component.translatable( "commands.twitchspawn.reloadcfg.invalid_syntax", errorLog), false); return 0; } @@ -175,7 +174,7 @@ public static int quickRefreshModule(CommandContext context) String sourceNickname = context.getSource().getTextName(); if (!ConfigManager.CREDENTIALS.hasPermission(sourceNickname)) { - context.getSource().sendSuccess(new TranslatableComponent( + context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.reloadcfg.no_perm"), true); TwitchSpawn.LOGGER.info("{} tried to run TwitchSpawn, but no permission", sourceNickname); return 0; @@ -194,7 +193,7 @@ public static int quickRefreshModule(CommandContext context) public static int rulesModule(CommandContext context, String rulesetName) { if (rulesetName == null) { - context.getSource().sendSuccess(new TranslatableComponent( + context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.rules.list", ConfigManager.RULESET_COLLECTION.getStreamers()), true); return 1; @@ -203,7 +202,7 @@ public static int rulesModule(CommandContext context, String TSLRuleset ruleset = ConfigManager.RULESET_COLLECTION.getRuleset(rulesetName); if (ruleset == null) { - context.getSource().sendSuccess(new TranslatableComponent( + context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.rules.one.fail", rulesetName), true); return 0; @@ -211,7 +210,7 @@ public static int rulesModule(CommandContext context, String String translationKey = rulesetName.equalsIgnoreCase("default") ? "commands.twitchspawn.rules.default" : "commands.twitchspawn.rules.one"; - context.getSource().sendSuccess(new TranslatableComponent(translationKey, + context.getSource().sendSuccess(() -> Component.translatable(translationKey, rulesetName, ruleset.toString()), true); return 1; } @@ -225,7 +224,7 @@ public static int simulateModule(CommandContext context, Str // If has no permission if (!ConfigManager.CREDENTIALS.hasPermission(sourceName)) { - context.getSource().sendSuccess(new TranslatableComponent( + context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.simulate.no_perm"), true); TwitchSpawn.LOGGER.info("{} tried to simulate an event, but no permission", sourceName); return 0; @@ -235,7 +234,7 @@ public static int simulateModule(CommandContext context, Str String eventName = nbt.getString("event"); if (eventName.isEmpty()) { - context.getSource().sendSuccess(new TranslatableComponent( + context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.simulate.missing"), true); return 0; } @@ -243,7 +242,7 @@ public static int simulateModule(CommandContext context, Str Set eventPairs = TSLEventKeyword.toPairs(eventName); if (eventPairs == null) { - context.getSource().sendSuccess(new TranslatableComponent( + context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.simulate.invalid_event", eventName), true); return 0; } @@ -272,7 +271,7 @@ public static int simulateModule(CommandContext context, Str ConfigManager.RULESET_COLLECTION.handleEvent(simulatedEvent); - context.getSource().sendSuccess(new TranslatableComponent( + context.getSource().sendSuccess(() -> Component.translatable( "commands.twitchspawn.simulate.success", nbt), true); return 1; @@ -294,7 +293,7 @@ public static int executeModule(CommandContext context) thro tslAction.process(eventArguments); } catch (TSLSyntaxError e) { - throw new CommandRuntimeException(new TextComponent(e.getMessage())); + throw new CommandSyntaxException(new BuiltInExceptions().dispatcherParseException(), Component.translatable(e.getMessage())); } return 1; @@ -307,7 +306,7 @@ public static int executeModule(CommandContext context) thro public static int testModule(CommandContext context, String streamerNick) throws CommandSyntaxException { if (!ConfigManager.RULESET_COLLECTION.hasStreamer(streamerNick)) { TwitchSpawn.LOGGER.info("There are no ruleset associated with {}", streamerNick); - context.getSource().sendSuccess(new TranslatableComponent("commands.twitchspawn.test.not_found", streamerNick), true); + context.getSource().sendSuccess(() -> Component.translatable("commands.twitchspawn.test.not_found", streamerNick), true); return 0; } @@ -356,7 +355,7 @@ public static int testModule(CommandContext context, String } TwitchSpawn.LOGGER.info("Tests queued for {}", streamerNick); - context.getSource().sendSuccess(new TranslatableComponent("commands.twitchspawn.test.success", streamerNick), true); + context.getSource().sendSuccess(() -> Component.translatable("commands.twitchspawn.test.success", streamerNick), true); return 1; } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/command/serializer/RulesetNameArgumentSerializer.java b/src/main/java/net/programmer/igoodie/twitchspawn/command/serializer/RulesetNameArgumentSerializer.java deleted file mode 100644 index ef68dcf..0000000 --- a/src/main/java/net/programmer/igoodie/twitchspawn/command/serializer/RulesetNameArgumentSerializer.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.programmer.igoodie.twitchspawn.command.serializer; - -import com.google.gson.JsonObject; -import net.minecraft.commands.synchronization.ArgumentSerializer; -import net.minecraft.network.FriendlyByteBuf; -import net.programmer.igoodie.twitchspawn.command.RulesetNameArgumentType; - -public class RulesetNameArgumentSerializer implements ArgumentSerializer { - - @Override - public void serializeToNetwork(RulesetNameArgumentType p_121579_, FriendlyByteBuf p_121580_) { - - } - - @Override - public RulesetNameArgumentType deserializeFromNetwork(FriendlyByteBuf p_121581_) { - return RulesetNameArgumentType.rulesetName(); - } - - @Override - public void serializeToJson(RulesetNameArgumentType p_121577_, JsonObject p_121578_) { - - } - -} diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/command/serializer/StreamerArgumentSerializer.java b/src/main/java/net/programmer/igoodie/twitchspawn/command/serializer/StreamerArgumentSerializer.java deleted file mode 100644 index a6b2103..0000000 --- a/src/main/java/net/programmer/igoodie/twitchspawn/command/serializer/StreamerArgumentSerializer.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.programmer.igoodie.twitchspawn.command.serializer; - -import com.google.gson.JsonObject; -import net.minecraft.commands.synchronization.ArgumentSerializer; -import net.minecraft.network.FriendlyByteBuf; -import net.programmer.igoodie.twitchspawn.command.StreamerArgumentType; - -public class StreamerArgumentSerializer implements ArgumentSerializer { - - @Override - public void serializeToNetwork(StreamerArgumentType argumentType, FriendlyByteBuf buffer) { - - } - - @Override - public StreamerArgumentType deserializeFromNetwork(FriendlyByteBuf buffer) { - return StreamerArgumentType.streamerNick(); - } - - @Override - public void serializeToJson(StreamerArgumentType argumentType, JsonObject jsonObject) { - - } - -} diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java b/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java index 749f61b..18c3e25 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java @@ -136,10 +136,9 @@ public void queue(TSLEvent eventNode, EventArguments args, CooldownBucket cooldo .getPlayerByName(args.streamerNickname); if (playerEntity != null) { - NetworkManager.CHANNEL.sendTo( - new GlobalChatCooldownPacket(cooldownBucket.getGlobalCooldownTimestamp()), - playerEntity.connection.connection, - NetworkDirection.PLAY_TO_CLIENT + NetworkManager.CHANNEL.send( + new GlobalChatCooldownPacket(cooldownBucket.getGlobalCooldownTimestamp()), + playerEntity.connection.getConnection() ); } } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java b/src/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java index 2f09198..13fcaa5 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java @@ -1,40 +1,53 @@ package net.programmer.igoodie.twitchspawn.network; import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.network.NetworkRegistry; -import net.minecraftforge.network.simple.SimpleChannel; + +import net.minecraftforge.network.Channel; +import net.minecraftforge.network.ChannelBuilder; +import net.minecraftforge.network.NetworkDirection; +import net.minecraftforge.network.SimpleChannel; import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.network.packet.GlobalChatCooldownPacket; import net.programmer.igoodie.twitchspawn.network.packet.OsRunPacket; import net.programmer.igoodie.twitchspawn.network.packet.StatusChangedPacket; public class NetworkManager { - - private static final String PROTOCOL_VERSION = "0.0.4"; - - public static final SimpleChannel CHANNEL = NetworkRegistry.ChannelBuilder - .named(new ResourceLocation(TwitchSpawn.MOD_ID, "network")) - .clientAcceptedVersions(v -> v.equals(PROTOCOL_VERSION)) - .serverAcceptedVersions(v -> v.equals(PROTOCOL_VERSION)) - .networkProtocolVersion(() -> PROTOCOL_VERSION) - .simpleChannel(); - + /** + * Protocol versions now are Integers. So gone 0.0.5 :) + */ + private static final int PROTOCOL_VERSION = 1; + + /** + * Channel for network communication. + */ + public static final SimpleChannel CHANNEL = ChannelBuilder. + named(new ResourceLocation(TwitchSpawn.MOD_ID, "network")). + clientAcceptedVersions(Channel.VersionTest.exact(PROTOCOL_VERSION)). + serverAcceptedVersions(Channel.VersionTest.exact(PROTOCOL_VERSION)). + networkProtocolVersion(PROTOCOL_VERSION). + simpleChannel(); + + + /** + * The method that initializes the network channel. + */ public static void initialize() { - CHANNEL.registerMessage(0, StatusChangedPacket.class, - StatusChangedPacket::encode, - StatusChangedPacket::decode, - StatusChangedPacket::handle); - - CHANNEL.registerMessage(1, OsRunPacket.class, - OsRunPacket::encode, - OsRunPacket::decode, - OsRunPacket::handle); - - CHANNEL.registerMessage(2, GlobalChatCooldownPacket.class, - GlobalChatCooldownPacket::encode, - GlobalChatCooldownPacket::decode, - GlobalChatCooldownPacket::handle - ); + CHANNEL.messageBuilder(StatusChangedPacket.class, 0, NetworkDirection.PLAY_TO_CLIENT) + .decoder(StatusChangedPacket::decode) + .encoder(StatusChangedPacket::encode) + .consumerMainThread(StatusChangedPacket::handle) + .add(); + + CHANNEL.messageBuilder(OsRunPacket.class, 1, NetworkDirection.PLAY_TO_CLIENT) + .decoder(OsRunPacket::decode) + .encoder(OsRunPacket::encode) + .consumerMainThread(OsRunPacket::handle) + .add(); + + CHANNEL.messageBuilder(GlobalChatCooldownPacket.class, 2, NetworkDirection.PLAY_TO_CLIENT) + .decoder(GlobalChatCooldownPacket::decode) + .encoder(GlobalChatCooldownPacket::encode) + .consumerMainThread(GlobalChatCooldownPacket::handle) + .add(); } - } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java b/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java index abedc9c..9f1e977 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java @@ -1,13 +1,16 @@ package net.programmer.igoodie.twitchspawn.network.packet; + import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.network.NetworkEvent; +import net.minecraftforge.event.network.CustomPayloadEvent; import net.programmer.igoodie.twitchspawn.client.gui.GlobalChatCooldownOverlay; -import java.util.function.Supplier; - public class GlobalChatCooldownPacket { + public GlobalChatCooldownPacket(long timestamp) { + this.timestamp = timestamp; + } + public static void encode(GlobalChatCooldownPacket packet, FriendlyByteBuf buffer) { buffer.writeLong(packet.timestamp); } @@ -16,20 +19,13 @@ public static GlobalChatCooldownPacket decode(FriendlyByteBuf buffer) { return new GlobalChatCooldownPacket(buffer.readLong()); } - public static void handle(final GlobalChatCooldownPacket packet, - Supplier context) { - context.get().enqueueWork(() -> { - GlobalChatCooldownOverlay.setCooldownTimestamp(packet.timestamp); - }); - context.get().setPacketHandled(true); - } - - /* -------------------------------- */ - - private long timestamp; - - public GlobalChatCooldownPacket(long timestamp) { - this.timestamp = timestamp; + public void handle(CustomPayloadEvent.Context context) { + context.enqueueWork(() -> GlobalChatCooldownOverlay.setCooldownTimestamp(this.timestamp)); + context.setPacketHandled(true); } + /** + * Timestamp of the cooldown. + */ + private final long timestamp; } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java b/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java index ae401a5..b7fa790 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java @@ -1,13 +1,17 @@ package net.programmer.igoodie.twitchspawn.network.packet; + import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.network.NetworkEvent; +import net.minecraftforge.event.network.CustomPayloadEvent; import net.programmer.igoodie.twitchspawn.tslanguage.action.OsRunAction; -import java.util.function.Supplier; - public class OsRunPacket { + public OsRunPacket(OsRunAction.Shell shell, String script) { + this.shell = shell; + this.script = script; + } + public static void encode(OsRunPacket packet, FriendlyByteBuf buffer) { buffer.writeInt(packet.shell.ordinal()); buffer.writeUtf(packet.script); @@ -20,19 +24,19 @@ public static OsRunPacket decode(FriendlyByteBuf buffer) { return new OsRunPacket(shell, script); } - public static void handle(final OsRunPacket packet, Supplier context) { - context.get().enqueueWork(() -> OsRunAction.handleLocalScript(packet.shell, packet.script)); - context.get().setPacketHandled(true); + public void handle(CustomPayloadEvent.Context context) { + context.enqueueWork(() -> OsRunAction.handleLocalScript(this.shell, this.script)); + context.setPacketHandled(true); } - /* ------------------------------------------------ */ - - private OsRunAction.Shell shell; - private String script; - public OsRunPacket(OsRunAction.Shell shell, String script) { - this.shell = shell; - this.script = script; - } + /** + * Shell to run the script with. + */ + private final OsRunAction.Shell shell; + /** + * Script to run. + */ + private final String script; } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java b/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java index 97b54ac..caf866c 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java @@ -1,13 +1,16 @@ package net.programmer.igoodie.twitchspawn.network.packet; + import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.network.NetworkEvent; +import net.minecraftforge.event.network.CustomPayloadEvent; import net.programmer.igoodie.twitchspawn.client.gui.StatusIndicatorOverlay; -import java.util.function.Supplier; - public class StatusChangedPacket { + public StatusChangedPacket(boolean status) { + this.status = status; + } + public static void encode(StatusChangedPacket packet, FriendlyByteBuf buffer) { buffer.writeBoolean(packet.status); } @@ -16,20 +19,13 @@ public static StatusChangedPacket decode(FriendlyByteBuf buffer) { return new StatusChangedPacket(buffer.readBoolean()); } - public static void handle(final StatusChangedPacket packet, - Supplier context) { - context.get().enqueueWork(() -> { - StatusIndicatorOverlay.setRunning(packet.status); - }); - context.get().setPacketHandled(true); - } - - /* ---------------------------- */ - - private boolean status; - - public StatusChangedPacket(boolean status) { - this.status = status; + public void handle(CustomPayloadEvent.Context context) { + context.enqueueWork(() -> StatusIndicatorOverlay.setRunning(this.status)); + context.setPacketHandled(true); } + /** + * True if the status is running, false if stopped. + */ + private final boolean status; } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java b/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java new file mode 100644 index 0000000..c754634 --- /dev/null +++ b/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java @@ -0,0 +1,41 @@ +package net.programmer.igoodie.twitchspawn.registries; + + +import net.minecraft.commands.synchronization.ArgumentTypeInfo; +import net.minecraft.commands.synchronization.ArgumentTypeInfos; +import net.minecraft.commands.synchronization.SingletonArgumentInfo; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.programmer.igoodie.twitchspawn.TwitchSpawn; +import net.programmer.igoodie.twitchspawn.command.RulesetNameArgumentType; +import net.programmer.igoodie.twitchspawn.command.StreamerArgumentType; +import net.programmer.igoodie.twitchspawn.command.TSLWordsArgumentType; + + +/** + * This class registers argument types. + */ +@Mod.EventBusSubscriber(modid = TwitchSpawn.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) +public class TwitchSpawnAugmentTypes +{ + /** + * Registry for argument types. + */ + public static final DeferredRegister> REGISTRY = + DeferredRegister.create(ForgeRegistries.COMMAND_ARGUMENT_TYPES, TwitchSpawn.MOD_ID); + + static { + // Argument type for ruleset names. + REGISTRY.register("ruleset", () -> ArgumentTypeInfos.registerByClass(RulesetNameArgumentType.class, + SingletonArgumentInfo.contextFree(RulesetNameArgumentType::rulesetName))); + + // Argument type for streamer names. + REGISTRY.register("streamer", () -> ArgumentTypeInfos.registerByClass(StreamerArgumentType.class, + SingletonArgumentInfo.contextFree(StreamerArgumentType::streamerNick))); + + // Argument type for TSL words. + REGISTRY.register("tslwords", () -> ArgumentTypeInfos.registerByClass(TSLWordsArgumentType.class, + SingletonArgumentInfo.contextFree(TSLWordsArgumentType::tslWords))); + } +} diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java b/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java new file mode 100644 index 0000000..32e5f0d --- /dev/null +++ b/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java @@ -0,0 +1,36 @@ +package net.programmer.igoodie.twitchspawn.registries; + + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import net.programmer.igoodie.twitchspawn.TwitchSpawn; + + +/** + * This class registers sound events. + */ +@Mod.EventBusSubscriber(modid = TwitchSpawn.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) +public class TwitchSpawnSoundEvent +{ + /** + * Registry for sound events. + */ + public static final DeferredRegister REGISTRY = + DeferredRegister.create(ForgeRegistries.SOUND_EVENTS, TwitchSpawn.MOD_ID); + + /** + * Sound event for popping in. + */ + public static final RegistryObject POP_IN = REGISTRY.register("pop_in", + () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(TwitchSpawn.MOD_ID))); + + /** + * Sound event for popping out. + */ + public static final RegistryObject POP_OUT = REGISTRY.register("pop_out", + () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(TwitchSpawn.MOD_ID))); +} diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java b/src/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java index 78c2cad..8935072 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java @@ -3,9 +3,8 @@ import io.socket.client.IO; import io.socket.client.Socket; import net.minecraft.commands.CommandSourceStack; -import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.network.NetworkDirection; import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; @@ -70,12 +69,10 @@ public void start() { } for (ServerPlayer player : TwitchSpawn.SERVER.getPlayerList().getPlayers()) { - UUID uuid = player.getUUID(); - TranslatableComponent successText = new TranslatableComponent("commands.twitchspawn.start.success"); - player.sendMessage(successText, uuid); - NetworkManager.CHANNEL.sendTo(new StatusChangedPacket(true), - player.connection.connection, - NetworkDirection.PLAY_TO_CLIENT); + Component successText = Component.translatable("commands.twitchspawn.start.success"); + player.sendSystemMessage(successText); + NetworkManager.CHANNEL.send(new StatusChangedPacket(true), + player.connection.getConnection()); } } @@ -98,13 +95,11 @@ public void stop(CommandSourceStack source, String reason) { if (TwitchSpawn.SERVER != null) { for (ServerPlayer player : TwitchSpawn.SERVER.getPlayerList().getPlayers()) { - UUID uuid = player.getUUID(); - TranslatableComponent successText = new TranslatableComponent("commands.twitchspawn.stop.success", - source == null ? "Server" : source.getTextName(), reason); - player.sendMessage(successText, uuid); - NetworkManager.CHANNEL.sendTo(new StatusChangedPacket(false), - player.connection.connection, - NetworkDirection.PLAY_TO_CLIENT); + Component successText = Component.translatable("commands.twitchspawn.stop.success", + source == null ? "Server" : source.getTextName(), reason); + player.sendSystemMessage(successText); + NetworkManager.CHANNEL.send(new StatusChangedPacket(false), + player.connection.getConnection()); } } } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ChangeAction.java b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ChangeAction.java index a2eb728..5d2b418 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ChangeAction.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ChangeAction.java @@ -1,19 +1,23 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import java.util.LinkedList; +import java.util.List; + import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.item.ItemParser; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; +import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; import net.programmer.igoodie.twitchspawn.util.ExpressionEvaluator; - -import java.util.LinkedList; -import java.util.List; +import net.programmer.igoodie.twitchspawn.util.ItemProcessingHelper; public class ChangeAction extends ItemSelectiveAction { @@ -85,8 +89,9 @@ private void parseItem(List itemPart) throws TSLSyntaxError { EventArguments randomEvent = EventArguments.createRandom("RandomStreamer"); String randomItem = ExpressionEvaluator.replaceExpressions(this.itemRaw, expression -> ExpressionEvaluator.fromArgs(expression, randomEvent)); - new ItemParser(new StringReader(randomItem), true).parse(); + // This is an ugly way, but I do not know if there is other way how to get lookup class. + ItemParser.parseForTesting(BuiltInRegistries.ITEM.asLookup(), new StringReader(randomItem)); } catch (CommandSyntaxException e) { throw new TSLSyntaxError(e.getRawMessage().getString()); } @@ -94,37 +99,41 @@ private void parseItem(List itemPart) throws TSLSyntaxError { @Override protected void performAction(ServerPlayer player, EventArguments args) { - ItemStack itemStack = createItemStack(args); - - if (selectionType == SelectionType.WITH_INDEX) { - getInventory(player, inventoryType).set(inventoryIndex, itemStack.copy()); - - } else if (selectionType == SelectionType.EVERYTHING) { - if (inventoryType == null) { - setAll(player.getInventory().items, itemStack); - setAll(player.getInventory().armor, itemStack); - setAll(player.getInventory().offhand, itemStack); - - } else { - setAll(getInventory(player, inventoryType), itemStack); - } - - } else if (selectionType == SelectionType.RANDOM) { - InventorySlot randomSlot = inventoryType == null + try { + // Why whole in try-catch? Well, I think it fits better here. Can change if not needed. + ItemStack itemStack = ItemProcessingHelper.createItemStack( + this.replaceExpressions(this.itemRaw, args), + this.itemAmount); + + if (this.selectionType == SelectionType.WITH_INDEX) { + this.getInventory(player, this.inventoryType).set(this.inventoryIndex, itemStack.copy()); + } else if (this.selectionType == SelectionType.EVERYTHING) { + if (this.inventoryType == null) { + this.setAll(player.getInventory().items, itemStack); + this.setAll(player.getInventory().armor, itemStack); + this.setAll(player.getInventory().offhand, itemStack); + } else { + this.setAll(getInventory(player, this.inventoryType), itemStack); + } + } else if (this.selectionType == SelectionType.RANDOM) { + InventorySlot randomSlot = this.inventoryType == null ? randomInventorySlot(player, true) - : randomInventorySlot(getInventory(player, inventoryType), true); - if (randomSlot != null) { - randomSlot.inventory.set(randomSlot.index, itemStack.copy()); - } - - } else if (selectionType == SelectionType.ONLY_HELD_ITEM) { - int selectedHotbarIndex = player.getInventory().selected; - player.getInventory().items.set(selectedHotbarIndex, itemStack.copy()); - - } else if (selectionType == SelectionType.HOTBAR) { - for (int i = 0; i <= 8; i++) { - player.getInventory().items.set(i, itemStack.copy()); + : randomInventorySlot(this.getInventory(player, this.inventoryType), true); + + if (randomSlot != null) { + randomSlot.inventory.set(randomSlot.index, itemStack.copy()); + } + } else if (this.selectionType == SelectionType.ONLY_HELD_ITEM) { + int selectedHotbarIndex = player.getInventory().selected; + player.getInventory().items.set(selectedHotbarIndex, itemStack.copy()); + } else if (this.selectionType == SelectionType.HOTBAR) { + for (int i = 0; i <= 8; i++) + { + player.getInventory().items.set(i, itemStack.copy()); + } } + } catch (CommandSyntaxException e) { + TwitchSpawn.LOGGER.error("Failed to parse item: " + this.itemRaw + " with error: " + e.getRawMessage()); } MinecraftServer server = player.getServer(); @@ -132,9 +141,9 @@ protected void performAction(ServerPlayer player, EventArguments args) { if (server != null) { CommandSourceStack commandSource = player.createCommandSourceStack() .withPermission(9999).withSuppressedOutput(); - server.getCommands().performCommand(commandSource, + server.getCommands().performPrefixedCommand(commandSource, "/playsound minecraft:item.armor.equip_leather master @s"); - server.getCommands().performCommand(commandSource, + server.getCommands().performPrefixedCommand(commandSource, "/particle minecraft:entity_effect ~ ~ ~ 2 2 2 0.1 400"); } } @@ -144,20 +153,4 @@ private void setAll(List inventory, ItemStack itemStack) { inventory.set(i, itemStack.copy()); } } - - private ItemStack createItemStack(EventArguments args) { - try { - String input = replaceExpressions(itemRaw, args); - - ItemParser itemParser = new ItemParser(new StringReader(input), true).parse(); - ItemStack itemStack = new ItemStack(itemParser.getItem(), itemAmount); - itemStack.setTag(itemParser.getNbt()); - - return itemStack; - - } catch (CommandSyntaxException e) { - throw new InternalError("Invalid item format occurred after validation... Something fishy here.."); - } - } - } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java index 447da72..5fc0277 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java @@ -62,9 +62,9 @@ protected void performAction(ServerPlayer player, EventArguments args) { if (server != null) { CommandSourceStack commandSource = player.createCommandSourceStack() .withPermission(9999).withSuppressedOutput(); - server.getCommands().performCommand(commandSource, + server.getCommands().performPrefixedCommand(commandSource, "/playsound minecraft:entity.item.break master @s"); - server.getCommands().performCommand(commandSource, + server.getCommands().performPrefixedCommand(commandSource, "/particle minecraft:smoke ~ ~ ~ 2 2 2 0.1 400"); } } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/DropAction.java b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/DropAction.java index 92fe35b..f68ed98 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/DropAction.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/DropAction.java @@ -2,15 +2,18 @@ import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import java.util.List; + import net.minecraft.commands.arguments.item.ItemParser; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; +import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; import net.programmer.igoodie.twitchspawn.util.ExpressionEvaluator; - -import java.util.List; +import net.programmer.igoodie.twitchspawn.util.ItemProcessingHelper; public class DropAction extends TSLAction { @@ -43,8 +46,9 @@ public DropAction(List words) throws TSLSyntaxError { EventArguments randomEvent = EventArguments.createRandom("RandomStreamer"); String randomItem = ExpressionEvaluator.replaceExpressions(this.itemRaw, expression -> ExpressionEvaluator.fromArgs(expression, randomEvent)); - new ItemParser(new StringReader(randomItem), true).parse(); + // This is an ugly way, but I do not know if there is other way how to get lookup class. + ItemParser.parseForTesting(BuiltInRegistries.ITEM.asLookup(), new StringReader(randomItem)); } catch (CommandSyntaxException e) { throw new TSLSyntaxError(e.getRawMessage().getString()); } @@ -52,35 +56,34 @@ public DropAction(List words) throws TSLSyntaxError { @Override protected void performAction(ServerPlayer player, EventArguments args) { - ItemStack itemStack = createItemStack(args); - player.drop(itemStack, false, false); - } - - private ItemStack createItemStack(EventArguments args) { try { - String input = replaceExpressions(itemRaw, args); - - ItemParser itemParser = new ItemParser(new StringReader(input), true).parse(); - ItemStack itemStack = new ItemStack(itemParser.getItem(), itemAmount); - itemStack.setTag(itemParser.getNbt()); - - return itemStack; - + ItemStack itemStack = ItemProcessingHelper.createItemStack( + this.replaceExpressions(this.itemRaw, args), + this.itemAmount); + player.drop(itemStack, false, false); } catch (CommandSyntaxException e) { - throw new InternalError("Invalid item format occurred after validation... Something fishy here.."); + TwitchSpawn.LOGGER.error("Failed to parse item: " + this.itemRaw + " with error: " + e.getRawMessage()); } } + @Override protected String subtitleEvaluator(String expression, EventArguments args) { - ItemStack itemStack = createItemStack(args); + try { + ItemStack itemStack = ItemProcessingHelper.createItemStack( + this.replaceExpressions(this.itemRaw, args), + this.itemAmount); - if (expression.equals("itemName")) - return itemStack.getItem().getName(itemStack).getString(); -// return itemStack.getItem().getName().getString(); // getName() is client only... + if (expression.equals("itemName")) { + return itemStack.getItem().getName(itemStack).getString(); + } - if (expression.equals("itemCount")) - return String.valueOf(itemStack.getCount()); + if (expression.equals("itemCount")) { + return String.valueOf(itemStack.getCount()); + } + } catch (CommandSyntaxException e) { + TwitchSpawn.LOGGER.error("Failed to parse item: " + this.itemRaw + " with error: " + e.getRawMessage()); + } return null; } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java index 9d3ccc2..86ea5fe 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java @@ -37,8 +37,8 @@ protected void performAction(ServerPlayer player, EventArguments args) { for (String command : commands) { TwitchSpawn.SERVER.execute(() -> { int result = TwitchSpawn.SERVER - .getCommands() - .performCommand(source, replaceExpressions(command, args)); + .getCommands() + .performPrefixedCommand(source, replaceExpressions(command, args)); if (result <= 0) { // Wohooo we knew iGoodie liked hacky solutions. ( ? :/ ) // If it yielded an error, and not worked as expected @@ -46,8 +46,8 @@ protected void performAction(ServerPlayer player, EventArguments args) { CommandSourceStack newSource = player.createCommandSourceStack() .withPermission(9999); TwitchSpawn.SERVER - .getCommands() - .performCommand(newSource, replaceExpressions(command, args)); + .getCommands() + .performPrefixedCommand(newSource, replaceExpressions(command, args)); } TwitchSpawn.LOGGER.info("Executed (Status:{}) -> {}", result, replaceExpressions(command, args)); diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java index 5533c47..438f4d0 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java @@ -176,9 +176,8 @@ protected void performAction(ServerPlayer player, EventArguments args) { handleLocalScript(shell, replaceExpressions(shellScript, args)); } else if (scriptLocation == ScriptLocation.REMOTE) { - NetworkManager.CHANNEL.sendTo(new OsRunPacket(shell, replaceExpressions(shellScript, args)), - player.connection.connection, - NetworkDirection.PLAY_TO_CLIENT); + NetworkManager.CHANNEL.send(new OsRunPacket(shell, replaceExpressions(shellScript, args)), + player.connection.getConnection()); } } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java index f2941b0..4d6bdb3 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java @@ -93,9 +93,9 @@ protected void performAction(ServerPlayer player, EventArguments args) { if (server != null) { CommandSourceStack commandSource = player.createCommandSourceStack() .withPermission(9999).withSuppressedOutput(); - server.getCommands().performCommand(commandSource, + server.getCommands().performPrefixedCommand(commandSource, "/playsound minecraft:block.conduit.activate master @s"); - server.getCommands().performCommand(commandSource, + server.getCommands().performPrefixedCommand(commandSource, "/particle minecraft:end_rod ~ ~ ~ 2 2 2 0.0001 400"); } } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java index 4375afe..94d4407 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java @@ -69,14 +69,14 @@ private String validateCoordinateExpression(String expression) throws TSLSyntaxE @Override protected void performAction(ServerPlayer player, EventArguments args) { String command = String.format("/summon %s %s %s %s %s", - entityType.getRegistryName(), + entityType.builtInRegistryHolder().key().location(), rawCoordX, rawCoordY, rawCoordZ, replaceExpressions(rawNbt, args)); - player.getServer().getCommands().performCommand(player.createCommandSourceStack() - .withPermission(9999).withSuppressedOutput(), command); + player.getServer().getCommands().performPrefixedCommand(player.createCommandSourceStack() + .withPermission(9999).withSuppressedOutput(), command); } @Override diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java index 7209ea6..e332026 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java @@ -1,8 +1,13 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + import com.google.gson.JsonArray; +import java.util.LinkedList; +import java.util.List; + +import net.minecraft.core.Holder; +import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; @@ -23,10 +28,6 @@ import net.programmer.igoodie.twitchspawn.util.ExpressionEvaluator; import net.programmer.igoodie.twitchspawn.util.MCPHelpers; -import java.util.LinkedList; -import java.util.List; -import java.util.UUID; - public abstract class TSLAction implements TSLFlowNode { private static final int DEFAULT_FADE_IN_TICKS = 10; @@ -209,7 +210,18 @@ protected void notifyPlayer(ServerPlayer player, String title, String subtitle) SoundEvent soundLocation = SoundEvents.PLAYER_LEVELUP; SoundSource category = SoundSource.MASTER; Vec3 position = player.position(); - ClientboundSoundPacket packetSound = new ClientboundSoundPacket(soundLocation, category, position.x, position.y, position.z, volume, pitch); + Holder lookup = player.getServer().registryAccess(). + registryOrThrow(Registries.SOUND_EVENT). + wrapAsHolder(soundLocation); + + ClientboundSoundPacket packetSound = new ClientboundSoundPacket(lookup, + category, + position.x, + position.y, + position.z, + volume, + pitch, + 0); player.connection.send(packetSound); if (ConfigManager.PREFERENCES.messageDisplay == PreferencesConfig.MessageDisplay.DISABLED) @@ -239,9 +251,8 @@ protected void notifyPlayer(ServerPlayer player, String title, String subtitle) } if (ConfigManager.PREFERENCES.messageDisplay == PreferencesConfig.MessageDisplay.CHAT) { - UUID uuid = player.getUUID(); - if (text != null) player.sendMessage(MCPHelpers.merge(new TextComponent(">> "), text), uuid); - if (subtext != null) player.sendMessage(MCPHelpers.merge(new TextComponent(">> "), subtext), uuid); + if (text != null) player.sendSystemMessage(MCPHelpers.merge(Component.translatable(">> "), text)); + if (subtext != null) player.sendSystemMessage(MCPHelpers.merge(Component.translatable(">> "), subtext)); } } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java index a9b84f6..50b63c5 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java @@ -73,9 +73,9 @@ protected void performAction(ServerPlayer player, EventArguments args) { if (server != null) { CommandSourceStack commandSource = player.createCommandSourceStack() .withPermission(9999).withSuppressedOutput(); - server.getCommands().performCommand(commandSource, + server.getCommands().performPrefixedCommand(commandSource, "/playsound minecraft:entity.ender_pearl.throw master @s"); - server.getCommands().performCommand(commandSource, + server.getCommands().performPrefixedCommand(commandSource, "/particle minecraft:witch ~ ~ ~ 2 2 2 0.1 400"); } } diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/util/ItemProcessingHelper.java b/src/main/java/net/programmer/igoodie/twitchspawn/util/ItemProcessingHelper.java new file mode 100644 index 0000000..a8e2f1b --- /dev/null +++ b/src/main/java/net/programmer/igoodie/twitchspawn/util/ItemProcessingHelper.java @@ -0,0 +1,40 @@ +package net.programmer.igoodie.twitchspawn.util; + + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.datafixers.util.Either; + +import net.minecraft.commands.arguments.item.ItemParser; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.item.ItemStack; + + +/** + * This class provides helper methods for item processing. + */ +public class ItemProcessingHelper +{ + /** + * Creates an item stack from given item input and item amount. + * @param itemInput Item input. + * @param itemAmount Item amount. + * @return Created item stack. + * @throws CommandSyntaxException If something goes wrong during parsing. + */ + public static ItemStack createItemStack(String itemInput, int itemAmount) throws CommandSyntaxException + { + Either itemResult = + ItemParser.parseForTesting(BuiltInRegistries.ITEM.asLookup(), new StringReader(itemInput)); + + if (itemResult.left().isPresent()) + { + ItemStack itemStack = new ItemStack(itemResult.left().get().item(), itemAmount); + itemResult.ifRight(tagResult -> itemStack.setTag(tagResult.nbt())); + + return itemStack; + } + + throw new InternalError("Invalid item format occurred after validation... Something fishy here.."); + } +} From 2d8ffec891f7016e30b96c491d053174f93fef59 Mon Sep 17 00:00:00 2001 From: BONNe Date: Fri, 22 Dec 2023 20:42:19 +0200 Subject: [PATCH 02/15] Fixes null-pointer for sub-titles --- .../igoodie/twitchspawn/tslanguage/action/TSLAction.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java index e332026..109c354 100644 --- a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java +++ b/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java @@ -231,7 +231,9 @@ protected void notifyPlayer(ServerPlayer player, String title, String subtitle) Component text = MCPHelpers.fromJsonLenient(title); Component subtext = MCPHelpers.fromJsonLenient(subtitle); - if (subtext != null && subtext.getString().equals("NOTHING_0xDEADC0DE_0xDEADBEEF")) { + if (subtext == null) { + subtext = Component.nullToEmpty(""); // You cannot send NULL pockets. + } else if (subtext.getString().equals("NOTHING_0xDEADC0DE_0xDEADBEEF")) { return; // Stop here since it was a DISPLAYING NOTHING statement } From 672faa20f23f952a06765de85bde52b7997dca89 Mon Sep 17 00:00:00 2001 From: BONNe Date: Sun, 24 Dec 2023 19:57:27 +0200 Subject: [PATCH 03/15] Init architectury project --- .gitignore | 1 + build.gradle | 215 ++++-------------- common/build.gradle | 37 +++ .../igoodie/twitchspawn/TwitchSpawn.java | 0 .../twitchspawn/TwitchSpawnLoadingErrors.java | 0 .../client/gui/GlobalChatCooldownOverlay.java | 0 .../client/gui/StatusIndicatorOverlay.java | 0 .../twitchspawn/command/CommandArguments.java | 0 .../command/RulesetNameArgumentType.java | 0 .../command/StreamerArgumentType.java | 0 .../command/TSLWordsArgumentType.java | 0 .../command/TwitchSpawnCommand.java | 0 .../configuration/ConfigManager.java | 0 .../configuration/CredentialsConfig.java | 0 .../configuration/PreferencesConfig.java | 0 .../configuration/RulesConfig.java | 0 .../configuration/SubtitlesConfig.java | 0 .../configuration/TextComponentConfig.java | 0 .../configuration/TitlesConfig.java | 0 .../twitchspawn/easteregg/Developers.java | 0 .../twitchspawn/eventqueue/EventQueue.java | 0 .../eventqueue/EventQueueState.java | 0 .../eventqueue/EventQueueTask.java | 0 .../twitchspawn/network/NetworkManager.java | 0 .../packet/GlobalChatCooldownPacket.java | 0 .../network/packet/OsRunPacket.java | 0 .../network/packet/StatusChangedPacket.java | 0 .../registries/TwitchSpawnAugmentTypes.java | 0 .../registries/TwitchSpawnSoundEvent.java | 0 .../igoodie/twitchspawn/tracer/Platform.java | 0 .../twitchspawn/tracer/SocketIOTracer.java | 0 .../twitchspawn/tracer/TraceManager.java | 0 .../twitchspawn/tracer/WebSocketTracer.java | 0 .../tracer/chat/TwitchChatTracer.java | 0 .../tracer/model/TwitchChatMessage.java | 0 .../socket/StreamElementsSocketTracer.java | 0 .../tracer/socket/StreamlabsSocketTracer.java | 0 .../tracer/socket/TwitchPubSubTracer.java | 0 .../twitchspawn/tslanguage/TSLFlowNode.java | 0 .../twitchspawn/tslanguage/TSLRuleset.java | 0 .../tslanguage/TSLRulesetCollection.java | 0 .../tslanguage/action/BothAction.java | 0 .../tslanguage/action/ChangeAction.java | 0 .../tslanguage/action/ClearAction.java | 0 .../tslanguage/action/DropAction.java | 0 .../tslanguage/action/EitherAction.java | 0 .../tslanguage/action/ExecuteAction.java | 0 .../tslanguage/action/ForAction.java | 0 .../action/ItemSelectiveAction.java | 0 .../tslanguage/action/NothingAction.java | 0 .../tslanguage/action/OsRunAction.java | 0 .../tslanguage/action/ReflectAction.java | 0 .../tslanguage/action/ShuffleAction.java | 0 .../tslanguage/action/SummonAction.java | 0 .../tslanguage/action/TSLAction.java | 0 .../tslanguage/action/ThrowAction.java | 0 .../tslanguage/action/WaitAction.java | 0 .../tslanguage/event/EventArguments.java | 0 .../tslanguage/event/TSLEvent.java | 0 .../tslanguage/event/TSLEventPair.java | 0 .../event/builder/DonationBuilder.java | 0 .../builder/DonorDriveDonationBuilder.java | 0 .../event/builder/EventBuilder.java | 0 .../event/builder/ExtraLifeBuilder.java | 0 .../event/builder/PatreonBuilder.java | 0 .../event/builder/TiltifyBuilder.java | 0 .../event/builder/TreatStreamBuilder.java | 0 .../event/builder/TwitchFollowBuilder.java | 0 .../tslanguage/keyword/TSLActionKeyword.java | 0 .../keyword/TSLComparatorSymbol.java | 0 .../tslanguage/keyword/TSLEventKeyword.java | 0 .../keyword/TSLPredicateProperty.java | 0 .../tslanguage/parser/TSLParser.java | 0 .../tslanguage/parser/TSLRuleTokenizer.java | 0 .../tslanguage/parser/TSLSyntaxError.java | 0 .../tslanguage/parser/TSLSyntaxErrors.java | 0 .../tslanguage/parser/TSLTokenizer.java | 0 .../tslanguage/predicate/BasicComparator.java | 0 .../predicate/ContainsComparator.java | 0 .../predicate/EqualsComparator.java | 0 .../predicate/GreaterThanComparator.java | 0 .../predicate/GreaterThanOrEqComparator.java | 0 .../predicate/InRangeComparator.java | 0 .../tslanguage/predicate/IsComparator.java | 0 .../predicate/LessThanComparator.java | 0 .../predicate/LessThanOrEqComparator.java | 0 .../predicate/PostfixComparator.java | 0 .../predicate/PrefixComparator.java | 0 .../tslanguage/predicate/TSLComparator.java | 0 .../tslanguage/predicate/TSLPredicate.java | 0 .../twitchspawn/udl/NotepadUDLUpdater.java | 0 .../twitchspawn/util/CooldownBucket.java | 0 .../twitchspawn/util/ExpressionEvaluator.java | 0 .../igoodie/twitchspawn/util/GsonUtils.java | 0 .../util/ItemProcessingHelper.java | 0 .../igoodie/twitchspawn/util/JSONUtils.java | 0 .../igoodie/twitchspawn/util/MCPHelpers.java | 0 .../util/PercentageRandomizer.java | 0 .../igoodie/twitchspawn/util/TSHelper.java | 0 .../src}/main/resources/META-INF/mods.toml | 0 .../twitchspawn/default/preferences.toml | 0 .../twitchspawn/default/rules.default.tsl | 0 .../default/subtitles.default.json | 0 .../twitchspawn/default/titles.default.json | 0 .../assets/twitchspawn/lang/de_de.json | 0 .../assets/twitchspawn/lang/en_us.json | 0 .../assets/twitchspawn/lang/es_es.json | 74 +++--- .../assets/twitchspawn/lang/fr_fr.json | 0 .../assets/twitchspawn/lang/it_it.json | 0 .../resources/assets/twitchspawn/sounds.json | 0 .../assets/twitchspawn/sounds/pop_in.ogg | Bin .../assets/twitchspawn/sounds/pop_out.ogg | Bin .../assets/twitchspawn/textures/cooldown.png | Bin .../twitchspawn/textures/indicators.png | Bin .../assets/twitchspawn/udl/tsl_udl.xml | 0 .../src}/main/resources/pack.mcmeta | 0 {src => common/src}/main/resources/pack.png | Bin .../src}/test/resources/comment_expected.tsl | 0 .../src}/test/resources/comment_test.tsl | 0 {src => common/src}/test/resources/test.toml | 0 fabric/build.gradle | 85 +++++++ fabric/src/main/resources/fabric.mod.json | 27 +++ .../main/resources/twitchspawn.mixins.json | 13 ++ forge/build.gradle | 94 ++++++++ forge/gradle.properties | 1 + forge/src/main/resources/META-INF/mods.toml | 72 ++++++ forge/src/main/resources/pack.mcmeta | 7 + .../main/resources/twitchspawn.mixins.json | 13 ++ gradle.properties | 22 +- gradle/wrapper/gradle-wrapper.jar | Bin 62076 -> 61608 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 7 +- settings.gradle | 15 +- 133 files changed, 450 insertions(+), 235 deletions(-) create mode 100644 common/build.gradle rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawnLoadingErrors.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/command/CommandArguments.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/command/RulesetNameArgumentType.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/command/TSLWordsArgumentType.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/configuration/ConfigManager.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/configuration/CredentialsConfig.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/configuration/PreferencesConfig.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/configuration/RulesConfig.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/configuration/SubtitlesConfig.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/configuration/TextComponentConfig.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/configuration/TitlesConfig.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/easteregg/Developers.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueueState.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueueTask.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tracer/Platform.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tracer/SocketIOTracer.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tracer/WebSocketTracer.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tracer/chat/TwitchChatTracer.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tracer/model/TwitchChatMessage.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamElementsSocketTracer.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamlabsSocketTracer.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/TwitchPubSubTracer.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLFlowNode.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRuleset.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRulesetCollection.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/BothAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ChangeAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/DropAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/EitherAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ForAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ItemSelectiveAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/NothingAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ReflectAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/WaitAction.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/EventArguments.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEvent.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEventPair.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonationBuilder.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonorDriveDonationBuilder.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/EventBuilder.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/ExtraLifeBuilder.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/PatreonBuilder.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TiltifyBuilder.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TreatStreamBuilder.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TwitchFollowBuilder.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLActionKeyword.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLComparatorSymbol.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLEventKeyword.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLPredicateProperty.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLParser.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLRuleTokenizer.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLSyntaxError.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLSyntaxErrors.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLTokenizer.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/BasicComparator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/ContainsComparator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/EqualsComparator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/GreaterThanComparator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/GreaterThanOrEqComparator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/InRangeComparator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/IsComparator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/LessThanComparator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/LessThanOrEqComparator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/PostfixComparator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/PrefixComparator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLComparator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLPredicate.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/udl/NotepadUDLUpdater.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/util/CooldownBucket.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/util/ExpressionEvaluator.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/util/GsonUtils.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/util/ItemProcessingHelper.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/util/JSONUtils.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/util/MCPHelpers.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/util/PercentageRandomizer.java (100%) rename {src => common/src}/main/java/net/programmer/igoodie/twitchspawn/util/TSHelper.java (100%) rename {src => common/src}/main/resources/META-INF/mods.toml (100%) rename {src => common/src}/main/resources/assets/twitchspawn/default/preferences.toml (100%) rename {src => common/src}/main/resources/assets/twitchspawn/default/rules.default.tsl (100%) rename {src => common/src}/main/resources/assets/twitchspawn/default/subtitles.default.json (100%) rename {src => common/src}/main/resources/assets/twitchspawn/default/titles.default.json (100%) rename {src => common/src}/main/resources/assets/twitchspawn/lang/de_de.json (100%) rename {src => common/src}/main/resources/assets/twitchspawn/lang/en_us.json (100%) rename {src => common/src}/main/resources/assets/twitchspawn/lang/es_es.json (98%) rename {src => common/src}/main/resources/assets/twitchspawn/lang/fr_fr.json (100%) rename {src => common/src}/main/resources/assets/twitchspawn/lang/it_it.json (100%) rename {src => common/src}/main/resources/assets/twitchspawn/sounds.json (100%) rename {src => common/src}/main/resources/assets/twitchspawn/sounds/pop_in.ogg (100%) rename {src => common/src}/main/resources/assets/twitchspawn/sounds/pop_out.ogg (100%) rename {src => common/src}/main/resources/assets/twitchspawn/textures/cooldown.png (100%) rename {src => common/src}/main/resources/assets/twitchspawn/textures/indicators.png (100%) rename {src => common/src}/main/resources/assets/twitchspawn/udl/tsl_udl.xml (100%) rename {src => common/src}/main/resources/pack.mcmeta (100%) rename {src => common/src}/main/resources/pack.png (100%) rename {src => common/src}/test/resources/comment_expected.tsl (100%) rename {src => common/src}/test/resources/comment_test.tsl (100%) rename {src => common/src}/test/resources/test.toml (100%) create mode 100644 fabric/build.gradle create mode 100644 fabric/src/main/resources/fabric.mod.json create mode 100644 fabric/src/main/resources/twitchspawn.mixins.json create mode 100644 forge/build.gradle create mode 100644 forge/gradle.properties create mode 100644 forge/src/main/resources/META-INF/mods.toml create mode 100644 forge/src/main/resources/pack.mcmeta create mode 100644 forge/src/main/resources/twitchspawn.mixins.json diff --git a/.gitignore b/.gitignore index c63ba5d..ba3bd7e 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,4 @@ gradle-app.setting **/build/ # End of https://www.gitignore.io/api/java,gradle,intellij +/common/src/main/corrected/ diff --git a/build.gradle b/build.gradle index d7912bb..6a2bf78 100644 --- a/build.gradle +++ b/build.gradle @@ -1,194 +1,59 @@ -buildscript { - dependencies { - classpath 'gradle.plugin.com.github.johnrengelman:shadow:7.1.2' - } -} - plugins { - id 'java' - id 'idea' - id 'maven-publish' - id 'net.minecraftforge.gradle' version '[6.0.16,6.2)' -} - -apply plugin: 'com.github.johnrengelman.shadow' - -version = mod_version -group = "igoodie.twitchspawn" -archivesBaseName = "twitchspawn_" + minecraft_version - -java.toolchain.languageVersion = JavaLanguageVersion.of(17) - -println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) - -minecraft { - // The mappings can be changed at any time, and must be in the following format. - // snapshot_YYYYMMDD Snapshot are built nightly. - // stable_# Stables are built at the discretion of the MCP team. - // Use non-default mappings at your own risk. they may not always work. - // Simply re-run your setup task after changing the mappings to update your workspace. - mappings channel: mcpMappings_channel, version: mcpMappings_version - // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. - - copyIdeResources = true - - // Default run configurations. - // These can be tweaked, removed, or duplicated as needed. - runs { - // applies to all the run configs below - configureEach { - // Recommended logging data for a userdev environment - property 'forge.logging.markers', 'REGISTRIES' - - // Recommended logging level for the console - property 'forge.logging.console.level', 'debug' - - mods { - "${mod_id}" { - source sourceSets.main - } - } - } - - client { - workingDirectory project.file('run/client') - // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. - property 'forge.enabledGameTestNamespaces', mod_id - } - - server { - workingDirectory project.file('run/server') - property 'forge.enabledGameTestNamespaces', mod_id - args '--nogui' - } - - // This run config launches GameTestServer and runs all registered gametests, then exits. - gameTestServer { - property 'forge.enabledGameTestNamespaces', mod_id - } - - data { - // example of overriding the workingDirectory set in configureEach above - workingDirectory project.file('run-data') - - // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. - args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') - } - } -} - -repositories { - mavenCentral() + id "architectury-plugin" version "3.4-SNAPSHOT" + id "dev.architectury.loom" version "1.4-SNAPSHOT" apply false } -configurations { - shade - implementation.extendsFrom shade +architectury { + minecraft = rootProject.minecraft_version } -dependencies { - // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed - // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied. - // The userdev artifact is a special name and will get all sorts of transformations applied to it. - minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" +subprojects { + apply plugin: "dev.architectury.loom" - // Nightly Config by Electronwill -// shadow group: 'com.electronwill.night-config', name: 'core', version: '3.6.0' -// shadow group: 'com.electronwill.night-config', name: 'toml', version: '3.6.0' - - // SocketIO Client - shade "io.socket:socket.io-client:1.0.0" - minecraftLibrary "io.socket:socket.io-client:1.0.0" - - // JUnit 5 for testings - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.0' - testImplementation 'org.junit.jupiter:junit-jupiter-params:5.5.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.0' - - // For more info... - // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html - // http://www.gradle.org/docs/current/userguide/dependency_management.html - -} - -//// Fix the classpath the right way and once and for all -//afterEvaluate { -// // Collect deps in runtimeClasspath but NOT in minecraft -// def deps = (configurations.runtimeClasspath - configurations.minecraft).join(';') -// // Add deps to classpath -// minecraft.runs.each { run -> -// run.token 'minecraft_classpath', deps -// } -//} - -//jar { -// configurations.shade.each { dep -> -// from(project.zipTree(dep)) { -// exclude 'META-INF', 'META-INF/**' -// } -// } -//} - -//shadowJar { -// configurations = [project.configurations.shadow] -// classifier "" -//// relocate 'com.electronwill.nightconfig.core', "com.electronwill.nightconfig.${mod_id}.core" -//// relocate 'com.electronwill.nightconfig.toml', "com.electronwill.nightconfig.${mod_id}.toml" -//// relocate "io.socket.client", "io.socket.${mod_id}.client" -//} - -// ==================================== + loom { + silentMojangMappingsLicense() + } -// Example for how to get properties into the manifest for reading by the runtime.. -jar { - archiveClassifier = 'slim' - //noinspection GroovyAssignabilityCheck - manifest { - attributes([ - "Specification-Title" : mod_id, - "Specification-Vendor" : mod_group, - "Specification-Version" : "1.0", - "Implementation-Title" : project.name, - "Implementation-Version" : "${mod_version}", - "Implementation-Vendor" : mod_group, - "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") - ]) + dependencies { + minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" + // The following line declares the mojmap mappings, you may use other mappings as well + mappings loom.officialMojangMappings() + // The following line declares the yarn mappings you may select this one as well. + // mappings "net.fabricmc:yarn:@YARN_MAPPINGS@:v2" } } -shadowJar { - archiveClassifier = '' - configurations = [project.configurations.shade] - finalizedBy 'reobfShadowJar' -} +allprojects { + apply plugin: "java" + apply plugin: "architectury-plugin" + apply plugin: "maven-publish" -assemble.dependsOn shadowJar + base { + archivesName = rootProject.archives_base_name + } -reobf { - shadowJar {} -} + version = rootProject.mod_version + group = rootProject.maven_group -// ==================================== + repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. + } -// Example configuration to allow publishing using the maven-publish task -// This is the preferred method to reobfuscate your jar file -jar.finalizedBy('reobfJar') -// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing -//publish.dependsOn('reobfJar') -publishing { - publications { - mavenJava(MavenPublication) { - artifact jar - } + dependencies { + implementation 'org.json:json:20231013' } - repositories { - maven { - url "file:///${project.projectDir}/mcmodsrepo" - } + + tasks.withType(JavaCompile) { + options.encoding = "UTF-8" + options.release.set(17) } -} -test { - useJUnitPlatform() + java { + withSourcesJar() + } } diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 0000000..0933e7b --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,37 @@ +plugins { + id "com.github.johnrengelman.shadow" version "7.1.2" +} + + +dependencies { + // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies + // Do NOT use other classes from fabric loader + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + // Remove the next line if you don't want to depend on the API + modApi "dev.architectury:architectury:${rootProject.architectury_version}" + + // Add JSON dependency + compileOnly "com.electronwill.night-config:core:3.6.4" + compileOnly "com.electronwill.night-config:toml:3.6.4" + + implementation 'com.squareup.okhttp3:okhttp:3.8.1' + implementation 'io.socket:socket.io-client:1.0.2' +} + +architectury { + common("fabric", "forge") +} + +publishing { + publications { + mavenCommon(MavenPublication) { + artifactId = rootProject.archives_base_name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} \ No newline at end of file diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawnLoadingErrors.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawnLoadingErrors.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawnLoadingErrors.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawnLoadingErrors.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/command/CommandArguments.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/CommandArguments.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/command/CommandArguments.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/command/CommandArguments.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/command/RulesetNameArgumentType.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/RulesetNameArgumentType.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/command/RulesetNameArgumentType.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/command/RulesetNameArgumentType.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/command/TSLWordsArgumentType.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TSLWordsArgumentType.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/command/TSLWordsArgumentType.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/command/TSLWordsArgumentType.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/command/TwitchSpawnCommand.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/configuration/ConfigManager.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/ConfigManager.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/configuration/ConfigManager.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/ConfigManager.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/configuration/CredentialsConfig.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/CredentialsConfig.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/configuration/CredentialsConfig.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/CredentialsConfig.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/configuration/PreferencesConfig.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/PreferencesConfig.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/configuration/PreferencesConfig.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/PreferencesConfig.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/configuration/RulesConfig.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/RulesConfig.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/configuration/RulesConfig.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/RulesConfig.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/configuration/SubtitlesConfig.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/SubtitlesConfig.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/configuration/SubtitlesConfig.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/SubtitlesConfig.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TextComponentConfig.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TextComponentConfig.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/configuration/TextComponentConfig.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TextComponentConfig.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TitlesConfig.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TitlesConfig.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/configuration/TitlesConfig.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TitlesConfig.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/easteregg/Developers.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/easteregg/Developers.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/easteregg/Developers.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/easteregg/Developers.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueueState.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueueState.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueueState.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueueState.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueueTask.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueueTask.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueueTask.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueueTask.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tracer/Platform.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/Platform.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tracer/Platform.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/Platform.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tracer/SocketIOTracer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/SocketIOTracer.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tracer/SocketIOTracer.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/SocketIOTracer.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tracer/WebSocketTracer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/WebSocketTracer.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tracer/WebSocketTracer.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/WebSocketTracer.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tracer/chat/TwitchChatTracer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/chat/TwitchChatTracer.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tracer/chat/TwitchChatTracer.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/chat/TwitchChatTracer.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tracer/model/TwitchChatMessage.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/model/TwitchChatMessage.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tracer/model/TwitchChatMessage.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/model/TwitchChatMessage.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamElementsSocketTracer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamElementsSocketTracer.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamElementsSocketTracer.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamElementsSocketTracer.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamlabsSocketTracer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamlabsSocketTracer.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamlabsSocketTracer.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamlabsSocketTracer.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/TwitchPubSubTracer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/TwitchPubSubTracer.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/TwitchPubSubTracer.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/TwitchPubSubTracer.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLFlowNode.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLFlowNode.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLFlowNode.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLFlowNode.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRuleset.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRuleset.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRuleset.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRuleset.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRulesetCollection.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRulesetCollection.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRulesetCollection.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRulesetCollection.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/BothAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/BothAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/BothAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/BothAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ChangeAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ChangeAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ChangeAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ChangeAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/DropAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/DropAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/DropAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/DropAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/EitherAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/EitherAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/EitherAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/EitherAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ForAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ForAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ForAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ForAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ItemSelectiveAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ItemSelectiveAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ItemSelectiveAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ItemSelectiveAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/NothingAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/NothingAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/NothingAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/NothingAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ReflectAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ReflectAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ReflectAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ReflectAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/WaitAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/WaitAction.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/WaitAction.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/WaitAction.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/EventArguments.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/EventArguments.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/EventArguments.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/EventArguments.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEvent.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEvent.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEvent.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEvent.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEventPair.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEventPair.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEventPair.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEventPair.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonationBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonationBuilder.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonationBuilder.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonationBuilder.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonorDriveDonationBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonorDriveDonationBuilder.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonorDriveDonationBuilder.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonorDriveDonationBuilder.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/EventBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/EventBuilder.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/EventBuilder.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/EventBuilder.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/ExtraLifeBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/ExtraLifeBuilder.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/ExtraLifeBuilder.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/ExtraLifeBuilder.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/PatreonBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/PatreonBuilder.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/PatreonBuilder.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/PatreonBuilder.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TiltifyBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TiltifyBuilder.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TiltifyBuilder.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TiltifyBuilder.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TreatStreamBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TreatStreamBuilder.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TreatStreamBuilder.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TreatStreamBuilder.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TwitchFollowBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TwitchFollowBuilder.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TwitchFollowBuilder.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TwitchFollowBuilder.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLActionKeyword.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLActionKeyword.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLActionKeyword.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLActionKeyword.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLComparatorSymbol.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLComparatorSymbol.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLComparatorSymbol.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLComparatorSymbol.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLEventKeyword.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLEventKeyword.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLEventKeyword.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLEventKeyword.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLPredicateProperty.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLPredicateProperty.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLPredicateProperty.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLPredicateProperty.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLParser.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLParser.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLParser.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLParser.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLRuleTokenizer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLRuleTokenizer.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLRuleTokenizer.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLRuleTokenizer.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLSyntaxError.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLSyntaxError.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLSyntaxError.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLSyntaxError.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLSyntaxErrors.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLSyntaxErrors.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLSyntaxErrors.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLSyntaxErrors.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLTokenizer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLTokenizer.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLTokenizer.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLTokenizer.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/BasicComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/BasicComparator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/BasicComparator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/BasicComparator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/ContainsComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/ContainsComparator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/ContainsComparator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/ContainsComparator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/EqualsComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/EqualsComparator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/EqualsComparator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/EqualsComparator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/GreaterThanComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/GreaterThanComparator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/GreaterThanComparator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/GreaterThanComparator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/GreaterThanOrEqComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/GreaterThanOrEqComparator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/GreaterThanOrEqComparator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/GreaterThanOrEqComparator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/InRangeComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/InRangeComparator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/InRangeComparator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/InRangeComparator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/IsComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/IsComparator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/IsComparator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/IsComparator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/LessThanComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/LessThanComparator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/LessThanComparator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/LessThanComparator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/LessThanOrEqComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/LessThanOrEqComparator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/LessThanOrEqComparator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/LessThanOrEqComparator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/PostfixComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/PostfixComparator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/PostfixComparator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/PostfixComparator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/PrefixComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/PrefixComparator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/PrefixComparator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/PrefixComparator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLComparator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLComparator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLComparator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLPredicate.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLPredicate.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLPredicate.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLPredicate.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/udl/NotepadUDLUpdater.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/udl/NotepadUDLUpdater.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/udl/NotepadUDLUpdater.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/udl/NotepadUDLUpdater.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/util/CooldownBucket.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/CooldownBucket.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/util/CooldownBucket.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/util/CooldownBucket.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/util/ExpressionEvaluator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/ExpressionEvaluator.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/util/ExpressionEvaluator.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/util/ExpressionEvaluator.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/util/GsonUtils.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/GsonUtils.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/util/GsonUtils.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/util/GsonUtils.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/util/ItemProcessingHelper.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/ItemProcessingHelper.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/util/ItemProcessingHelper.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/util/ItemProcessingHelper.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/util/JSONUtils.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/JSONUtils.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/util/JSONUtils.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/util/JSONUtils.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/util/MCPHelpers.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/MCPHelpers.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/util/MCPHelpers.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/util/MCPHelpers.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/util/PercentageRandomizer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/PercentageRandomizer.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/util/PercentageRandomizer.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/util/PercentageRandomizer.java diff --git a/src/main/java/net/programmer/igoodie/twitchspawn/util/TSHelper.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/TSHelper.java similarity index 100% rename from src/main/java/net/programmer/igoodie/twitchspawn/util/TSHelper.java rename to common/src/main/java/net/programmer/igoodie/twitchspawn/util/TSHelper.java diff --git a/src/main/resources/META-INF/mods.toml b/common/src/main/resources/META-INF/mods.toml similarity index 100% rename from src/main/resources/META-INF/mods.toml rename to common/src/main/resources/META-INF/mods.toml diff --git a/src/main/resources/assets/twitchspawn/default/preferences.toml b/common/src/main/resources/assets/twitchspawn/default/preferences.toml similarity index 100% rename from src/main/resources/assets/twitchspawn/default/preferences.toml rename to common/src/main/resources/assets/twitchspawn/default/preferences.toml diff --git a/src/main/resources/assets/twitchspawn/default/rules.default.tsl b/common/src/main/resources/assets/twitchspawn/default/rules.default.tsl similarity index 100% rename from src/main/resources/assets/twitchspawn/default/rules.default.tsl rename to common/src/main/resources/assets/twitchspawn/default/rules.default.tsl diff --git a/src/main/resources/assets/twitchspawn/default/subtitles.default.json b/common/src/main/resources/assets/twitchspawn/default/subtitles.default.json similarity index 100% rename from src/main/resources/assets/twitchspawn/default/subtitles.default.json rename to common/src/main/resources/assets/twitchspawn/default/subtitles.default.json diff --git a/src/main/resources/assets/twitchspawn/default/titles.default.json b/common/src/main/resources/assets/twitchspawn/default/titles.default.json similarity index 100% rename from src/main/resources/assets/twitchspawn/default/titles.default.json rename to common/src/main/resources/assets/twitchspawn/default/titles.default.json diff --git a/src/main/resources/assets/twitchspawn/lang/de_de.json b/common/src/main/resources/assets/twitchspawn/lang/de_de.json similarity index 100% rename from src/main/resources/assets/twitchspawn/lang/de_de.json rename to common/src/main/resources/assets/twitchspawn/lang/de_de.json diff --git a/src/main/resources/assets/twitchspawn/lang/en_us.json b/common/src/main/resources/assets/twitchspawn/lang/en_us.json similarity index 100% rename from src/main/resources/assets/twitchspawn/lang/en_us.json rename to common/src/main/resources/assets/twitchspawn/lang/en_us.json diff --git a/src/main/resources/assets/twitchspawn/lang/es_es.json b/common/src/main/resources/assets/twitchspawn/lang/es_es.json similarity index 98% rename from src/main/resources/assets/twitchspawn/lang/es_es.json rename to common/src/main/resources/assets/twitchspawn/lang/es_es.json index 656940c..f717319 100644 --- a/src/main/resources/assets/twitchspawn/lang/es_es.json +++ b/common/src/main/resources/assets/twitchspawn/lang/es_es.json @@ -1,38 +1,38 @@ - -{ - "modloader.twitchspawn.error.tsl": "Error de TSL: §4{2}", - "modloader.twitchspawn.error.json": "Error de JSON: §4{2}", - "modloader.twitchspawn.error.toml": "Error de TOML: §4{2}", - "modloader.twitchspawn.error.unknown": "Error Desconocido: §4{2} ({3})", - - "commands.twitchspawn.reloadcfg.success": "§3>> ¡Se han recargado exitosamente todas las configuraciones!", - "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Recarga Fallida. Errores de Sintaxis:\n{0}", - "commands.twitchspawn.reloadcfg.already_started": "§4>> TwitchSpawn debe ser detenido para poder recargar las configuraciones.", - "commands.twitchspawn.reloadcfg.no_perm": "§4>> No tienes permiso para recargar las configuraciones de TwitchSpawn.", - - "commands.twitchspawn.status.on": "§3>> TwitchSpawn se esta ejecutando. [ON]", - "commands.twitchspawn.status.off": "§3>> TwitchSpawn no se esta ejecutando [OFF]", - - "commands.twitchspawn.start.success": "§a>> ¡TwitchSpawn ha iniciado en este servidor!", - "commands.twitchspawn.start.illegal_state": "§4>> TwitchSpawn ya se esta ejecutando.", - "commands.twitchspawn.start.no_perm": "§4>> No tienes permiso para iniciar TwitchSpawn.", - - "commands.twitchspawn.stop.success": "§6>> TwitchSpawn se ha detenido por {0} (Razon: {1})", - "commands.twitchspawn.stop.illegal_state": "§4>> TwitchSpawn ya esta apagado.", - "commands.twitchspawn.stop.no_perm": "§4>> No tienes permiso para detener TwitchSpawn.", - - "commands.twitchspawn.rules.list": "§3>> Lista de Reglas cargadas para: {0}", - "commands.twitchspawn.rules.default": "§3>> La Lista de Reglas por defecto incluye:\n{1}", - "commands.twitchspawn.rules.one": "§3>> Lista de Recarga caragada para {0} e incluye:\n{1}", - "commands.twitchspawn.rules.one.fail": "§4>> Ninguna Lista de Reglas ha sido cargada para {0}", - - "commands.twitchspawn.simulate.missing": "§4>> Falta el nombre del evento en el objeto de simulación. Esperado: \"event\" field.", - "commands.twitchspawn.simulate.invalid_event": "§4>> Nombre de evento invalido -> {0}", - "commands.twitchspawn.simulate.success": "§a>> Simulacion ejecutada {0}", - "commands.twitchspawn.simulate.no_perm": "§4>> No tienes permiso para simular un evento.", - - "commands.twitchspawn.test.not_found": "§4>> Ninguna Lista de Reglas asociada con {0}", - "commands.twitchspawn.test.success": "§a>> Se han puesto en cola las reglas para {0}", - - "errors.twitchspawn.loading": "No se puede cargar TwitchSpawn." + +{ + "modloader.twitchspawn.error.tsl": "Error de TSL: §4{2}", + "modloader.twitchspawn.error.json": "Error de JSON: §4{2}", + "modloader.twitchspawn.error.toml": "Error de TOML: §4{2}", + "modloader.twitchspawn.error.unknown": "Error Desconocido: §4{2} ({3})", + + "commands.twitchspawn.reloadcfg.success": "§3>> ¡Se han recargado exitosamente todas las configuraciones!", + "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Recarga Fallida. Errores de Sintaxis:\n{0}", + "commands.twitchspawn.reloadcfg.already_started": "§4>> TwitchSpawn debe ser detenido para poder recargar las configuraciones.", + "commands.twitchspawn.reloadcfg.no_perm": "§4>> No tienes permiso para recargar las configuraciones de TwitchSpawn.", + + "commands.twitchspawn.status.on": "§3>> TwitchSpawn se esta ejecutando. [ON]", + "commands.twitchspawn.status.off": "§3>> TwitchSpawn no se esta ejecutando [OFF]", + + "commands.twitchspawn.start.success": "§a>> ¡TwitchSpawn ha iniciado en este servidor!", + "commands.twitchspawn.start.illegal_state": "§4>> TwitchSpawn ya se esta ejecutando.", + "commands.twitchspawn.start.no_perm": "§4>> No tienes permiso para iniciar TwitchSpawn.", + + "commands.twitchspawn.stop.success": "§6>> TwitchSpawn se ha detenido por {0} (Razon: {1})", + "commands.twitchspawn.stop.illegal_state": "§4>> TwitchSpawn ya esta apagado.", + "commands.twitchspawn.stop.no_perm": "§4>> No tienes permiso para detener TwitchSpawn.", + + "commands.twitchspawn.rules.list": "§3>> Lista de Reglas cargadas para: {0}", + "commands.twitchspawn.rules.default": "§3>> La Lista de Reglas por defecto incluye:\n{1}", + "commands.twitchspawn.rules.one": "§3>> Lista de Recarga caragada para {0} e incluye:\n{1}", + "commands.twitchspawn.rules.one.fail": "§4>> Ninguna Lista de Reglas ha sido cargada para {0}", + + "commands.twitchspawn.simulate.missing": "§4>> Falta el nombre del evento en el objeto de simulación. Esperado: \"event\" field.", + "commands.twitchspawn.simulate.invalid_event": "§4>> Nombre de evento invalido -> {0}", + "commands.twitchspawn.simulate.success": "§a>> Simulacion ejecutada {0}", + "commands.twitchspawn.simulate.no_perm": "§4>> No tienes permiso para simular un evento.", + + "commands.twitchspawn.test.not_found": "§4>> Ninguna Lista de Reglas asociada con {0}", + "commands.twitchspawn.test.success": "§a>> Se han puesto en cola las reglas para {0}", + + "errors.twitchspawn.loading": "No se puede cargar TwitchSpawn." } \ No newline at end of file diff --git a/src/main/resources/assets/twitchspawn/lang/fr_fr.json b/common/src/main/resources/assets/twitchspawn/lang/fr_fr.json similarity index 100% rename from src/main/resources/assets/twitchspawn/lang/fr_fr.json rename to common/src/main/resources/assets/twitchspawn/lang/fr_fr.json diff --git a/src/main/resources/assets/twitchspawn/lang/it_it.json b/common/src/main/resources/assets/twitchspawn/lang/it_it.json similarity index 100% rename from src/main/resources/assets/twitchspawn/lang/it_it.json rename to common/src/main/resources/assets/twitchspawn/lang/it_it.json diff --git a/src/main/resources/assets/twitchspawn/sounds.json b/common/src/main/resources/assets/twitchspawn/sounds.json similarity index 100% rename from src/main/resources/assets/twitchspawn/sounds.json rename to common/src/main/resources/assets/twitchspawn/sounds.json diff --git a/src/main/resources/assets/twitchspawn/sounds/pop_in.ogg b/common/src/main/resources/assets/twitchspawn/sounds/pop_in.ogg similarity index 100% rename from src/main/resources/assets/twitchspawn/sounds/pop_in.ogg rename to common/src/main/resources/assets/twitchspawn/sounds/pop_in.ogg diff --git a/src/main/resources/assets/twitchspawn/sounds/pop_out.ogg b/common/src/main/resources/assets/twitchspawn/sounds/pop_out.ogg similarity index 100% rename from src/main/resources/assets/twitchspawn/sounds/pop_out.ogg rename to common/src/main/resources/assets/twitchspawn/sounds/pop_out.ogg diff --git a/src/main/resources/assets/twitchspawn/textures/cooldown.png b/common/src/main/resources/assets/twitchspawn/textures/cooldown.png similarity index 100% rename from src/main/resources/assets/twitchspawn/textures/cooldown.png rename to common/src/main/resources/assets/twitchspawn/textures/cooldown.png diff --git a/src/main/resources/assets/twitchspawn/textures/indicators.png b/common/src/main/resources/assets/twitchspawn/textures/indicators.png similarity index 100% rename from src/main/resources/assets/twitchspawn/textures/indicators.png rename to common/src/main/resources/assets/twitchspawn/textures/indicators.png diff --git a/src/main/resources/assets/twitchspawn/udl/tsl_udl.xml b/common/src/main/resources/assets/twitchspawn/udl/tsl_udl.xml similarity index 100% rename from src/main/resources/assets/twitchspawn/udl/tsl_udl.xml rename to common/src/main/resources/assets/twitchspawn/udl/tsl_udl.xml diff --git a/src/main/resources/pack.mcmeta b/common/src/main/resources/pack.mcmeta similarity index 100% rename from src/main/resources/pack.mcmeta rename to common/src/main/resources/pack.mcmeta diff --git a/src/main/resources/pack.png b/common/src/main/resources/pack.png similarity index 100% rename from src/main/resources/pack.png rename to common/src/main/resources/pack.png diff --git a/src/test/resources/comment_expected.tsl b/common/src/test/resources/comment_expected.tsl similarity index 100% rename from src/test/resources/comment_expected.tsl rename to common/src/test/resources/comment_expected.tsl diff --git a/src/test/resources/comment_test.tsl b/common/src/test/resources/comment_test.tsl similarity index 100% rename from src/test/resources/comment_test.tsl rename to common/src/test/resources/comment_test.tsl diff --git a/src/test/resources/test.toml b/common/src/test/resources/test.toml similarity index 100% rename from src/test/resources/test.toml rename to common/src/test/resources/test.toml diff --git a/fabric/build.gradle b/fabric/build.gradle new file mode 100644 index 0000000..d9a63b3 --- /dev/null +++ b/fabric/build.gradle @@ -0,0 +1,85 @@ +plugins { + id "com.github.johnrengelman.shadow" version "7.1.2" +} + +architectury { + platformSetupLoomIde() + fabric() +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentFabric.extendsFrom common +// +// shade +// implementation.extendsFrom shade +} + + +dependencies { + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" + // Remove the next line if you don't want to depend on the API + modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}" + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } + + implementation "com.electronwill.night-config:core:3.6.4" + implementation "com.electronwill.night-config:toml:3.6.4" + + implementation 'com.squareup.okhttp3:okhttp:3.8.1' + implementation 'io.socket:socket.io-client:1.0.2' +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +shadowJar { + configurations = [project.configurations.shadowCommon] + archiveClassifier.set("dev-shadow") +} + +remapJar { + inputFile.set shadowJar.archiveFile + dependsOn shadowJar + archiveClassifier.set(null) +} + +jar { + archiveClassifier.set("dev") +} + +sourcesJar { + def commonSources = project(":common").sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenFabric(MavenPublication) { + artifactId = rootProject.archives_base_name + "-" + project.name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} \ No newline at end of file diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..e72e678 --- /dev/null +++ b/fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,27 @@ +{ + "schemaVersion": 1, + "id": "twitchspawn", + "version": "${version}", + + "name": "TwitchSpawn", + "description": "TwitchSpawn listens for live events related to your Twitch channel using various Socket APIs.\nThen it handles those events with the rules handcrafted by you!", + "authors": [], + "contact": {}, + + "license": "GNU LGPL 3.0", + "icon": "icon.png", + + "environment": "*", + "entrypoints": { + "main": [ + "net.programmer.igoodie.twitchspawn.fabric.TwitchSpawnFabric" + ] + }, + "mixins": [ + "twitchspawn.mixins.json" + ], + "depends": { + "fabricloader": ">=0.15.3", + "minecraft": ">=1.20.2" + } +} diff --git a/fabric/src/main/resources/twitchspawn.mixins.json b/fabric/src/main/resources/twitchspawn.mixins.json new file mode 100644 index 0000000..e99789a --- /dev/null +++ b/fabric/src/main/resources/twitchspawn.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.programmer.igoodie.twitchspawn.mixin.fabric", + "compatibilityLevel": "JAVA_17", + "client": [ + "MixinGui", + "ScreenAccessor" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/forge/build.gradle b/forge/build.gradle new file mode 100644 index 0000000..9611155 --- /dev/null +++ b/forge/build.gradle @@ -0,0 +1,94 @@ +plugins { + id "com.github.johnrengelman.shadow" version "7.1.2" +} +architectury { + platformSetupLoomIde() + forge() +} + +loom { +// accessWidenerPath = project(":common").loom.accessWidenerPath + + forge { +// convertAccessWideners = true +// extraAccessWideners.add loom.accessWidenerPath.get().asFile.name + + mixinConfig "twitchspawn-common.mixins.json" + mixinConfig "twitchspawn.mixins.json" + } +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentForge.extendsFrom common +} + +dependencies { + forge "net.minecraftforge:forge:${rootProject.forge_version}" + // Remove the next line if you don't want to depend on the API + modApi "dev.architectury:architectury-forge:${rootProject.architectury_version}" + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false } + + implementation 'com.squareup.okhttp3:okhttp:3.8.1' + implementation 'io.socket:socket.io-client:1.0.2' + + forgeRuntimeLibrary 'com.squareup.okhttp3:okhttp:3.8.1' + forgeRuntimeLibrary 'io.socket:socket.io-client:1.0.2' +} + +processResources { + inputs.property "version", project.version + + filesMatching("META-INF/mods.toml") { + expand "version": project.version + } +} + +shadowJar { + exclude "fabric.mod.json" + exclude "architectury.common.json" + + configurations = [project.configurations.shadowCommon] + archiveClassifier.set("dev-shadow") +} + +remapJar { + inputFile.set shadowJar.archiveFile + dependsOn shadowJar + archiveClassifier.set(null) +} + +jar { + archiveClassifier.set("dev") +} + +sourcesJar { + def commonSources = project(":common").sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenForge(MavenPublication) { + artifactId = rootProject.archives_base_name + "-" + project.name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} diff --git a/forge/gradle.properties b/forge/gradle.properties new file mode 100644 index 0000000..32f842a --- /dev/null +++ b/forge/gradle.properties @@ -0,0 +1 @@ +loom.platform=forge \ No newline at end of file diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..af7090b --- /dev/null +++ b/forge/src/main/resources/META-INF/mods.toml @@ -0,0 +1,72 @@ +# This is an example mods.toml file. It contains the data relating to the loading mods. +# There are several mandatory fields (#mandatory), and many more that are optional (#optional). +# The overall format is standard TOML format, v0.5.0. +# Note that there are a couple of TOML lists in this file. +# Find more information on toml format here: https://github.com/toml-lang/toml +# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml +modLoader="javafml" #mandatory +# A version range to match for said mod loader - for regular FML @Mod it will be the forge version +loaderVersion="[48,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. +# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. +license="GNU LGPL 3.0" +# A URL to refer people to when problems occur with this mod +issueTrackerURL="https://github.com/iGoodie/TwitchSpawn/issues" +# A list of mods - how many allowed here is determined by the individual mod loader +[[mods]] #mandatory +# The modid of the mod +modId="twitchspawn" #mandatory +# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it +# ${version} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata +# see the associated build.gradle script for how to populate this completely automatically during a build +version="${version}" #mandatory +# A display name for the mod +displayName="TwitchSpawn" #mandatory +# A URL to query for updates for this mod. See the JSON update specification +#updateJSONURL="http://myurl.me/" #optional +# A URL for the "homepage" for this mod, displayed in the mod UI +#displayURL="http://example.com/" #optional +# A file name (in the root of the mod JAR) containing a logo for display +logoFile="icon.png" #optional +# A text field displayed in the mod UI +#credits="Thanks for this example mod goes to Java" #optional +# A text field displayed in the mod UI +authors="iGoodie, BONNe1704" #optional +# Display Test controls the display for your mod in the server connection screen +# MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod. +# IGNORE_SERVER_VERSION means that your mod will not cause a red X if it's present on the server but not on the client. This is what you should use if you're a server only mod. +# IGNORE_ALL_VERSION means that your mod will not cause a red X if it's present on the client or the server. This is a special case and should only be used if your mod has no server component. +# NONE means that no display test is set on your mod. You need to do this yourself, see IExtensionPoint.DisplayTest for more information. You can define any scheme you wish with this value. +# IMPORTANT NOTE: this is NOT an instruction as to which environments (CLIENT or DEDICATED SERVER) your mod loads on. Your mod should load (and maybe do nothing!) whereever it finds itself. +#displayTest="MATCH_VERSION" # MATCH_VERSION is the default if nothing is specified (#optional) + +# The description text for the mod (multi line!) (#mandatory) +description=''' +TwitchSpawn listens for live events related to your Twitch channel using various Socket APIs.\nThen it handles those events with the rules handcrafted by you! +''' +# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. +[[dependencies.twitchspawn]] #optional + # the modid of the dependency + modId="forge" #mandatory + # Does this dependency have to exist - if not, ordering below must be specified + mandatory=true #mandatory + # The version range of the dependency + versionRange="[48,)" #mandatory + # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory + ordering="NONE" + # Side this dependency is applied on - BOTH, CLIENT or SERVER + side="BOTH" +# Here's another dependency +[[dependencies.twitchspawn]] + modId="minecraft" + mandatory=true + # This version range declares a minimum of the current minecraft version up to but not including the next major version + versionRange="[1.20.2,1.21)" + ordering="NONE" + side="BOTH" +[[dependencies.twitchspawn]] + modId = "architectury" + mandatory = true + versionRange = "[9.1.12,)" + ordering = "AFTER" + side = "BOTH" \ No newline at end of file diff --git a/forge/src/main/resources/pack.mcmeta b/forge/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..9936dbb --- /dev/null +++ b/forge/src/main/resources/pack.mcmeta @@ -0,0 +1,7 @@ +{ + "pack": { + "description": "TwitchSpawn resources", + "pack_format": 18, + "forge:server_data_pack_format": 12 + } +} diff --git a/forge/src/main/resources/twitchspawn.mixins.json b/forge/src/main/resources/twitchspawn.mixins.json new file mode 100644 index 0000000..40ccef5 --- /dev/null +++ b/forge/src/main/resources/twitchspawn.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.programmer.igoodie.twitchspawn.mixin.forge", + "compatibilityLevel": "JAVA_17", + "mixins": [ + ], + "client": [ + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/gradle.properties b/gradle.properties index 50c0639..1648d2a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,14 +1,14 @@ -# Sets default memory used for gradle commands. Can be overridden by user or command line properties. -# This is required to provide enough memory for the Minecraft decompilation process. -org.gradle.jvmargs=-Xmx3G -org.gradle.daemon=false - -mod_id=twitchspawn -mod_group=net.programmer.igoodie -mod_version=1.9.5 +org.gradle.jvmargs=-Xmx1G minecraft_version=1.20.2 -forge_version=48.1.0 -mcpMappings_channel=official -mcpMappings_version=1.20.2 +archives_base_name=TwitchSpawn +mod_version=2.0.0 +maven_group=net.programmer.igoodie + +architectury_version=10.0.17 + +fabric_loader_version=0.15.3 +fabric_api_version=0.91.2+1.20.2 + +forge_version=1.20.2-48.1.0 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c1962a79e29d3e0ab67b14947c167a862655af9b..ccebba7710deaf9f98673a68957ea02138b60d0a 100644 GIT binary patch delta 8469 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 F{TFmrHLU;u diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 309b4e1..3499ded 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index aeb74cb..79a61d4 100644 --- a/gradlew +++ b/gradlew @@ -85,6 +85,9 @@ done APP_BASE_NAME=${0##*/} APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -194,10 +197,6 @@ if "$cygwin" || "$msys" ; then done fi - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in diff --git a/settings.gradle b/settings.gradle index 0077fa7..7feba6a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,13 +1,14 @@ pluginManagement { repositories { + maven { url "https://maven.fabricmc.net/" } + maven { url "https://maven.architectury.dev/" } + maven { url "https://maven.minecraftforge.net/" } gradlePluginPortal() - maven { - name = 'MinecraftForge' - url = 'https://maven.minecraftforge.net/' - } } } -plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0' -} +include("common") +include("fabric") +include("forge") + +rootProject.name = "architectury-twitchspawn" \ No newline at end of file From 80597dfc8d29bf2143d20b6014f703f9c4cde355 Mon Sep 17 00:00:00 2001 From: BONNe Date: Sun, 24 Dec 2023 21:02:29 +0200 Subject: [PATCH 04/15] Change forge implementations to Architectury API. --- .../igoodie/twitchspawn/TwitchSpawn.java | 270 ++++++++++-------- .../twitchspawn/TwitchSpawnLoadingErrors.java | 43 +-- .../client/gui/GlobalChatCooldownOverlay.java | 67 +++-- .../client/gui/StatusIndicatorOverlay.java | 57 ++-- .../command/RulesetNameArgumentType.java | 7 +- .../command/StreamerArgumentType.java | 2 +- .../command/TSLWordsArgumentType.java | 2 +- .../configuration/ConfigManager.java | 15 +- .../configuration/CredentialsConfig.java | 7 +- .../configuration/PreferencesConfig.java | 8 +- .../configuration/RulesConfig.java | 11 +- .../configuration/SubtitlesConfig.java | 2 +- .../configuration/TextComponentConfig.java | 5 +- .../configuration/TitlesConfig.java | 2 +- .../twitchspawn/easteregg/Developers.java | 2 +- .../twitchspawn/eventqueue/EventQueue.java | 17 +- .../events/TwitchSpawnClientGuiEvent.java | 42 +++ .../events/TwitchSpawnCommonEvent.java | 17 ++ .../events/TwitchSpawnEventHandler.java | 40 +++ .../twitchspawn/network/NetworkManager.java | 52 ++-- .../packet/GlobalChatCooldownPacket.java | 10 +- .../network/packet/OsRunPacket.java | 10 +- .../network/packet/StatusChangedPacket.java | 10 +- .../registries/TwitchSpawnArgumentTypes.java | 18 ++ .../registries/TwitchSpawnSoundEvent.java | 14 +- .../twitchspawn/tracer/SocketIOTracer.java | 7 +- .../twitchspawn/tracer/TraceManager.java | 20 +- .../twitchspawn/tracer/WebSocketTracer.java | 12 +- .../tracer/chat/TwitchChatTracer.java | 9 +- .../tracer/model/TwitchChatMessage.java | 8 +- .../socket/StreamElementsSocketTracer.java | 11 +- .../tracer/socket/StreamlabsSocketTracer.java | 9 +- .../tracer/socket/TwitchPubSubTracer.java | 19 +- .../twitchspawn/tslanguage/TSLRuleset.java | 11 +- .../tslanguage/TSLRulesetCollection.java | 13 +- .../tslanguage/action/BothAction.java | 9 +- .../tslanguage/action/ClearAction.java | 5 +- .../tslanguage/action/EitherAction.java | 7 +- .../tslanguage/action/ExecuteAction.java | 7 +- .../tslanguage/action/ForAction.java | 5 +- .../action/ItemSelectiveAction.java | 7 +- .../tslanguage/action/NothingAction.java | 5 +- .../tslanguage/action/OsRunAction.java | 18 +- .../tslanguage/action/ReflectAction.java | 11 +- .../tslanguage/action/ShuffleAction.java | 5 +- .../tslanguage/action/SummonAction.java | 5 +- .../tslanguage/action/ThrowAction.java | 5 +- .../tslanguage/action/WaitAction.java | 13 +- .../tslanguage/event/EventArguments.java | 5 +- .../tslanguage/event/TSLEvent.java | 7 +- .../event/builder/DonationBuilder.java | 4 +- .../builder/DonorDriveDonationBuilder.java | 4 +- .../event/builder/EventBuilder.java | 4 +- .../event/builder/ExtraLifeBuilder.java | 5 +- .../event/builder/PatreonBuilder.java | 5 +- .../event/builder/TiltifyBuilder.java | 5 +- .../event/builder/TreatStreamBuilder.java | 5 +- .../event/builder/TwitchFollowBuilder.java | 5 +- .../tslanguage/keyword/TSLEventKeyword.java | 8 +- .../keyword/TSLPredicateProperty.java | 3 +- .../tslanguage/parser/TSLParser.java | 17 +- .../predicate/InRangeComparator.java | 3 +- .../tslanguage/predicate/TSLPredicate.java | 3 +- .../twitchspawn/udl/NotepadUDLUpdater.java | 5 +- .../twitchspawn/util/ExpressionEvaluator.java | 3 +- .../igoodie/twitchspawn/util/GsonUtils.java | 2 +- .../igoodie/twitchspawn/util/JSONUtils.java | 2 +- .../util/PercentageRandomizer.java | 3 +- common/src/main/resources/META-INF/mods.toml | 29 -- .../resources/twitchspawn-common.mixins.json | 13 + 70 files changed, 659 insertions(+), 432 deletions(-) create mode 100644 common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnClientGuiEvent.java create mode 100644 common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnCommonEvent.java create mode 100644 common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnEventHandler.java create mode 100644 common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnArgumentTypes.java delete mode 100644 common/src/main/resources/META-INF/mods.toml create mode 100644 common/src/main/resources/twitchspawn-common.mixins.json 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 2973e0c..86df6a3 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java @@ -4,130 +4,176 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import dev.architectury.event.events.common.CommandRegistrationEvent; +import dev.architectury.event.events.common.LifecycleEvent; +import dev.architectury.event.events.common.PlayerEvent; +import dev.architectury.utils.Env; +import dev.architectury.utils.EnvExecutor; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.RegisterCommandsEvent; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.event.server.ServerAboutToStartEvent; -import net.minecraftforge.event.server.ServerStartingEvent; -import net.minecraftforge.event.server.ServerStoppingEvent; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.ModLoadingStage; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.fml.loading.FMLEnvironment; import net.programmer.igoodie.twitchspawn.client.gui.GlobalChatCooldownOverlay; import net.programmer.igoodie.twitchspawn.client.gui.StatusIndicatorOverlay; import net.programmer.igoodie.twitchspawn.command.TwitchSpawnCommand; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; import net.programmer.igoodie.twitchspawn.configuration.PreferencesConfig; +import net.programmer.igoodie.twitchspawn.events.TwitchSpawnCommonEvent; +import net.programmer.igoodie.twitchspawn.events.TwitchSpawnEventHandler; import net.programmer.igoodie.twitchspawn.network.NetworkManager; import net.programmer.igoodie.twitchspawn.network.packet.StatusChangedPacket; -import net.programmer.igoodie.twitchspawn.registries.TwitchSpawnAugmentTypes; +import net.programmer.igoodie.twitchspawn.registries.TwitchSpawnArgumentTypes; import net.programmer.igoodie.twitchspawn.registries.TwitchSpawnSoundEvent; import net.programmer.igoodie.twitchspawn.tracer.TraceManager; import net.programmer.igoodie.twitchspawn.udl.NotepadUDLUpdater; -@Mod(TwitchSpawn.MOD_ID) -public class TwitchSpawn { - - public static final String MOD_ID = "twitchspawn"; - public static final Logger LOGGER = LogManager.getLogger(TwitchSpawn.class); - - public static MinecraftServer SERVER; - public static TraceManager TRACE_MANAGER; - - public TwitchSpawn() { - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::commonSetup); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::dedicatedServerSetup); - - MinecraftForge.EVENT_BUS.register(this); - - IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); - TwitchSpawnSoundEvent.REGISTRY.register(modEventBus); - TwitchSpawnAugmentTypes.REGISTRY.register(modEventBus); - } - - private void commonSetup(final FMLCommonSetupEvent event) { - try { - ConfigManager.loadConfigs(); - NetworkManager.initialize(); - } catch (TwitchSpawnLoadingErrors e) { - e.bindFMLWarnings(ModLoadingStage.COMMON_SETUP); - if (FMLEnvironment.dist == Dist.DEDICATED_SERVER) { - throw new RuntimeException("TwitchSpawn loading errors occurred"); - } - } - } - - private void clientSetup(final FMLClientSetupEvent event) { - NotepadUDLUpdater.attemptUpdate(); - MinecraftForge.EVENT_BUS.register(StatusIndicatorOverlay.class); - MinecraftForge.EVENT_BUS.register(GlobalChatCooldownOverlay.class); - } - - private void dedicatedServerSetup(final FMLDedicatedServerSetupEvent event) {} - - - @SubscribeEvent - public void onRegisterCommands(RegisterCommandsEvent event) { - TwitchSpawnCommand.register(event.getDispatcher()); - } - - @SubscribeEvent - public void onServerAboutToStart(ServerAboutToStartEvent event) { - SERVER = event.getServer(); - TRACE_MANAGER = new TraceManager(); - } - - @SubscribeEvent - public void onServerStarting(ServerStartingEvent event) { - if (ConfigManager.PREFERENCES.autoStart == PreferencesConfig.AutoStartEnum.ENABLED) { - LOGGER.info("Auto-start is enabled. Attempting to start tracers."); - TRACE_MANAGER.start(); - } - } - - @SubscribeEvent - public void onServerStopping(ServerStoppingEvent event) { - SERVER = null; - - if (TRACE_MANAGER.isRunning()) - TRACE_MANAGER.stop(null, "Server stopping"); - - ConfigManager.RULESET_COLLECTION.clearQueue(); - } - - @SubscribeEvent - public void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) { - ServerPlayer entity = (ServerPlayer) event.getEntity(); - - String translationKey = TRACE_MANAGER.isRunning() ? - "commands.twitchspawn.status.on" : "commands.twitchspawn.status.off"; - - entity.sendSystemMessage(Component.translatable(translationKey)); - - if (TRACE_MANAGER.isRunning()) - TRACE_MANAGER.connectStreamer(entity.getName().getString()); - - NetworkManager.CHANNEL.send(new StatusChangedPacket(TRACE_MANAGER.isRunning()), - entity.connection.getConnection()); - } - - @SubscribeEvent - public void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) { - ServerPlayer entity = (ServerPlayer) event.getEntity(); - - if (TRACE_MANAGER.isRunning()) - TRACE_MANAGER.disconnectStreamer(entity.getName().getString()); - } +public class TwitchSpawn +{ + /** + * The plugin mod-id + */ + public static final String MOD_ID = "twitchspawn"; + + /** + * Minecraft server instance. + */ + public static MinecraftServer SERVER; + + /** + * Trace manager. + */ + public static TraceManager TRACE_MANAGER; + + /** + * Logger. + */ + public static final Logger LOGGER = LogManager.getLogger(); + + + /** + * The main init class. + */ + public static void init() + { + TwitchSpawnEventHandler.init(); + + CommandRegistrationEvent.EVENT.register((dispatcher, registry, selection) -> + TwitchSpawnCommand.register(dispatcher)); + + EnvExecutor.runInEnv(Env.CLIENT, () -> TwitchSpawn.Client::initializeClient); + EnvExecutor.runInEnv(Env.SERVER, () -> TwitchSpawn.Server::initializeServer); + } + + + /** + * List of common tasks initialized by both environments. + */ + private static void initializeCommon() + { + // Trigger tracer on server start. + LifecycleEvent.SERVER_BEFORE_START.register(server -> { + SERVER = server; + TRACE_MANAGER = new TraceManager(); + }); + + // Trigger autostart if that is enabled. + LifecycleEvent.SERVER_STARTING.register(server -> { + if (ConfigManager.PREFERENCES.autoStart == PreferencesConfig.AutoStartEnum.ENABLED) { + LOGGER.info("Auto-start is enabled. Attempting to start tracers."); + TRACE_MANAGER.start(); + } + }); + + // Trigger server stop that would disable tracers. + LifecycleEvent.SERVER_STOPPING.register(server -> { + SERVER = null; + + if (TRACE_MANAGER.isRunning()) + { + TRACE_MANAGER.stop(null, "Server stopping"); + } + + ConfigManager.RULESET_COLLECTION.clearQueue(); + }); + + // Do stuff on player joining the server. + PlayerEvent.PLAYER_JOIN.register(player -> + { + String translationKey = TRACE_MANAGER.isRunning() ? + "commands.twitchspawn.status.on" : "commands.twitchspawn.status.off"; + + player.sendSystemMessage(Component.translatable(translationKey)); + + if (TRACE_MANAGER.isRunning()) + { + TRACE_MANAGER.connectStreamer(player.getName().getString()); + } + + NetworkManager.CHANNEL.sendToPlayer(player, new StatusChangedPacket(TRACE_MANAGER.isRunning())); + }); + + // Do stuff on player leaving the server. + PlayerEvent.PLAYER_QUIT.register(player -> + { + if (TRACE_MANAGER.isRunning()) + { + TRACE_MANAGER.disconnectStreamer(player.getName().getString()); + } + }); + + try + { + TwitchSpawnSoundEvent.REGISTRY.register(); + TwitchSpawnArgumentTypes.registerArgumentType(); + + ConfigManager.loadConfigs(); + NetworkManager.initialize(); + } + catch (TwitchSpawnLoadingErrors e) + { + TwitchSpawnCommonEvent.SETUP_EVENT.invoker().setupEvent(e); + } + } + + + /** + * Client related tasks. + */ + @Environment(EnvType.CLIENT) + public static class Client + { + @Environment(EnvType.CLIENT) + public static void initializeClient() + { + TwitchSpawn.initializeCommon(); + NotepadUDLUpdater.attemptUpdate(); + + PlayerEvent.PLAYER_JOIN.register(player -> + { + StatusIndicatorOverlay.register(); + GlobalChatCooldownOverlay.register(); + }); + + PlayerEvent.PLAYER_QUIT.register(player -> + { + StatusIndicatorOverlay.unregister(); + GlobalChatCooldownOverlay.unregister(); + }); + } + } + + + /** + * Server related tasks + */ + @Environment(EnvType.SERVER) + public static class Server + { + @Environment(EnvType.SERVER) + public static void initializeServer() + { + TwitchSpawn.initializeCommon(); + } + } } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawnLoadingErrors.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawnLoadingErrors.java index 418c50e..986c57e 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawnLoadingErrors.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawnLoadingErrors.java @@ -1,15 +1,11 @@ package net.programmer.igoodie.twitchspawn; -import com.electronwill.nightconfig.core.io.ParsingException; -import com.google.gson.JsonSyntaxException; -import net.minecraftforge.fml.*; -import net.minecraftforge.forgespi.language.IModInfo; -import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; -import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxErrors; import java.util.LinkedList; import java.util.List; +import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxErrors; + public class TwitchSpawnLoadingErrors extends Exception { List exceptions; @@ -26,37 +22,16 @@ public void addException(Exception exception) { } public boolean isEmpty() { - return exceptions.size() == 0; + return exceptions.isEmpty(); } - public void bindFMLWarnings(ModLoadingStage stage) { - ModContainer modContainer = ModList.get() - .getModContainerById(TwitchSpawn.MOD_ID).get(); - - IModInfo modInfo = modContainer.getModInfo(); - - for (Exception exception : exceptions) { - String i18nMessage; - - if (exception instanceof TSLSyntaxError) - i18nMessage = "modloader.twitchspawn.error.tsl"; - else if (exception instanceof ParsingException) - i18nMessage = "modloader.twitchspawn.error.toml"; - else if (exception instanceof JsonSyntaxException) - i18nMessage = "modloader.twitchspawn.error.json"; - else - i18nMessage = "modloader.twitchspawn.error.unknown"; - - ModLoadingWarning warning = new ModLoadingWarning( - modInfo, stage, i18nMessage, - exception.getMessage(), - exception.getClass().getSimpleName() - ); - ModLoader.get().addWarning(warning); - - TwitchSpawn.LOGGER.error(exception.getMessage()); - } + /** + * Returns the list of exceptions + * @return The exception list. + */ + public List getExceptions() { + return this.exceptions; } @Override diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java index a48c4bd..2eb27f1 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/GlobalChatCooldownOverlay.java @@ -1,16 +1,19 @@ package net.programmer.igoodie.twitchspawn.client.gui; + import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; + +import dev.architectury.event.EventResult; +import dev.architectury.event.events.client.ClientGuiEvent; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.client.event.RenderGuiOverlayEvent; -import net.minecraftforge.client.gui.overlay.VanillaGuiOverlay; -import net.minecraftforge.eventbus.api.SubscribeEvent; import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; import net.programmer.igoodie.twitchspawn.configuration.PreferencesConfig; +import net.programmer.igoodie.twitchspawn.events.TwitchSpawnClientGuiEvent; import net.programmer.igoodie.twitchspawn.util.CooldownBucket; public class GlobalChatCooldownOverlay { @@ -19,20 +22,47 @@ public class GlobalChatCooldownOverlay { new ResourceLocation(TwitchSpawn.MOD_ID, "textures/cooldown.png"); private static long timestamp = -1; + private static boolean drew = false; + /** + * Render indicator + */ + private static final TwitchSpawnClientGuiEvent.OverlayRenderPre PRE_RENDER = + (graphics, resourceLocation) -> drew = false; + + /** + * Render the gui + */ + private static final TwitchSpawnClientGuiEvent.OverlayRenderPost POST_RENDER = + GlobalChatCooldownOverlay::onRenderGuiPost; + + + /** + * Register rendering events. + */ + public static void register() { + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_PRE.register(PRE_RENDER); + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_POST.register(POST_RENDER); + } + + + /** + * Unregister rendering events. + */ + public static void unregister() { + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_PRE.unregister(PRE_RENDER); + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_POST.unregister(POST_RENDER); + } + + public static void setCooldownTimestamp(long timestamp) { GlobalChatCooldownOverlay.timestamp = timestamp; } - @SubscribeEvent - public static void onRenderGuiPre(RenderGuiOverlayEvent.Pre event) { - drew = false; - } - @SubscribeEvent - public static void onRenderGuiPost(RenderGuiOverlayEvent.Post event) { - if (event.getOverlay() != VanillaGuiOverlay.HOTBAR.type()) + private static void onRenderGuiPost(GuiGraphics graphics, ResourceLocation resourceLocation) { + if (!resourceLocation.equals(ResourceLocation.of("hotbar", ':'))) return; // Render only on HOTBAR // Already drew, stop here @@ -60,20 +90,20 @@ public static void onRenderGuiPost(RenderGuiOverlayEvent.Post event) { y = 5; } - PoseStack matrixStack = event.getGuiGraphics().pose(); + PoseStack matrixStack = graphics.pose(); matrixStack.pushPose(); matrixStack.scale(scale, scale, scale); - renderGlyph(event.getGuiGraphics(), matrixStack, String.format("%02d", minutes), x, (int) (y / scale)); - renderGlyph(event.getGuiGraphics(), matrixStack, ":", x + 32, (int) (y / scale)); - renderGlyph(event.getGuiGraphics(), matrixStack, String.format("%02d", seconds), (x + 10 + 2 * 18), (int) (y / scale)); - renderGlyph(event.getGuiGraphics(), matrixStack, "i", (int) (x + 10 + 4.25f * 18), (int) ((y - 2) / scale)); + renderGlyph(graphics, matrixStack, String.format("%02d", minutes), x, (int) (y / scale)); + renderGlyph(graphics, matrixStack, ":", x + 32, (int) (y / scale)); + renderGlyph(graphics, matrixStack, String.format("%02d", seconds), (x + 10 + 2 * 18), (int) (y / scale)); + renderGlyph(graphics, matrixStack, "i", (int) (x + 10 + 4.25f * 18), (int) ((y - 2) / scale)); matrixStack.popPose(); } drew = true; } - public static void renderGlyph(GuiGraphics guiGraphics, PoseStack ms, String number, int x, int y) { + private static void renderGlyph(GuiGraphics guiGraphics, PoseStack ms, String number, int x, int y) { RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.setShaderTexture(0, cooldownGlyphs); @@ -88,7 +118,7 @@ public static void renderGlyph(GuiGraphics guiGraphics, PoseStack ms, String num int w = 28; int h = 25; - guiGraphics.blit(VanillaGuiOverlay.HOTBAR.id(), + guiGraphics.blit(ResourceLocation.tryParse("hotbar"), x, y, ux, uy, w, h @@ -105,7 +135,7 @@ public static void renderGlyph(GuiGraphics guiGraphics, PoseStack ms, String num int w = 18; int h = 18; - guiGraphics.blit(VanillaGuiOverlay.HOTBAR.id(), + guiGraphics.blit(ResourceLocation.tryParse("hotbar"), x + offset, y, ux, uy, w, h @@ -122,5 +152,4 @@ public static void renderGlyph(GuiGraphics guiGraphics, PoseStack ms, String num RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.setShaderTexture(0, new ResourceLocation("hud/hotbar")); } - } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java index d43c01c..dbbe562 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/StatusIndicatorOverlay.java @@ -3,19 +3,22 @@ import com.mojang.blaze3d.systems.RenderSystem; +import dev.architectury.event.EventResult; +import dev.architectury.event.events.client.ClientGuiEvent; +import dev.architectury.hooks.client.screen.ScreenAccess; +import dev.architectury.injectables.annotations.ExpectPlatform; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; -import net.minecraftforge.client.event.CustomizeGuiOverlayEvent; -import net.minecraftforge.client.event.RenderGuiOverlayEvent; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; import net.programmer.igoodie.twitchspawn.configuration.PreferencesConfig; +import net.programmer.igoodie.twitchspawn.events.TwitchSpawnClientGuiEvent; import net.programmer.igoodie.twitchspawn.registries.TwitchSpawnSoundEvent; @@ -25,8 +28,40 @@ public class StatusIndicatorOverlay { new ResourceLocation(TwitchSpawn.MOD_ID, "textures/indicators.png"); private static boolean running = false; + private static boolean drew = false; + /** + * Render indicator + */ + private static final TwitchSpawnClientGuiEvent.OverlayRenderPre PRE_RENDER = + (graphics, resourceLocation) -> drew = false; + + /** + * Render the gui + */ + private static final TwitchSpawnClientGuiEvent.RenderDebugHud POST_RENDER = + StatusIndicatorOverlay::onRenderGuiPost; + + + /** + * Register rendering events. + */ + public static void register() { + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_PRE.register(PRE_RENDER); + TwitchSpawnClientGuiEvent.DEBUG_TEXT.register(POST_RENDER); + } + + + /** + * Unregister rendering events. + */ + public static void unregister() { + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_PRE.unregister(PRE_RENDER); + TwitchSpawnClientGuiEvent.DEBUG_TEXT.unregister(POST_RENDER); + } + + public static void setRunning(boolean running) { StatusIndicatorOverlay.running = running; @@ -41,19 +76,8 @@ public static void setRunning(boolean running) { } } - @SubscribeEvent - public static void onClientTick(TickEvent.ClientTickEvent event) { - if (event.phase != TickEvent.Phase.END) - return; - } - - @SubscribeEvent - public static void onRenderGuiPre(RenderGuiOverlayEvent.Pre event) { - drew = false; - } - @SubscribeEvent - public static void onRenderGuiPost(CustomizeGuiOverlayEvent.DebugText event) { + private static void onRenderGuiPost(GuiGraphics gui) { if (ConfigManager.PREFERENCES.indicatorDisplay == PreferencesConfig.IndicatorDisplay.DISABLED) return; // The display is disabled, stop here @@ -66,7 +90,6 @@ public static void onRenderGuiPost(CustomizeGuiOverlayEvent.DebugText event) { RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderTexture(0, indicatorIcons); - GuiGraphics gui = event.getGuiGraphics(); gui.pose().pushPose(); int x = 5, y = 5; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/command/RulesetNameArgumentType.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/RulesetNameArgumentType.java index a7922ed..676e138 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/command/RulesetNameArgumentType.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/RulesetNameArgumentType.java @@ -1,15 +1,16 @@ package net.programmer.igoodie.twitchspawn.command; + import com.mojang.brigadier.StringReader; import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; - import java.util.concurrent.CompletableFuture; +import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; + public class RulesetNameArgumentType implements ArgumentType { public static RulesetNameArgumentType rulesetName() { @@ -22,7 +23,7 @@ public static String getRulesetName(final CommandContext context, final Strin /* ------------------------------ */ - private RulesetNameArgumentType() { } + public RulesetNameArgumentType() { } @Override public String parse(StringReader reader) throws CommandSyntaxException { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java index 1c7b78e..8b3c908 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/StreamerArgumentType.java @@ -24,7 +24,7 @@ public static String getStreamer(final CommandContext context, final String n /* ---------------------------------------- */ - private StreamerArgumentType() { } + public StreamerArgumentType() { } @Override public String parse(StringReader reader) throws CommandSyntaxException { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TSLWordsArgumentType.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TSLWordsArgumentType.java index 842a675..6c7e63a 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TSLWordsArgumentType.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/command/TSLWordsArgumentType.java @@ -17,7 +17,7 @@ public static String getWords(final CommandContext context, final String name /* ------------------------------------ */ - private TSLWordsArgumentType() { } + public TSLWordsArgumentType() { } @Override public String parse(StringReader reader) throws CommandSyntaxException { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/ConfigManager.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/ConfigManager.java index e3affa9..a38650c 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/ConfigManager.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/ConfigManager.java @@ -1,20 +1,27 @@ package net.programmer.igoodie.twitchspawn.configuration; -import net.minecraftforge.fml.loading.FMLPaths; + +import java.io.File; + + +import dev.architectury.injectables.annotations.ExpectPlatform; +import dev.architectury.platform.Platform; import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.TwitchSpawnLoadingErrors; import net.programmer.igoodie.twitchspawn.tslanguage.TSLRulesetCollection; -import java.io.File; - public class ConfigManager { - public static final String CONFIG_DIR_PATH = FMLPaths.CONFIGDIR.get().toString() + File.separator + "TwitchSpawn"; + public static final String CONFIG_DIR_PATH = Platform.getConfigFolder().toString() + File.separator + "TwitchSpawn"; public static CredentialsConfig CREDENTIALS; + public static TSLRulesetCollection RULESET_COLLECTION; + public static TitlesConfig TITLES; + public static SubtitlesConfig SUBTITLES; + public static PreferencesConfig PREFERENCES; public static void loadConfigs() throws TwitchSpawnLoadingErrors { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/CredentialsConfig.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/CredentialsConfig.java index 900bbe7..1c0b825 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/CredentialsConfig.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/CredentialsConfig.java @@ -1,15 +1,13 @@ package net.programmer.igoodie.twitchspawn.configuration; + import com.electronwill.nightconfig.core.CommentedConfig; import com.electronwill.nightconfig.core.Config; import com.electronwill.nightconfig.core.conversion.ObjectConverter; import com.electronwill.nightconfig.core.io.ParsingException; import com.electronwill.nightconfig.toml.TomlFormat; import com.electronwill.nightconfig.toml.TomlParser; -import net.programmer.igoodie.twitchspawn.TwitchSpawn; -import net.programmer.igoodie.twitchspawn.tracer.Platform; import org.apache.commons.io.FileUtils; - import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -18,6 +16,9 @@ import java.util.List; import java.util.stream.Collectors; +import net.programmer.igoodie.twitchspawn.TwitchSpawn; +import net.programmer.igoodie.twitchspawn.tracer.Platform; + public class CredentialsConfig { public static CredentialsConfig create(String filepath) throws ParsingException { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/PreferencesConfig.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/PreferencesConfig.java index 1ba3ef5..581a32b 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/PreferencesConfig.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/PreferencesConfig.java @@ -1,20 +1,22 @@ package net.programmer.igoodie.twitchspawn.configuration; + import com.electronwill.nightconfig.core.CommentedConfig; import com.electronwill.nightconfig.core.ConfigSpec; import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.electronwill.nightconfig.toml.TomlParser; import com.google.common.io.Resources; -import net.programmer.igoodie.twitchspawn.TwitchSpawn; import org.apache.commons.io.FileUtils; - import java.io.File; import java.io.IOException; import java.net.URL; import java.nio.charset.StandardCharsets; -public class PreferencesConfig { +import net.programmer.igoodie.twitchspawn.TwitchSpawn; + +public class PreferencesConfig +{ public enum IndicatorDisplay { DISABLED, CIRCLE_ONLY, ENABLED } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/RulesConfig.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/RulesConfig.java index 84b466f..6af2c3f 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/RulesConfig.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/RulesConfig.java @@ -1,12 +1,8 @@ package net.programmer.igoodie.twitchspawn.configuration; + import com.google.common.io.Resources; -import net.programmer.igoodie.twitchspawn.TwitchSpawn; -import net.programmer.igoodie.twitchspawn.tslanguage.TSLRuleset; -import net.programmer.igoodie.twitchspawn.tslanguage.TSLRulesetCollection; -import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxErrors; import org.apache.commons.io.FileUtils; - import java.io.File; import java.io.IOException; import java.net.URL; @@ -16,6 +12,11 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.programmer.igoodie.twitchspawn.TwitchSpawn; +import net.programmer.igoodie.twitchspawn.tslanguage.TSLRuleset; +import net.programmer.igoodie.twitchspawn.tslanguage.TSLRulesetCollection; +import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxErrors; + public class RulesConfig { public static TSLRulesetCollection createRules(String directory) throws TSLSyntaxErrors { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/SubtitlesConfig.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/SubtitlesConfig.java index 40793b1..08db822 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/SubtitlesConfig.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/SubtitlesConfig.java @@ -1,7 +1,7 @@ package net.programmer.igoodie.twitchspawn.configuration; -import com.google.gson.JsonArray; +import com.google.gson.JsonArray; import java.io.File; public class SubtitlesConfig extends TextComponentConfig { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TextComponentConfig.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TextComponentConfig.java index c485cce..fc30efb 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TextComponentConfig.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TextComponentConfig.java @@ -1,18 +1,19 @@ package net.programmer.igoodie.twitchspawn.configuration; + import com.google.common.io.Resources; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; -import net.programmer.igoodie.twitchspawn.util.GsonUtils; import org.apache.commons.io.FileUtils; - import java.io.File; import java.io.IOException; import java.net.URL; import java.nio.charset.StandardCharsets; +import net.programmer.igoodie.twitchspawn.util.GsonUtils; + public abstract class TextComponentConfig { protected JsonObject componentJson; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TitlesConfig.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TitlesConfig.java index 6011d4b..798fa2e 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TitlesConfig.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/configuration/TitlesConfig.java @@ -1,7 +1,7 @@ package net.programmer.igoodie.twitchspawn.configuration; -import com.google.gson.JsonArray; +import com.google.gson.JsonArray; import java.io.File; public class TitlesConfig extends TextComponentConfig { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/easteregg/Developers.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/easteregg/Developers.java index eb8d6a4..8e7e439 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/easteregg/Developers.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/easteregg/Developers.java @@ -7,6 +7,6 @@ public class Developers { public static final Set TWITCH_NICKS = new HashSet<>( - Arrays.asList("iGoodiex", "TheDiaval", "Girloflegend")); + Arrays.asList("iGoodiex", "TheDiaval", "Girloflegend", "BONNe1704")); } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java index 18c3e25..724bcfa 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/eventqueue/EventQueue.java @@ -1,18 +1,19 @@ package net.programmer.igoodie.twitchspawn.eventqueue; + +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; + import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.network.NetworkDirection; import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.network.NetworkManager; import net.programmer.igoodie.twitchspawn.network.packet.GlobalChatCooldownPacket; +import net.programmer.igoodie.twitchspawn.network.packet.StatusChangedPacket; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEvent; import net.programmer.igoodie.twitchspawn.util.CooldownBucket; -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; - public class EventQueue { private final Thread innerThread; @@ -136,10 +137,8 @@ public void queue(TSLEvent eventNode, EventArguments args, CooldownBucket cooldo .getPlayerByName(args.streamerNickname); if (playerEntity != null) { - NetworkManager.CHANNEL.send( - new GlobalChatCooldownPacket(cooldownBucket.getGlobalCooldownTimestamp()), - playerEntity.connection.getConnection() - ); + NetworkManager.CHANNEL.sendToPlayer(playerEntity, + new GlobalChatCooldownPacket(cooldownBucket.getGlobalCooldownTimestamp())); } } } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnClientGuiEvent.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnClientGuiEvent.java new file mode 100644 index 0000000..802f4a8 --- /dev/null +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnClientGuiEvent.java @@ -0,0 +1,42 @@ +package net.programmer.igoodie.twitchspawn.events; + + +import dev.architectury.event.Event; +import dev.architectury.event.EventFactory; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Overlay; +import net.minecraft.resources.ResourceLocation; + + +@Environment(EnvType.CLIENT) +public interface TwitchSpawnClientGuiEvent +{ + Event DEBUG_TEXT = EventFactory.createLoop(); + + Event OVERLAY_RENDER_PRE = EventFactory.createLoop(); + + Event OVERLAY_RENDER_POST = EventFactory.createLoop(); + + + @Environment(EnvType.CLIENT) + interface RenderDebugHud + { + void renderHud(GuiGraphics graphics); + } + + + @Environment(EnvType.CLIENT) + interface OverlayRenderPre + { + void renderHud(GuiGraphics graphics, ResourceLocation overlay); + } + + + @Environment(EnvType.CLIENT) + interface OverlayRenderPost + { + void renderHud(GuiGraphics graphics, ResourceLocation overlay); + } +} diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnCommonEvent.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnCommonEvent.java new file mode 100644 index 0000000..4819b61 --- /dev/null +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnCommonEvent.java @@ -0,0 +1,17 @@ +package net.programmer.igoodie.twitchspawn.events; + + +import dev.architectury.event.Event; +import dev.architectury.event.EventFactory; +import net.programmer.igoodie.twitchspawn.TwitchSpawnLoadingErrors; + + +public interface TwitchSpawnCommonEvent +{ + Event SETUP_EVENT = EventFactory.createCompoundEventResult(); + + interface SetupEvent + { + void setupEvent(TwitchSpawnLoadingErrors error); + } +} diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnEventHandler.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnEventHandler.java new file mode 100644 index 0000000..3380654 --- /dev/null +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnEventHandler.java @@ -0,0 +1,40 @@ +package net.programmer.igoodie.twitchspawn.events; + + +import dev.architectury.injectables.annotations.ExpectPlatform; +import dev.architectury.platform.Platform; +import dev.architectury.utils.Env; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + + +public final class TwitchSpawnEventHandler +{ + private TwitchSpawnEventHandler() + { + } + + + private static boolean initialized = false; + + + public static void init() + { + if (initialized) return; + + initialized = true; + + if (Platform.getEnvironment() == Env.CLIENT) + { + registerClient(); + } + } + + + @ExpectPlatform + @Environment(EnvType.CLIENT) + private static void registerClient() + { + throw new AssertionError(); + } +} diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java index 13fcaa5..1430b1a 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/NetworkManager.java @@ -1,53 +1,39 @@ package net.programmer.igoodie.twitchspawn.network; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.network.Channel; -import net.minecraftforge.network.ChannelBuilder; -import net.minecraftforge.network.NetworkDirection; -import net.minecraftforge.network.SimpleChannel; +import dev.architectury.networking.NetworkChannel; +import net.minecraft.resources.ResourceLocation; import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.network.packet.GlobalChatCooldownPacket; import net.programmer.igoodie.twitchspawn.network.packet.OsRunPacket; import net.programmer.igoodie.twitchspawn.network.packet.StatusChangedPacket; -public class NetworkManager { - /** - * Protocol versions now are Integers. So gone 0.0.5 :) - */ - private static final int PROTOCOL_VERSION = 1; +public class NetworkManager { /** * Channel for network communication. */ - public static final SimpleChannel CHANNEL = ChannelBuilder. - named(new ResourceLocation(TwitchSpawn.MOD_ID, "network")). - clientAcceptedVersions(Channel.VersionTest.exact(PROTOCOL_VERSION)). - serverAcceptedVersions(Channel.VersionTest.exact(PROTOCOL_VERSION)). - networkProtocolVersion(PROTOCOL_VERSION). - simpleChannel(); + public static final NetworkChannel CHANNEL = NetworkChannel. + create(new ResourceLocation(TwitchSpawn.MOD_ID, "network")); /** * The method that initializes the network channel. */ public static void initialize() { - CHANNEL.messageBuilder(StatusChangedPacket.class, 0, NetworkDirection.PLAY_TO_CLIENT) - .decoder(StatusChangedPacket::decode) - .encoder(StatusChangedPacket::encode) - .consumerMainThread(StatusChangedPacket::handle) - .add(); - - CHANNEL.messageBuilder(OsRunPacket.class, 1, NetworkDirection.PLAY_TO_CLIENT) - .decoder(OsRunPacket::decode) - .encoder(OsRunPacket::encode) - .consumerMainThread(OsRunPacket::handle) - .add(); - - CHANNEL.messageBuilder(GlobalChatCooldownPacket.class, 2, NetworkDirection.PLAY_TO_CLIENT) - .decoder(GlobalChatCooldownPacket::decode) - .encoder(GlobalChatCooldownPacket::encode) - .consumerMainThread(GlobalChatCooldownPacket::handle) - .add(); + CHANNEL.register(StatusChangedPacket.class, + StatusChangedPacket::encode, + StatusChangedPacket::decode, + StatusChangedPacket::handle); + + CHANNEL.register(OsRunPacket.class, + OsRunPacket::encode, + OsRunPacket::decode, + OsRunPacket::handle); + + CHANNEL.register(GlobalChatCooldownPacket.class, + GlobalChatCooldownPacket::encode, + GlobalChatCooldownPacket::decode, + GlobalChatCooldownPacket::handle); } } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java index 9f1e977..f7105ea 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/GlobalChatCooldownPacket.java @@ -1,10 +1,13 @@ package net.programmer.igoodie.twitchspawn.network.packet; +import java.util.function.Supplier; + +import dev.architectury.networking.NetworkManager; import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.event.network.CustomPayloadEvent; import net.programmer.igoodie.twitchspawn.client.gui.GlobalChatCooldownOverlay; + public class GlobalChatCooldownPacket { public GlobalChatCooldownPacket(long timestamp) { @@ -19,9 +22,8 @@ public static GlobalChatCooldownPacket decode(FriendlyByteBuf buffer) { return new GlobalChatCooldownPacket(buffer.readLong()); } - public void handle(CustomPayloadEvent.Context context) { - context.enqueueWork(() -> GlobalChatCooldownOverlay.setCooldownTimestamp(this.timestamp)); - context.setPacketHandled(true); + public void handle(Supplier context) { + context.get().queue(() -> GlobalChatCooldownOverlay.setCooldownTimestamp(this.timestamp)); } /** diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java index b7fa790..30ed253 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/OsRunPacket.java @@ -1,10 +1,13 @@ package net.programmer.igoodie.twitchspawn.network.packet; +import java.util.function.Supplier; + +import dev.architectury.networking.NetworkManager; import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.event.network.CustomPayloadEvent; import net.programmer.igoodie.twitchspawn.tslanguage.action.OsRunAction; + public class OsRunPacket { public OsRunPacket(OsRunAction.Shell shell, String script) { @@ -24,9 +27,8 @@ public static OsRunPacket decode(FriendlyByteBuf buffer) { return new OsRunPacket(shell, script); } - public void handle(CustomPayloadEvent.Context context) { - context.enqueueWork(() -> OsRunAction.handleLocalScript(this.shell, this.script)); - context.setPacketHandled(true); + public void handle(Supplier context) { + context.get().queue(() -> OsRunAction.handleLocalScript(this.shell, this.script)); } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java index caf866c..7ec552b 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/network/packet/StatusChangedPacket.java @@ -1,10 +1,13 @@ package net.programmer.igoodie.twitchspawn.network.packet; +import java.util.function.Supplier; + +import dev.architectury.networking.NetworkManager; import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.event.network.CustomPayloadEvent; import net.programmer.igoodie.twitchspawn.client.gui.StatusIndicatorOverlay; + public class StatusChangedPacket { public StatusChangedPacket(boolean status) { @@ -19,9 +22,8 @@ public static StatusChangedPacket decode(FriendlyByteBuf buffer) { return new StatusChangedPacket(buffer.readBoolean()); } - public void handle(CustomPayloadEvent.Context context) { - context.enqueueWork(() -> StatusIndicatorOverlay.setRunning(this.status)); - context.setPacketHandled(true); + public void handle(Supplier context) { + context.get().queue(() -> StatusIndicatorOverlay.setRunning(this.status)); } /** diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnArgumentTypes.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnArgumentTypes.java new file mode 100644 index 0000000..02409b5 --- /dev/null +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnArgumentTypes.java @@ -0,0 +1,18 @@ +package net.programmer.igoodie.twitchspawn.registries; + + +import dev.architectury.injectables.annotations.ExpectPlatform; + + +/** + * This class registers argument types. + */ +public class TwitchSpawnArgumentTypes +{ + @ExpectPlatform + public static void registerArgumentType() + { + // Just throw an error, the content should get replaced at runtime. + throw new AssertionError(); + } +} diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java index 32e5f0d..8a329a4 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnSoundEvent.java @@ -1,36 +1,34 @@ package net.programmer.igoodie.twitchspawn.registries; +import dev.architectury.registry.registries.DeferredRegister; +import dev.architectury.registry.registries.RegistrySupplier; +import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; import net.programmer.igoodie.twitchspawn.TwitchSpawn; /** * This class registers sound events. */ -@Mod.EventBusSubscriber(modid = TwitchSpawn.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) public class TwitchSpawnSoundEvent { /** * Registry for sound events. */ public static final DeferredRegister REGISTRY = - DeferredRegister.create(ForgeRegistries.SOUND_EVENTS, TwitchSpawn.MOD_ID); + DeferredRegister.create(TwitchSpawn.MOD_ID, Registries.SOUND_EVENT); /** * Sound event for popping in. */ - public static final RegistryObject POP_IN = REGISTRY.register("pop_in", + public static final RegistrySupplier POP_IN = REGISTRY.register("pop_in", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(TwitchSpawn.MOD_ID))); /** * Sound event for popping out. */ - public static final RegistryObject POP_OUT = REGISTRY.register("pop_out", + public static final RegistrySupplier POP_OUT = REGISTRY.register("pop_out", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(TwitchSpawn.MOD_ID))); } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/SocketIOTracer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/SocketIOTracer.java index 0812c5b..01636dd 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/SocketIOTracer.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/SocketIOTracer.java @@ -1,12 +1,11 @@ package net.programmer.igoodie.twitchspawn.tracer; + +import java.net.URISyntaxException; + import io.socket.client.IO; import io.socket.client.Socket; import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; -import net.programmer.igoodie.twitchspawn.util.JSONUtils; -import org.json.JSONObject; - -import java.net.URISyntaxException; public abstract class SocketIOTracer { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java index 8935072..8a9396a 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/TraceManager.java @@ -1,5 +1,12 @@ package net.programmer.igoodie.twitchspawn.tracer; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + import io.socket.client.IO; import io.socket.client.Socket; import net.minecraft.commands.CommandSourceStack; @@ -17,9 +24,6 @@ import okhttp3.Dispatcher; import okhttp3.OkHttpClient; -import java.util.*; -import java.util.concurrent.TimeUnit; - public class TraceManager { private boolean running; @@ -61,6 +65,8 @@ public void start() { this.webSocketTracers.add(new TwitchChatTracer(this)); // TODO: Extract to a worker, not master webSocketTracers.forEach(WebSocketTracer::start); + TwitchSpawn.LOGGER.info("Connecting Streamers..."); + // Connect online players from credentials.toml for (CredentialsConfig.Streamer streamer : ConfigManager.CREDENTIALS.streamers) { if (TwitchSpawn.SERVER.getPlayerList().getPlayerByName(streamer.minecraftNick) != null) { @@ -68,11 +74,12 @@ public void start() { } } + TwitchSpawn.LOGGER.info("Notify Players..."); + for (ServerPlayer player : TwitchSpawn.SERVER.getPlayerList().getPlayers()) { Component successText = Component.translatable("commands.twitchspawn.start.success"); player.sendSystemMessage(successText); - NetworkManager.CHANNEL.send(new StatusChangedPacket(true), - player.connection.getConnection()); + NetworkManager.CHANNEL.sendToPlayer(player, new StatusChangedPacket(true)); } } @@ -98,8 +105,7 @@ public void stop(CommandSourceStack source, String reason) { Component successText = Component.translatable("commands.twitchspawn.stop.success", source == null ? "Server" : source.getTextName(), reason); player.sendSystemMessage(successText); - NetworkManager.CHANNEL.send(new StatusChangedPacket(false), - player.connection.getConnection()); + NetworkManager.CHANNEL.sendToPlayer(player, new StatusChangedPacket(false)); } } } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/WebSocketTracer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/WebSocketTracer.java index 7123b3a..b849d12 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/WebSocketTracer.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/WebSocketTracer.java @@ -1,13 +1,19 @@ package net.programmer.igoodie.twitchspawn.tracer; -import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; -import okhttp3.*; -import okio.ByteString; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeUnit; +import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; +import okhttp3.Dispatcher; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; +import okio.ByteString; + public abstract class WebSocketTracer { protected TraceManager manager; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/chat/TwitchChatTracer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/chat/TwitchChatTracer.java index 011d2fe..56a3c42 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/chat/TwitchChatTracer.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/chat/TwitchChatTracer.java @@ -1,5 +1,10 @@ package net.programmer.igoodie.twitchspawn.tracer.chat; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; + import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; @@ -13,10 +18,6 @@ import okhttp3.WebSocket; import okhttp3.WebSocketListener; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Stream; - public class TwitchChatTracer extends WebSocketTracer { // Streamer Nickname -> CooldownBucket diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/model/TwitchChatMessage.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/model/TwitchChatMessage.java index da34f04..447e9e8 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/model/TwitchChatMessage.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/model/TwitchChatMessage.java @@ -1,12 +1,16 @@ package net.programmer.igoodie.twitchspawn.tracer.model; -import net.programmer.igoodie.twitchspawn.easteregg.Developers; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Stream; +import net.programmer.igoodie.twitchspawn.easteregg.Developers; + public class TwitchChatMessage { public static final Pattern TWITCH_CHAT_PATTERN = Pattern.compile("^@(?.*?) (:(?.*?)!.*?\\.tmi\\.twitch\\.tv) PRIVMSG #(?.*?) :(?.*)$"); diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamElementsSocketTracer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamElementsSocketTracer.java index a9dcab6..d888293 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamElementsSocketTracer.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamElementsSocketTracer.java @@ -1,5 +1,11 @@ package net.programmer.igoodie.twitchspawn.tracer.socket; + +import org.json.JSONException; +import org.json.JSONObject; +import java.util.Timer; +import java.util.TimerTask; + import io.socket.client.Socket; import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; @@ -12,11 +18,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.event.builder.EventBuilder; import net.programmer.igoodie.twitchspawn.tslanguage.keyword.TSLEventKeyword; import net.programmer.igoodie.twitchspawn.util.JSONUtils; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Timer; -import java.util.TimerTask; public class StreamElementsSocketTracer extends SocketIOTracer { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamlabsSocketTracer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamlabsSocketTracer.java index 62f5897..fe9add4 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamlabsSocketTracer.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/StreamlabsSocketTracer.java @@ -1,5 +1,10 @@ package net.programmer.igoodie.twitchspawn.tracer.socket; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + import io.socket.client.IO; import io.socket.client.Socket; import net.programmer.igoodie.twitchspawn.TwitchSpawn; @@ -13,10 +18,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.event.builder.EventBuilder; import net.programmer.igoodie.twitchspawn.tslanguage.keyword.TSLEventKeyword; import net.programmer.igoodie.twitchspawn.util.JSONUtils; -import net.programmer.igoodie.twitchspawn.util.TSHelper; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; public class StreamlabsSocketTracer extends SocketIOTracer { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/TwitchPubSubTracer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/TwitchPubSubTracer.java index f979e48..5d73598 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/TwitchPubSubTracer.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tracer/socket/TwitchPubSubTracer.java @@ -1,5 +1,15 @@ package net.programmer.igoodie.twitchspawn.tracer.socket; + +import org.json.JSONException; +import org.json.JSONObject; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.*; + import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; @@ -10,15 +20,6 @@ import okhttp3.Response; import okhttp3.WebSocket; import okhttp3.WebSocketListener; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.*; public class TwitchPubSubTracer extends WebSocketTracer { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRuleset.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRuleset.java index a870380..c115b96 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRuleset.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRuleset.java @@ -1,5 +1,11 @@ package net.programmer.igoodie.twitchspawn.tslanguage; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEvent; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; @@ -7,11 +13,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxErrors; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLTokenizer; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - public class TSLRuleset { private String streamer; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRulesetCollection.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRulesetCollection.java index 58a1c07..40b85c4 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRulesetCollection.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/TSLRulesetCollection.java @@ -1,18 +1,19 @@ package net.programmer.igoodie.twitchspawn.tslanguage; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; +import net.programmer.igoodie.twitchspawn.eventqueue.EventQueue; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEvent; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEventPair; import net.programmer.igoodie.twitchspawn.tslanguage.keyword.TSLEventKeyword; import net.programmer.igoodie.twitchspawn.util.CooldownBucket; -import net.programmer.igoodie.twitchspawn.eventqueue.EventQueue; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; public class TSLRulesetCollection { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/BothAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/BothAction.java index c501ba6..50b52d4 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/BothAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/BothAction.java @@ -1,6 +1,11 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + import com.google.gson.JsonArray; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + import net.minecraft.server.level.ServerPlayer; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; import net.programmer.igoodie.twitchspawn.eventqueue.EventQueue; @@ -9,10 +14,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - public class BothAction extends TSLAction { public static final String DELIMITER = "AND"; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java index 5fc0277..aa44d4e 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ClearAction.java @@ -1,5 +1,8 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + +import java.util.List; + import net.minecraft.commands.CommandSourceStack; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; @@ -8,8 +11,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; -import java.util.List; - public class ClearAction extends ItemSelectiveAction { public ClearAction(List words) throws TSLSyntaxError { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/EitherAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/EitherAction.java index 98ca4cb..3459ec9 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/EitherAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/EitherAction.java @@ -1,6 +1,10 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + import com.google.gson.JsonArray; +import java.util.LinkedList; +import java.util.List; + import net.minecraft.server.level.ServerPlayer; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.keyword.TSLActionKeyword; @@ -8,9 +12,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; import net.programmer.igoodie.twitchspawn.util.PercentageRandomizer; -import java.util.LinkedList; -import java.util.List; - public class EitherAction extends TSLAction { public static final String DELIMITER = "OR"; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java index 86ea5fe..0a5ba46 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ExecuteAction.java @@ -1,5 +1,9 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + +import java.util.LinkedList; +import java.util.List; + import net.minecraft.commands.CommandSourceStack; import net.minecraft.server.level.ServerPlayer; import net.programmer.igoodie.twitchspawn.TwitchSpawn; @@ -7,9 +11,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; -import java.util.LinkedList; -import java.util.List; - public class ExecuteAction extends TSLAction { private List commands; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ForAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ForAction.java index c6f726a..9c9a7e9 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ForAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ForAction.java @@ -1,5 +1,8 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + +import java.util.List; + import net.minecraft.server.level.ServerPlayer; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.keyword.TSLActionKeyword; @@ -7,8 +10,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; import net.programmer.igoodie.twitchspawn.util.ExpressionEvaluator; -import java.util.List; - public class ForAction extends TSLAction { private TSLAction action; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ItemSelectiveAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ItemSelectiveAction.java index 8a64b64..72088c2 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ItemSelectiveAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ItemSelectiveAction.java @@ -1,12 +1,13 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.item.ItemStack; -import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; import java.util.LinkedList; import java.util.List; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; +import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; + public abstract class ItemSelectiveAction extends TSLAction { public enum InventoryType { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/NothingAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/NothingAction.java index 0bbb0c5..69804e9 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/NothingAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/NothingAction.java @@ -1,12 +1,13 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + +import java.util.List; + import net.minecraft.server.level.ServerPlayer; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; -import java.util.List; - public class NothingAction extends TSLAction { public NothingAction(List words) throws TSLSyntaxError { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java index 438f4d0..1350f50 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/OsRunAction.java @@ -1,7 +1,13 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.network.NetworkDirection; import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.network.NetworkManager; import net.programmer.igoodie.twitchspawn.network.packet.OsRunPacket; @@ -9,12 +15,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - public class OsRunAction extends TSLAction { public static void handleLocalScript(Shell shell, String script) { @@ -176,8 +176,8 @@ protected void performAction(ServerPlayer player, EventArguments args) { handleLocalScript(shell, replaceExpressions(shellScript, args)); } else if (scriptLocation == ScriptLocation.REMOTE) { - NetworkManager.CHANNEL.send(new OsRunPacket(shell, replaceExpressions(shellScript, args)), - player.connection.getConnection()); + NetworkManager.CHANNEL.sendToPlayer(player, + new OsRunPacket(shell, replaceExpressions(shellScript, args))); } } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ReflectAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ReflectAction.java index 4ceb345..7d96e30 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ReflectAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ReflectAction.java @@ -1,5 +1,11 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + import net.minecraft.server.level.ServerPlayer; import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; @@ -9,11 +15,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - public class ReflectAction extends TSLAction { private boolean onlyReflectedPlayers; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java index 4d6bdb3..2875e63 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ShuffleAction.java @@ -1,5 +1,8 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + +import java.util.List; + import net.minecraft.commands.CommandSourceStack; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; @@ -8,8 +11,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; -import java.util.List; - public class ShuffleAction extends ItemSelectiveAction { private int firstIndex; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java index 94d4407..17f879e 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java @@ -1,7 +1,10 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import java.util.List; + import net.minecraft.nbt.TagParser; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; @@ -9,8 +12,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; -import java.util.List; - public class SummonAction extends TSLAction { private EntityType entityType; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java index 50b63c5..9adfd09 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/ThrowAction.java @@ -1,5 +1,8 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; + +import java.util.List; + import net.minecraft.commands.CommandSourceStack; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; @@ -8,8 +11,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; -import java.util.List; - public class ThrowAction extends ItemSelectiveAction { public ThrowAction(List words) throws TSLSyntaxError { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/WaitAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/WaitAction.java index 0990642..35f0156 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/WaitAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/WaitAction.java @@ -1,11 +1,5 @@ package net.programmer.igoodie.twitchspawn.tslanguage.action; -import net.minecraft.server.level.ServerPlayer; -import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; -import net.programmer.igoodie.twitchspawn.eventqueue.EventQueue; -import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; -import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; -import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; import java.util.AbstractMap; import java.util.List; @@ -13,6 +7,13 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import net.minecraft.server.level.ServerPlayer; +import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; +import net.programmer.igoodie.twitchspawn.eventqueue.EventQueue; +import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; +import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; +import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; + public class WaitAction extends TSLAction { public static final Map UNIT_COEF = Stream.of( diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/EventArguments.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/EventArguments.java index 8c5de7b..9fa243f 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/EventArguments.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/EventArguments.java @@ -1,13 +1,14 @@ package net.programmer.igoodie.twitchspawn.tslanguage.event; -import com.google.common.base.Defaults; -import net.programmer.igoodie.twitchspawn.tslanguage.keyword.TSLEventKeyword; +import com.google.common.base.Defaults; import java.lang.reflect.Field; import java.util.HashSet; import java.util.Random; import java.util.Set; +import net.programmer.igoodie.twitchspawn.tslanguage.keyword.TSLEventKeyword; + public class EventArguments { public static EventArguments createRandom(String streamerNickname) { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEvent.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEvent.java index 38bad40..f9e2c13 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEvent.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/TSLEvent.java @@ -1,13 +1,14 @@ package net.programmer.igoodie.twitchspawn.tslanguage.event; -import net.programmer.igoodie.twitchspawn.tslanguage.TSLFlowNode; -import net.programmer.igoodie.twitchspawn.tslanguage.action.TSLAction; -import net.programmer.igoodie.twitchspawn.tslanguage.predicate.TSLPredicate; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import net.programmer.igoodie.twitchspawn.tslanguage.TSLFlowNode; +import net.programmer.igoodie.twitchspawn.tslanguage.action.TSLAction; +import net.programmer.igoodie.twitchspawn.tslanguage.predicate.TSLPredicate; + public class TSLEvent implements TSLFlowNode { protected String name; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonationBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonationBuilder.java index 85ded63..b4262eb 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonationBuilder.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonationBuilder.java @@ -1,11 +1,13 @@ package net.programmer.igoodie.twitchspawn.tslanguage.event.builder; + +import org.json.JSONObject; + import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; import net.programmer.igoodie.twitchspawn.tracer.Platform; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEventPair; import net.programmer.igoodie.twitchspawn.util.JSONUtils; -import org.json.JSONObject; public class DonationBuilder extends EventBuilder { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonorDriveDonationBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonorDriveDonationBuilder.java index e1a1dcb..7d310bd 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonorDriveDonationBuilder.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/DonorDriveDonationBuilder.java @@ -1,11 +1,13 @@ package net.programmer.igoodie.twitchspawn.tslanguage.event.builder; + +import org.json.JSONObject; + import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; import net.programmer.igoodie.twitchspawn.tracer.Platform; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEventPair; import net.programmer.igoodie.twitchspawn.util.JSONUtils; -import org.json.JSONObject; public class DonorDriveDonationBuilder extends EventBuilder { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/EventBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/EventBuilder.java index 21325c1..c216951 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/EventBuilder.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/EventBuilder.java @@ -1,12 +1,14 @@ package net.programmer.igoodie.twitchspawn.tslanguage.event.builder; + +import org.json.JSONObject; + import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; import net.programmer.igoodie.twitchspawn.tracer.Platform; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEventPair; import net.programmer.igoodie.twitchspawn.util.JSONUtils; import net.programmer.igoodie.twitchspawn.util.TSHelper; -import org.json.JSONObject; public abstract class EventBuilder { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/ExtraLifeBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/ExtraLifeBuilder.java index 915ec3f..d2f9e65 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/ExtraLifeBuilder.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/ExtraLifeBuilder.java @@ -1,13 +1,14 @@ package net.programmer.igoodie.twitchspawn.tslanguage.event.builder; + +import org.json.JSONObject; + import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; import net.programmer.igoodie.twitchspawn.tracer.Platform; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEventPair; import net.programmer.igoodie.twitchspawn.util.JSONUtils; -import org.json.JSONObject; -import java.awt.*; public class ExtraLifeBuilder extends EventBuilder { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/PatreonBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/PatreonBuilder.java index 00660ff..a01f94e 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/PatreonBuilder.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/PatreonBuilder.java @@ -1,13 +1,14 @@ package net.programmer.igoodie.twitchspawn.tslanguage.event.builder; + +import org.json.JSONObject; + import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; import net.programmer.igoodie.twitchspawn.tracer.Platform; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEventPair; import net.programmer.igoodie.twitchspawn.util.JSONUtils; -import org.json.JSONObject; -import java.awt.*; public class PatreonBuilder extends EventBuilder { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TiltifyBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TiltifyBuilder.java index f97e928..3279e33 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TiltifyBuilder.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TiltifyBuilder.java @@ -1,13 +1,14 @@ package net.programmer.igoodie.twitchspawn.tslanguage.event.builder; + +import org.json.JSONObject; + import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; import net.programmer.igoodie.twitchspawn.tracer.Platform; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEventPair; import net.programmer.igoodie.twitchspawn.util.JSONUtils; -import org.json.JSONObject; -import java.awt.*; public class TiltifyBuilder extends EventBuilder { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TreatStreamBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TreatStreamBuilder.java index 8f11ebb..3ce8310 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TreatStreamBuilder.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TreatStreamBuilder.java @@ -1,13 +1,14 @@ package net.programmer.igoodie.twitchspawn.tslanguage.event.builder; + +import org.json.JSONObject; + import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; import net.programmer.igoodie.twitchspawn.tracer.Platform; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEventPair; import net.programmer.igoodie.twitchspawn.util.JSONUtils; -import org.json.JSONObject; -import java.awt.*; public class TreatStreamBuilder extends EventBuilder { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TwitchFollowBuilder.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TwitchFollowBuilder.java index 036e088..778813d 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TwitchFollowBuilder.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/event/builder/TwitchFollowBuilder.java @@ -1,13 +1,14 @@ package net.programmer.igoodie.twitchspawn.tslanguage.event.builder; + +import org.json.JSONObject; + import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; import net.programmer.igoodie.twitchspawn.tracer.Platform; import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEventPair; import net.programmer.igoodie.twitchspawn.util.JSONUtils; -import org.json.JSONObject; -import java.awt.*; public class TwitchFollowBuilder extends EventBuilder { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLEventKeyword.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLEventKeyword.java index 96f0f15..a5cd5ea 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLEventKeyword.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLEventKeyword.java @@ -1,15 +1,13 @@ package net.programmer.igoodie.twitchspawn.tslanguage.keyword; -import net.programmer.igoodie.twitchspawn.configuration.CredentialsConfig; -import net.programmer.igoodie.twitchspawn.tracer.Platform; -import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; -import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEventPair; -import net.programmer.igoodie.twitchspawn.tslanguage.event.builder.*; import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEventPair; +import net.programmer.igoodie.twitchspawn.tslanguage.event.builder.*; + public enum TSLEventKeyword { DONATION( diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLPredicateProperty.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLPredicateProperty.java index ed71b21..714228d 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLPredicateProperty.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/keyword/TSLPredicateProperty.java @@ -1,12 +1,13 @@ package net.programmer.igoodie.twitchspawn.tslanguage.keyword; -import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import java.lang.reflect.Field; import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; + public enum TSLPredicateProperty { ACTOR( diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLParser.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLParser.java index 8475dc3..d93a27b 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLParser.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/parser/TSLParser.java @@ -1,8 +1,17 @@ package net.programmer.igoodie.twitchspawn.tslanguage.parser; + import com.google.gson.JsonArray; import com.google.gson.JsonParseException; import com.google.gson.JsonParser; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import net.programmer.igoodie.twitchspawn.tslanguage.TSLFlowNode; import net.programmer.igoodie.twitchspawn.tslanguage.action.TSLAction; import net.programmer.igoodie.twitchspawn.tslanguage.event.TSLEvent; @@ -13,14 +22,6 @@ import net.programmer.igoodie.twitchspawn.tslanguage.predicate.TSLPredicate; import net.programmer.igoodie.twitchspawn.util.GsonUtils; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - public class TSLParser { private static Pattern PERCENTAGE_PATTERN = Pattern.compile("(?\\d{1,3})(\\.(?\\d{1,2}))?"); diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/InRangeComparator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/InRangeComparator.java index 2483064..5246b24 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/InRangeComparator.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/InRangeComparator.java @@ -1,10 +1,11 @@ package net.programmer.igoodie.twitchspawn.tslanguage.predicate; -import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; + public class InRangeComparator extends TSLComparator { public static Pattern RANGE_PATTERN = Pattern.compile("^\\[(?.+),(?.+)\\]$"); diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLPredicate.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLPredicate.java index f757e29..7148ac4 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLPredicate.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/predicate/TSLPredicate.java @@ -1,8 +1,9 @@ package net.programmer.igoodie.twitchspawn.tslanguage.predicate; + import net.programmer.igoodie.twitchspawn.TwitchSpawn; -import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.TSLFlowNode; +import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import net.programmer.igoodie.twitchspawn.tslanguage.keyword.TSLPredicateProperty; import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/udl/NotepadUDLUpdater.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/udl/NotepadUDLUpdater.java index a35b94c..e765cb7 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/udl/NotepadUDLUpdater.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/udl/NotepadUDLUpdater.java @@ -1,9 +1,8 @@ package net.programmer.igoodie.twitchspawn.udl; + import com.google.common.io.Resources; -import net.programmer.igoodie.twitchspawn.TwitchSpawn; import org.apache.commons.io.FileUtils; - import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -16,6 +15,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.programmer.igoodie.twitchspawn.TwitchSpawn; + public class NotepadUDLUpdater { private static Set PROCESSES_TO_TERMINATE = new HashSet<>(Arrays.asList( diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/util/ExpressionEvaluator.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/ExpressionEvaluator.java index ba90d1a..a6d61bb 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/util/ExpressionEvaluator.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/ExpressionEvaluator.java @@ -1,6 +1,5 @@ package net.programmer.igoodie.twitchspawn.util; -import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -11,6 +10,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.programmer.igoodie.twitchspawn.tslanguage.event.EventArguments; + public class ExpressionEvaluator { public static final Pattern EXPRESSION_PATTERN = Pattern.compile("\\$\\{(.*?)\\}"); diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/util/GsonUtils.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/GsonUtils.java index 00a6445..de8970e 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/util/GsonUtils.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/GsonUtils.java @@ -1,10 +1,10 @@ package net.programmer.igoodie.twitchspawn.util; + import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; - import java.util.LinkedList; import java.util.List; import java.util.Map; diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/util/JSONUtils.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/JSONUtils.java index 345ba0c..f3f002b 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/util/JSONUtils.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/JSONUtils.java @@ -1,9 +1,9 @@ package net.programmer.igoodie.twitchspawn.util; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; - import java.util.function.Consumer; public class JSONUtils { diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/util/PercentageRandomizer.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/PercentageRandomizer.java index 9d3bead..cd53e9d 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/util/PercentageRandomizer.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/util/PercentageRandomizer.java @@ -1,6 +1,5 @@ package net.programmer.igoodie.twitchspawn.util; -import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; import java.util.Collections; import java.util.LinkedList; @@ -9,6 +8,8 @@ import java.util.function.Consumer; import java.util.stream.Collectors; +import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLParser; + public class PercentageRandomizer { private static final int MAX_PERCENTAGE = 100_00; diff --git a/common/src/main/resources/META-INF/mods.toml b/common/src/main/resources/META-INF/mods.toml deleted file mode 100644 index 7b9b57a..0000000 --- a/common/src/main/resources/META-INF/mods.toml +++ /dev/null @@ -1,29 +0,0 @@ -modLoader="javafml" -loaderVersion="[37,)" -license="EPL-1.0" -issueTrackerURL="https://github.com/iGoodie/TwitchSpawn/issues" - -[[mods]] -modId="twitchspawn" -version="${file.jarVersion}" -displayName="TwitchSpawn" -authors="iGoodie" -logoFile="pack.png" -description=''' - TwitchSpawn listens for live events related to your Twitch channel using various Socket APIs. - Then it handles those events with the rules handcrafted by you! -''' - -[[dependencies.twitchspawn]] - modId="forge" - mandatory=true - versionRange="[37.0.1,)" - ordering="NONE" - side="BOTH" - -[[dependencies.twitchspawn]] - modId="minecraft" - mandatory=true - versionRange="[1.17.1,)" - ordering="NONE" - side="BOTH" diff --git a/common/src/main/resources/twitchspawn-common.mixins.json b/common/src/main/resources/twitchspawn-common.mixins.json new file mode 100644 index 0000000..a6b2724 --- /dev/null +++ b/common/src/main/resources/twitchspawn-common.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.programmer.igoodie.twitchspawn.mixin.fabric", + "compatibilityLevel": "JAVA_17", + "mixins": [ + ], + "client": [ + ], + "injectors": { + "defaultRequire": 1 + } +} From a6a02947ed89ce86be124193a8796edd135a474f Mon Sep 17 00:00:00 2001 From: BONNe Date: Sun, 24 Dec 2023 21:02:59 +0200 Subject: [PATCH 05/15] Implement forge-specific code --- forge/build.gradle | 3 + .../TwitchSpawnEventHandlerClientImpl.java | 32 +++++++++ .../forge/TwitchSpawnEventHandlerImpl.java | 70 +++++++++++++++++++ .../twitchspawn/forge/TwitchSpawnForge.java | 22 ++++++ .../forge/TwitchSpawnArgumentTypesImpl.java | 16 ++--- forge/src/main/resources/META-INF/mods.toml | 5 +- 6 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerClientImpl.java create mode 100644 forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerImpl.java create mode 100644 forge/src/main/java/net/programmer/igoodie/twitchspawn/forge/TwitchSpawnForge.java rename common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java => forge/src/main/java/net/programmer/igoodie/twitchspawn/registries/forge/TwitchSpawnArgumentTypesImpl.java (80%) diff --git a/forge/build.gradle b/forge/build.gradle index 9611155..ad406ce 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -39,6 +39,9 @@ dependencies { forgeRuntimeLibrary 'com.squareup.okhttp3:okhttp:3.8.1' forgeRuntimeLibrary 'io.socket:socket.io-client:1.0.2' + + shadowCommon 'com.squareup.okhttp3:okhttp:3.8.1' + shadowCommon 'io.socket:socket.io-client:1.0.2' } processResources { diff --git a/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerClientImpl.java b/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerClientImpl.java new file mode 100644 index 0000000..ac04174 --- /dev/null +++ b/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerClientImpl.java @@ -0,0 +1,32 @@ +package net.programmer.igoodie.twitchspawn.events.forge; + + +import net.minecraftforge.client.event.CustomizeGuiOverlayEvent; +import net.minecraftforge.client.event.RenderGuiOverlayEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.programmer.igoodie.twitchspawn.events.TwitchSpawnClientGuiEvent; + + +/** + * This class manages the registration of events. + */ +public class TwitchSpawnEventHandlerClientImpl +{ + @SubscribeEvent + public static void onScreenGuiOverlayEvent(CustomizeGuiOverlayEvent.DebugText event) + { + TwitchSpawnClientGuiEvent.DEBUG_TEXT.invoker().renderHud(event.getGuiGraphics()); + } + + @SubscribeEvent + public static void onRenderGuiOverlayPre(RenderGuiOverlayEvent.Pre event) + { + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_PRE.invoker().renderHud(event.getGuiGraphics(), event.getOverlay().id()); + } + + @SubscribeEvent + public static void onRenderGuiOverlayPost(RenderGuiOverlayEvent.Post event) + { + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_POST.invoker().renderHud(event.getGuiGraphics(), event.getOverlay().id()); + } +} diff --git a/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerImpl.java b/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerImpl.java new file mode 100644 index 0000000..d3ea853 --- /dev/null +++ b/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerImpl.java @@ -0,0 +1,70 @@ + +package net.programmer.igoodie.twitchspawn.events.forge; + + +import com.electronwill.nightconfig.core.io.ParsingException; +import com.google.gson.JsonSyntaxException; + +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.*; +import net.minecraftforge.forgespi.language.IModInfo; +import net.programmer.igoodie.twitchspawn.TwitchSpawn; +import net.programmer.igoodie.twitchspawn.events.TwitchSpawnCommonEvent; +import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; + + +/** + * This class handles the registration of events. + */ +public class TwitchSpawnEventHandlerImpl +{ + @OnlyIn(Dist.CLIENT) + public static void registerClient() + { + // Register client events. + MinecraftForge.EVENT_BUS.register(TwitchSpawnEventHandlerClientImpl.class); + + // Register error for incorrect configs. + TwitchSpawnCommonEvent.SETUP_EVENT.register(error -> { + ModLoadingStage stage = ModLoadingStage.COMMON_SETUP; + + ModContainer modContainer = ModList.get().getModContainerById(TwitchSpawn.MOD_ID).get(); + + IModInfo modInfo = modContainer.getModInfo(); + + for (Exception exception : error.getExceptions()) + { + String i18nMessage; + + if (exception instanceof TSLSyntaxError) + { + i18nMessage = "modloader.twitchspawn.error.tsl"; + } + else if (exception instanceof ParsingException) + { + i18nMessage = "modloader.twitchspawn.error.toml"; + } + else if (exception instanceof JsonSyntaxException) + { + i18nMessage = "modloader.twitchspawn.error.json"; + } + else + { + i18nMessage = "modloader.twitchspawn.error.unknown"; + } + + ModLoadingWarning warning = new ModLoadingWarning( + modInfo, stage, i18nMessage, + exception.getMessage(), + exception.getClass().getSimpleName() + ); + + ModLoader.get().addWarning(warning); + + TwitchSpawn.LOGGER.error(exception.getMessage()); + } + }); + } +} diff --git a/forge/src/main/java/net/programmer/igoodie/twitchspawn/forge/TwitchSpawnForge.java b/forge/src/main/java/net/programmer/igoodie/twitchspawn/forge/TwitchSpawnForge.java new file mode 100644 index 0000000..7806508 --- /dev/null +++ b/forge/src/main/java/net/programmer/igoodie/twitchspawn/forge/TwitchSpawnForge.java @@ -0,0 +1,22 @@ +package net.programmer.igoodie.twitchspawn.forge; + + +import dev.architectury.platform.forge.EventBuses; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.programmer.igoodie.twitchspawn.TwitchSpawn; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.programmer.igoodie.twitchspawn.registries.forge.TwitchSpawnArgumentTypesImpl; + + +@Mod(TwitchSpawn.MOD_ID) +public class TwitchSpawnForge { + public TwitchSpawnForge() { + // Submit our event bus to let architectury register our content on the right time + EventBuses.registerModEventBus(TwitchSpawn.MOD_ID, FMLJavaModLoadingContext.get().getModEventBus()); + TwitchSpawn.init(); + + // Register Registry + TwitchSpawnArgumentTypesImpl.REGISTRY.register(FMLJavaModLoadingContext.get().getModEventBus()); + } +} diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java b/forge/src/main/java/net/programmer/igoodie/twitchspawn/registries/forge/TwitchSpawnArgumentTypesImpl.java similarity index 80% rename from common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java rename to forge/src/main/java/net/programmer/igoodie/twitchspawn/registries/forge/TwitchSpawnArgumentTypesImpl.java index c754634..18e25a0 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/registries/TwitchSpawnAugmentTypes.java +++ b/forge/src/main/java/net/programmer/igoodie/twitchspawn/registries/forge/TwitchSpawnArgumentTypesImpl.java @@ -1,10 +1,9 @@ -package net.programmer.igoodie.twitchspawn.registries; +package net.programmer.igoodie.twitchspawn.registries.forge; import net.minecraft.commands.synchronization.ArgumentTypeInfo; import net.minecraft.commands.synchronization.ArgumentTypeInfos; import net.minecraft.commands.synchronization.SingletonArgumentInfo; -import net.minecraftforge.fml.common.Mod; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import net.programmer.igoodie.twitchspawn.TwitchSpawn; @@ -13,18 +12,19 @@ import net.programmer.igoodie.twitchspawn.command.TSLWordsArgumentType; -/** - * This class registers argument types. - */ -@Mod.EventBusSubscriber(modid = TwitchSpawn.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) -public class TwitchSpawnAugmentTypes +public class TwitchSpawnArgumentTypesImpl { /** * Registry for argument types. */ - public static final DeferredRegister> REGISTRY = + public static final net.minecraftforge.registries.DeferredRegister> REGISTRY = DeferredRegister.create(ForgeRegistries.COMMAND_ARGUMENT_TYPES, TwitchSpawn.MOD_ID); + public static void registerArgumentType() + { + // Do nothing. Forge is registred on startup. + } + static { // Argument type for ruleset names. REGISTRY.register("ruleset", () -> ArgumentTypeInfos.registerByClass(RulesetNameArgumentType.class, diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml index af7090b..8170bfc 100644 --- a/forge/src/main/resources/META-INF/mods.toml +++ b/forge/src/main/resources/META-INF/mods.toml @@ -42,7 +42,8 @@ authors="iGoodie, BONNe1704" #optional # The description text for the mod (multi line!) (#mandatory) description=''' -TwitchSpawn listens for live events related to your Twitch channel using various Socket APIs.\nThen it handles those events with the rules handcrafted by you! + TwitchSpawn listens for live events related to your Twitch channel using various Socket APIs. + Then it handles those events with the rules handcrafted by you! ''' # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. [[dependencies.twitchspawn]] #optional @@ -69,4 +70,4 @@ TwitchSpawn listens for live events related to your Twitch channel using various mandatory = true versionRange = "[9.1.12,)" ordering = "AFTER" - side = "BOTH" \ No newline at end of file + side = "BOTH" From 0e9023c6d523079e804fff4fbadd256e058d4174 Mon Sep 17 00:00:00 2001 From: BONNe Date: Sun, 24 Dec 2023 21:03:12 +0200 Subject: [PATCH 06/15] Implement fabric-specific code --- fabric/build.gradle | 8 +- .../events/fabric/CustomErrorScreen.java | 103 ++++++++++++++++++ .../fabric/TwitchSpawnEventHandlerImpl.java | 49 +++++++++ .../twitchspawn/fabric/TwitchSpawnFabric.java | 13 +++ .../twitchspawn/mixin/fabric/MixinGui.java | 72 ++++++++++++ .../mixin/fabric/ScreenAccessor.java | 27 +++++ .../fabric/TwitchSpawnArgumentTypesImpl.java | 44 ++++++++ 7 files changed, 313 insertions(+), 3 deletions(-) create mode 100644 fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/CustomErrorScreen.java create mode 100644 fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/TwitchSpawnEventHandlerImpl.java create mode 100644 fabric/src/main/java/net/programmer/igoodie/twitchspawn/fabric/TwitchSpawnFabric.java create mode 100644 fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/MixinGui.java create mode 100644 fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/ScreenAccessor.java create mode 100644 fabric/src/main/java/net/programmer/igoodie/twitchspawn/registries/fabric/TwitchSpawnArgumentTypesImpl.java diff --git a/fabric/build.gradle b/fabric/build.gradle index d9a63b3..6be5b6a 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -31,8 +31,10 @@ dependencies { implementation "com.electronwill.night-config:core:3.6.4" implementation "com.electronwill.night-config:toml:3.6.4" - implementation 'com.squareup.okhttp3:okhttp:3.8.1' - implementation 'io.socket:socket.io-client:1.0.2' + shadowCommon "com.electronwill.night-config:core:3.6.4" + shadowCommon "com.electronwill.night-config:toml:3.6.4" + shadowCommon "com.squareup.okhttp3:okhttp:3.8.1" + shadowCommon "io.socket:socket.io-client:1.0.2" } processResources { @@ -82,4 +84,4 @@ publishing { repositories { // Add repositories to publish to here. } -} \ No newline at end of file +} diff --git a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/CustomErrorScreen.java b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/CustomErrorScreen.java new file mode 100644 index 0000000..880f35c --- /dev/null +++ b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/CustomErrorScreen.java @@ -0,0 +1,103 @@ +// +// Created by BONNe +// Copyright - 2023 +// + + +package net.programmer.igoodie.twitchspawn.events.fabric; + + +import com.electronwill.nightconfig.core.io.ParsingException; +import com.google.gson.JsonSyntaxException; +import java.util.List; + +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.MultiLineTextWidget; +import net.minecraft.client.gui.screens.ErrorScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.util.FormattedCharSequence; +import net.programmer.igoodie.twitchspawn.mixin.fabric.ScreenAccessor; +import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; + + +/** + * Very simplistic error screen for fabric. + */ +public class CustomErrorScreen extends ErrorScreen +{ + private final List modLoadErrors; + + private Component errorHeader; + + + public CustomErrorScreen(List warnings) + { + super(Component.literal("Loading Error"), Component.literal("Twitch Spawn")); + this.modLoadErrors = warnings; + } + + + @Override + public void init() + { + super.init(); + this.clearWidgets(); + + this.errorHeader = Component.literal(ChatFormatting.WHITE + "Twitch Spawn Loading Error" + ChatFormatting.RESET); + + MutableComponent component = Component.empty(); + + this.modLoadErrors.forEach(exception -> + { + String i18nMessage; + + if (exception instanceof TSLSyntaxError) + { + i18nMessage = "modloader.twitchspawn.error.tsl"; + } + else if (exception instanceof ParsingException) + { + i18nMessage = "modloader.twitchspawn.error.toml"; + } + else if (exception instanceof JsonSyntaxException) + { + i18nMessage = "modloader.twitchspawn.error.json"; + } + else + { + i18nMessage = "modloader.twitchspawn.error.unknown"; + } + + component.append(Component.translatable(i18nMessage)). + append(Component.literal(exception.getMessage())). + append("\n"); + }); + + MultiLineTextWidget multiLineTextWidget = new MultiLineTextWidget(10, 45, component, this.font); + + this.addRenderableWidget(multiLineTextWidget); + } + + + @Override + public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) + { + this.renderBackground(guiGraphics, mouseX, mouseY, partialTick); + + drawMultiLineCenteredString(guiGraphics, font, errorHeader, this.width / 2, 10); + ((ScreenAccessor) this).getRenderables().forEach(button -> button.render(guiGraphics, mouseX, mouseY, partialTick)); + } + + + private void drawMultiLineCenteredString(GuiGraphics guiGraphics, Font fr, Component str, int x, int y) + { + for (FormattedCharSequence s : fr.split(str, this.width)) + { + guiGraphics.drawString(fr, s, (int) (x - fr.width(s) / 2.0), (int) y, 0xFFFFFF, true); + y += fr.lineHeight; + } + } +} diff --git a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/TwitchSpawnEventHandlerImpl.java b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/TwitchSpawnEventHandlerImpl.java new file mode 100644 index 0000000..00e429e --- /dev/null +++ b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/TwitchSpawnEventHandlerImpl.java @@ -0,0 +1,49 @@ +// +// Created by BONNe +// Copyright - 2023 +// + + +package net.programmer.igoodie.twitchspawn.events.fabric; + + +import dev.architectury.event.events.common.LifecycleEvent; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.ErrorScreen; +import net.minecraft.client.gui.screens.Overlay; +import net.programmer.igoodie.twitchspawn.TwitchSpawn; +import net.programmer.igoodie.twitchspawn.events.TwitchSpawnCommonEvent; + + +/** + * This class manages the registration of events. + */ +public class TwitchSpawnEventHandlerImpl +{ + /** + * Register client events. + */ + public static void registerClient() + { + // Register error for incorrect configs. + TwitchSpawnCommonEvent.SETUP_EVENT.register(exception -> { + ClientLifecycleEvents.CLIENT_STARTED.register(client -> + Minecraft.getInstance().setOverlay(new Overlay() + { + @Override + public void render(GuiGraphics guiGraphics, int i, int j, float f) + { + ErrorScreen errorScreen = new CustomErrorScreen(exception.getExceptions()); + errorScreen.init(client, + client.getWindow().getGuiScaledWidth(), + client.getWindow().getGuiScaledHeight()); + errorScreen.render(guiGraphics, i, j, f); + } + })); + }); + } +} diff --git a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/fabric/TwitchSpawnFabric.java b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/fabric/TwitchSpawnFabric.java new file mode 100644 index 0000000..cea148b --- /dev/null +++ b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/fabric/TwitchSpawnFabric.java @@ -0,0 +1,13 @@ +package net.programmer.igoodie.twitchspawn.fabric; + +import net.programmer.igoodie.twitchspawn.TwitchSpawn; +import net.fabricmc.api.ModInitializer; + + +public class TwitchSpawnFabric implements ModInitializer { + @Override + public void onInitialize() { + TwitchSpawn.init(); + TwitchSpawn.LOGGER.info("TwitchSpawn Fabric initialized!"); + } +} \ No newline at end of file diff --git a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/MixinGui.java b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/MixinGui.java new file mode 100644 index 0000000..b7e6417 --- /dev/null +++ b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/MixinGui.java @@ -0,0 +1,72 @@ +// +// Created by BONNe +// Copyright - 2023 +// + + +package net.programmer.igoodie.twitchspawn.mixin.fabric; + + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.resources.ResourceLocation; +import net.programmer.igoodie.twitchspawn.events.TwitchSpawnClientGuiEvent; + + +/** + * This mixin injects into render method to simulate similar entry points as in forge. + */ +@Mixin(value = Gui.class) +public class MixinGui +{ + @Inject(method = "render", at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/gui/Gui;renderHotbar(FLnet/minecraft/client/gui/GuiGraphics;)V")) + private void preRenderHotbar(GuiGraphics guiGraphics, float f, CallbackInfo ci) + { + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_PRE.invoker().renderHud( + guiGraphics, + ResourceLocation.of("hotbar", ':')); + } + + @Inject(method = "render", at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/gui/components/spectator/SpectatorGui;renderHotbar(Lnet/minecraft/client/gui/GuiGraphics;)V")) + private void preRenderHotbarSpectator(GuiGraphics guiGraphics, float f, CallbackInfo ci) + { + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_PRE.invoker().renderHud( + guiGraphics, + ResourceLocation.of("hotbar", ':')); + } + + @Inject(method = "render", at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/gui/Gui;renderHotbar(FLnet/minecraft/client/gui/GuiGraphics;)V", + shift = At.Shift.AFTER)) + private void postRenderHotbar(GuiGraphics guiGraphics, float f, CallbackInfo ci) + { + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_POST.invoker().renderHud( + guiGraphics, + ResourceLocation.of("hotbar", ':')); + } + + @Inject(method = "render", at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/gui/components/spectator/SpectatorGui;renderHotbar(Lnet/minecraft/client/gui/GuiGraphics;)V", + shift = At.Shift.AFTER)) + private void postRenderHotbarSpectator(GuiGraphics guiGraphics, float f, CallbackInfo ci) + { + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_POST.invoker().renderHud( + guiGraphics, + ResourceLocation.of("hotbar", ':')); + } + + @Inject(method = "render", at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/gui/Gui;renderEffects(Lnet/minecraft/client/gui/GuiGraphics;)V", + shift = At.Shift.AFTER)) + private void renderDebugText(GuiGraphics guiGraphics, float f, CallbackInfo ci) + { + TwitchSpawnClientGuiEvent.DEBUG_TEXT.invoker().renderHud(guiGraphics); + } +} diff --git a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/ScreenAccessor.java b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/ScreenAccessor.java new file mode 100644 index 0000000..731e337 --- /dev/null +++ b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/ScreenAccessor.java @@ -0,0 +1,27 @@ +// +// Created by BONNe +// Copyright - 2023 +// + + +package net.programmer.igoodie.twitchspawn.mixin.fabric; + + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +import net.minecraft.client.gui.components.Renderable; +import net.minecraft.client.gui.screens.Screen; + + +/** + * Accessor for screen rendables variable + */ +@Mixin(Screen.class) +public interface ScreenAccessor +{ + @Accessor + List getRenderables(); +} diff --git a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/registries/fabric/TwitchSpawnArgumentTypesImpl.java b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/registries/fabric/TwitchSpawnArgumentTypesImpl.java new file mode 100644 index 0000000..b9d3cb8 --- /dev/null +++ b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/registries/fabric/TwitchSpawnArgumentTypesImpl.java @@ -0,0 +1,44 @@ +// +// Created by BONNe +// Copyright - 2023 +// + + +package net.programmer.igoodie.twitchspawn.registries.fabric; + + +import net.fabricmc.fabric.api.command.v2.ArgumentTypeRegistry; +import net.minecraft.commands.synchronization.SingletonArgumentInfo; +import net.minecraft.resources.ResourceLocation; +import net.programmer.igoodie.twitchspawn.TwitchSpawn; +import net.programmer.igoodie.twitchspawn.command.RulesetNameArgumentType; +import net.programmer.igoodie.twitchspawn.command.StreamerArgumentType; +import net.programmer.igoodie.twitchspawn.command.TSLWordsArgumentType; + + +/** + * This class manages the registration of command argument types. + */ +public class TwitchSpawnArgumentTypesImpl +{ + /** + * Fabric has very simple command argument type registration. + */ + public static void registerArgumentType() + { + ArgumentTypeRegistry.registerArgumentType( + new ResourceLocation(TwitchSpawn.MOD_ID, "ruleset"), + RulesetNameArgumentType.class, + SingletonArgumentInfo.contextFree(RulesetNameArgumentType::rulesetName)); + + ArgumentTypeRegistry.registerArgumentType( + new ResourceLocation(TwitchSpawn.MOD_ID, "streamer"), + StreamerArgumentType.class, + SingletonArgumentInfo.contextFree(StreamerArgumentType::streamerNick)); + + ArgumentTypeRegistry.registerArgumentType( + new ResourceLocation(TwitchSpawn.MOD_ID, "tslwords"), + TSLWordsArgumentType.class, + SingletonArgumentInfo.contextFree(TSLWordsArgumentType::tslWords)); + } +} From 4cb804f0c90675c3d29dc5ef851ca821968972a2 Mon Sep 17 00:00:00 2001 From: BONNe Date: Sun, 24 Dec 2023 22:15:22 +0200 Subject: [PATCH 07/15] Swap to correct client event --- .../java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java | 5 +++-- .../igoodie/twitchspawn/forge/TwitchSpawnForge.java | 3 +-- 2 files changed, 4 insertions(+), 4 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 86df6a3..4f832c9 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java @@ -4,6 +4,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import dev.architectury.event.events.client.ClientPlayerEvent; import dev.architectury.event.events.common.CommandRegistrationEvent; import dev.architectury.event.events.common.LifecycleEvent; import dev.architectury.event.events.common.PlayerEvent; @@ -149,13 +150,13 @@ public static void initializeClient() TwitchSpawn.initializeCommon(); NotepadUDLUpdater.attemptUpdate(); - PlayerEvent.PLAYER_JOIN.register(player -> + ClientPlayerEvent.CLIENT_PLAYER_JOIN.register(player -> { StatusIndicatorOverlay.register(); GlobalChatCooldownOverlay.register(); }); - PlayerEvent.PLAYER_QUIT.register(player -> + ClientPlayerEvent.CLIENT_PLAYER_QUIT.register(player -> { StatusIndicatorOverlay.unregister(); GlobalChatCooldownOverlay.unregister(); diff --git a/forge/src/main/java/net/programmer/igoodie/twitchspawn/forge/TwitchSpawnForge.java b/forge/src/main/java/net/programmer/igoodie/twitchspawn/forge/TwitchSpawnForge.java index 7806508..6d7c5da 100644 --- a/forge/src/main/java/net/programmer/igoodie/twitchspawn/forge/TwitchSpawnForge.java +++ b/forge/src/main/java/net/programmer/igoodie/twitchspawn/forge/TwitchSpawnForge.java @@ -2,10 +2,9 @@ import dev.architectury.platform.forge.EventBuses; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.programmer.igoodie.twitchspawn.TwitchSpawn; import net.programmer.igoodie.twitchspawn.registries.forge.TwitchSpawnArgumentTypesImpl; From 2e3001f39b679a43e5337ad5e8ba2cda89747bc6 Mon Sep 17 00:00:00 2001 From: BONNe Date: Mon, 25 Dec 2023 02:08:19 +0200 Subject: [PATCH 08/15] Implement Config Error Screen This screen is triggered on client startup and has config errors (like in forge). Remove unnecessary parts from the optimizing screen exceptions. --- .../igoodie/twitchspawn/TwitchSpawn.java | 48 +++- .../gui/screens/LoadingErrorScreen.java | 254 ++++++++++++++++++ .../events/TwitchSpawnClientGuiEvent.java | 44 ++- .../events/TwitchSpawnCommonEvent.java | 17 -- .../assets/twitchspawn/lang/de_de.json | 7 +- .../assets/twitchspawn/lang/en_us.json | 5 + .../assets/twitchspawn/lang/es_es.json | 9 +- .../assets/twitchspawn/lang/fr_fr.json | 5 + .../assets/twitchspawn/lang/it_it.json | 5 + 9 files changed, 370 insertions(+), 24 deletions(-) create mode 100644 common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/screens/LoadingErrorScreen.java delete mode 100644 common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnCommonEvent.java 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 4f832c9..c5b10ad 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java @@ -12,14 +12,16 @@ import dev.architectury.utils.EnvExecutor; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.gui.screens.TitleScreen; import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; import net.programmer.igoodie.twitchspawn.client.gui.GlobalChatCooldownOverlay; import net.programmer.igoodie.twitchspawn.client.gui.StatusIndicatorOverlay; +import net.programmer.igoodie.twitchspawn.client.gui.screens.LoadingErrorScreen; import net.programmer.igoodie.twitchspawn.command.TwitchSpawnCommand; import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; import net.programmer.igoodie.twitchspawn.configuration.PreferencesConfig; -import net.programmer.igoodie.twitchspawn.events.TwitchSpawnCommonEvent; +import net.programmer.igoodie.twitchspawn.events.TwitchSpawnClientGuiEvent; import net.programmer.igoodie.twitchspawn.events.TwitchSpawnEventHandler; import net.programmer.igoodie.twitchspawn.network.NetworkManager; import net.programmer.igoodie.twitchspawn.network.packet.StatusChangedPacket; @@ -131,9 +133,10 @@ private static void initializeCommon() ConfigManager.loadConfigs(); NetworkManager.initialize(); } - catch (TwitchSpawnLoadingErrors e) + catch (TwitchSpawnLoadingErrors exception) { - TwitchSpawnCommonEvent.SETUP_EVENT.invoker().setupEvent(e); + EnvExecutor.runInEnv(Env.CLIENT, () -> () -> Client.notifyCrash(exception)); + EnvExecutor.runInEnv(Env.SERVER, () -> () -> Server.notifyCrash(exception)); } } @@ -144,6 +147,9 @@ private static void initializeCommon() @Environment(EnvType.CLIENT) public static class Client { + /** + * The client initialization. + */ @Environment(EnvType.CLIENT) public static void initializeClient() { @@ -162,6 +168,27 @@ public static void initializeClient() GlobalChatCooldownOverlay.unregister(); }); } + + + /** + * Notify the client about the config crash. + * @param errors The errors that caused the config crash. + */ + @Environment(EnvType.CLIENT) + public static void notifyCrash(TwitchSpawnLoadingErrors errors) + { + TwitchSpawnClientGuiEvent.FINISH_LOADING_OVERLAY.register((client, screen) -> + { + if (screen instanceof TitleScreen) + { + LoadingErrorScreen errorScreen = new LoadingErrorScreen(errors.getExceptions()); + errorScreen.init(client, + client.getWindow().getGuiScaledWidth(), + client.getWindow().getGuiScaledHeight()); + client.setScreen(errorScreen); + } + }); + } } @@ -171,10 +198,25 @@ public static void initializeClient() @Environment(EnvType.SERVER) public static class Server { + /** + * The server initialization. + */ @Environment(EnvType.SERVER) public static void initializeServer() { TwitchSpawn.initializeCommon(); } + + + /** + * Notify the server about the config crash. + * @param errors The errors that caused the config crash. + */ + @Environment(EnvType.SERVER) + public static void notifyCrash(TwitchSpawnLoadingErrors errors) + { + LOGGER.warn("TwitchSpawn config contains errors:"); + LOGGER.warn("\n" + errors.toString()); + } } } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/screens/LoadingErrorScreen.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/screens/LoadingErrorScreen.java new file mode 100644 index 0000000..0a0d49e --- /dev/null +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/screens/LoadingErrorScreen.java @@ -0,0 +1,254 @@ +// +// Created by BONNe +// Copyright - 2023 +// + + +package net.programmer.igoodie.twitchspawn.client.gui.screens; + + +import com.electronwill.nightconfig.core.io.ParsingException; +import com.google.gson.JsonSyntaxException; +import java.io.File; +import java.util.List; +import java.util.Objects; + +import net.minecraft.ChatFormatting; +import net.minecraft.Util; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.ObjectSelectionList; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import net.minecraft.util.FormattedCharSequence; +import net.programmer.igoodie.twitchspawn.TwitchSpawnLoadingErrors; +import net.programmer.igoodie.twitchspawn.configuration.ConfigManager; +import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; + + +/** + * Very simplistic error screen for fabric. + */ +public class LoadingErrorScreen extends Screen +{ + /** + * Creates a new error screen with the given exceptions. + * @param configLoadingExceptions The exceptions to display. + */ + public LoadingErrorScreen(List configLoadingExceptions) + { + super(Component.literal("Loading Error")); + this.configLoadingExceptions = configLoadingExceptions; + } + + + @Override + public void init() + { + super.init(); + this.clearWidgets(); + + this.errorScreenTitle = Component.translatable("modloader.twitchspawn.error.title"). + withStyle(ChatFormatting.YELLOW); + + this.addRenderableWidget(Button.builder( + Component.translatable("modloader.twitchspawn.error.folder"), + onPress -> Util.getPlatform().openFile(new File(ConfigManager.CONFIG_DIR_PATH))). + size(this.width / 2 - 55, 20). + pos(50, this.height - 46). + build()); + this.addRenderableWidget(Button.builder( + Component.translatable("modloader.twitchspawn.error.reload"), + onPress -> reloadConfigs()). + size(this.width / 2 - 55, 20). + pos(this.width / 2 + 5, this.height - 46). + build()); + this.addRenderableWidget(Button.builder( + Component.translatable("modloader.twitchspawn.error.continue"), + onPress -> this.minecraft.setScreen(null)). + size(this.width / 2, 20). + pos(this.width / 4, this.height - 24). + build()); + + this.entryList = new LoadingEntryList(this, this.configLoadingExceptions); + this.addWidget(this.entryList); + this.setFocused(this.entryList); + } + + + @Override + public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) + { + super.render(guiGraphics, mouseX, mouseY, partialTick); + this.entryList.render(guiGraphics, mouseX, mouseY, partialTick); + drawMultiLineCenteredString(guiGraphics, + font, + errorScreenTitle, + this.width / 2, + 10); + } + + + @Override + public void renderBackground(GuiGraphics guiGraphics, int i, int j, float f) + { + guiGraphics.fillGradient(0, 0, this.width, this.height, -12574688, -11530224); + } + + + /** + * This method reloads configs and repopulates list with new exceptions or close screen if everything + * is correct. + */ + private void reloadConfigs() + { + try + { + ConfigManager.loadConfigs(); + this.minecraft.setScreen(null); + } + catch (TwitchSpawnLoadingErrors e) + { + this.configLoadingExceptions.clear(); + this.configLoadingExceptions.addAll(e.getExceptions()); + this.init(); + } + } + + + /** + * This method draws multiline centered string. + * @param guiGraphics GuiGraphics instance. + * @param font FontRenderer instance. + * @param component String to draw. + * @param x X coordinate. + * @param y Y coordinate. + */ + private void drawMultiLineCenteredString(GuiGraphics guiGraphics, Font font, Component component, int x, int y) + { + for (FormattedCharSequence chars : font.split(component, this.width)) + { + guiGraphics.drawString(font, chars, (int) ((x - font.width(chars) / 2.0)), y, 0xFFFFFF, true); + y += font.lineHeight; + } + } + + + /** + * This class contains and renders all error entries. + */ + private static class LoadingEntryList extends ObjectSelectionList + { + LoadingEntryList(final LoadingErrorScreen parent, final List errors) + { + super(parent.minecraft, + parent.width, + parent.height, + 35, + parent.height - 50, + errors.stream().mapToInt(warning -> + parent.font.split(Component.literal(warning.getMessage()), parent.width - 20).size()). + max(). + orElse(0) * parent.minecraft.font.lineHeight + 8); + + errors.forEach(exception -> { + String i18nMessage; + + if (exception instanceof TSLSyntaxError) + { + i18nMessage = "modloader.twitchspawn.error.tsl"; + } + else if (exception instanceof ParsingException) + { + i18nMessage = "modloader.twitchspawn.error.toml"; + } + else if (exception instanceof JsonSyntaxException) + { + i18nMessage = "modloader.twitchspawn.error.json"; + } + else + { + i18nMessage = "modloader.twitchspawn.error.unknown"; + } + + this.addEntry(new LoadingMessageEntry( + Component.translatable(i18nMessage).withStyle(ChatFormatting.DARK_RED). + append(Component.literal(exception.getMessage()).withStyle(ChatFormatting.WHITE)))); + }); + } + + + @Override + protected int getScrollbarPosition() + { + return this.width - 6; + } + + + @Override + public int getRowWidth() + { + return this.width; + } + + + public class LoadingMessageEntry extends ObjectSelectionList.Entry + { + private final Component message; + + LoadingMessageEntry(final Component message) + { + this.message = Objects.requireNonNull(message); + } + + + @Override + public Component getNarration() + { + return Component.translatable("narrator.select", message); + } + + + @Override + public void render(GuiGraphics guiGraphics, + int entryIdx, + int top, + int left, + final int entryWidth, + final int entryHeight, + final int mouseX, + final int mouseY, + final boolean p_194999_5_, + final float partialTick) + { + Font font = Minecraft.getInstance().font; + var strings = font.split(message, LoadingEntryList.this.width - 20); + int y = top + 2; + + for (var string : strings) + { + guiGraphics.drawString(font, string, left + 5, y, 0xFFFFFF, false); + y += font.lineHeight; + } + } + } + } + + + /** + * List of config exceptions + */ + private final List configLoadingExceptions; + + /** + * The component that displays error entries. + */ + private LoadingEntryList entryList; + + /** + * The title of the error screen. + */ + private Component errorScreenTitle; +} diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnClientGuiEvent.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnClientGuiEvent.java index 802f4a8..9df5811 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnClientGuiEvent.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnClientGuiEvent.java @@ -5,21 +5,40 @@ import dev.architectury.event.EventFactory; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.screens.Overlay; +import net.minecraft.client.gui.screens.Screen; import net.minecraft.resources.ResourceLocation; @Environment(EnvType.CLIENT) public interface TwitchSpawnClientGuiEvent { + /** + * This event is fired when the debug text is rendered. + */ Event DEBUG_TEXT = EventFactory.createLoop(); + /** + * This event is fired before overlay is rendered. + */ Event OVERLAY_RENDER_PRE = EventFactory.createLoop(); + /** + * This event is fired after overlay is rendered. + */ Event OVERLAY_RENDER_POST = EventFactory.createLoop(); + /** + * This event is fired after loading screen is removed. + */ + Event FINISH_LOADING_OVERLAY = EventFactory.createLoop(); + + /** + * The forge event is {@link net.minecraftforge.client.event.CustomizeGuiOverlayEvent.DebugText} + * The fabric triggers it via {@link net.programmer.igoodie.twitchspawn.mixin.fabric.MixinGui#renderDebugText} + */ @Environment(EnvType.CLIENT) interface RenderDebugHud { @@ -27,6 +46,11 @@ interface RenderDebugHud } + /** + * The forge event is {@link net.minecraftforge.client.event.RenderGuiOverlayEvent.Pre} + * The fabric triggers it via {@link net.programmer.igoodie.twitchspawn.mixin.fabric.MixinGui#preRenderHotbar} + * and {@link net.programmer.igoodie.twitchspawn.mixin.fabric.MixinGui#preRenderHotbarSpectator} + */ @Environment(EnvType.CLIENT) interface OverlayRenderPre { @@ -34,9 +58,27 @@ interface OverlayRenderPre } + /** + * This event is fired when the debug text is rendered. + * The forge event is {@link net.minecraftforge.client.event.RenderGuiOverlayEvent.Post} + * The fabric triggers it via {@link net.programmer.igoodie.twitchspawn.mixin.fabric.MixinGui#postRenderHotbar} + * and {@link net.programmer.igoodie.twitchspawn.mixin.fabric.MixinGui#postRenderHotbarSpectator} + */ @Environment(EnvType.CLIENT) interface OverlayRenderPost { void renderHud(GuiGraphics graphics, ResourceLocation overlay); } + + + /** + * This event is fired when the debug text is rendered. + * The forge triggers it via {@link net.programmer.igoodie.twitchspawn.mixin.forge.MixinLoadingOverlay#overlayRemoveEvent} + * The fabric triggers it via {@link net.programmer.igoodie.twitchspawn.mixin.fabric.MixinLoadingOverlay#overlayRemoveEvent} + */ + @Environment(EnvType.CLIENT) + interface LoadingScreenFinish + { + void removeOverlay(Minecraft client, Screen screen); + } } diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnCommonEvent.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnCommonEvent.java deleted file mode 100644 index 4819b61..0000000 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/events/TwitchSpawnCommonEvent.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.programmer.igoodie.twitchspawn.events; - - -import dev.architectury.event.Event; -import dev.architectury.event.EventFactory; -import net.programmer.igoodie.twitchspawn.TwitchSpawnLoadingErrors; - - -public interface TwitchSpawnCommonEvent -{ - Event SETUP_EVENT = EventFactory.createCompoundEventResult(); - - interface SetupEvent - { - void setupEvent(TwitchSpawnLoadingErrors error); - } -} diff --git a/common/src/main/resources/assets/twitchspawn/lang/de_de.json b/common/src/main/resources/assets/twitchspawn/lang/de_de.json index 2a08bf1..06f64e2 100644 --- a/common/src/main/resources/assets/twitchspawn/lang/de_de.json +++ b/common/src/main/resources/assets/twitchspawn/lang/de_de.json @@ -1,4 +1,9 @@ { + "modloader.twitchspawn.error.title": "TwitchSpawn Errors", + "modloader.twitchspawn.error.continue": "Proceed to main menu", + "modloader.twitchspawn.error.folder": "Open Config Folder", + "modloader.twitchspawn.error.reload": "Reload Configs", + "modloader.twitchspawn.error.tsl": "TSL Error: §4{2}", "modloader.twitchspawn.error.json": "JSON Error: §4{2}", "modloader.twitchspawn.error.toml": "TOML Error: §4{2}", @@ -32,6 +37,6 @@ "commands.twitchspawn.test.not_found": "§4>> Kein Regelwerk mit {0} verbunden", "commands.twitchspawn.test.success": "§a>> Erfolgreich Regeln für {0} in die Warteschlange gestellt", - + "errors.twitchspawn.loading": "Kann TwitchSpawn nicht laden." } diff --git a/common/src/main/resources/assets/twitchspawn/lang/en_us.json b/common/src/main/resources/assets/twitchspawn/lang/en_us.json index c0e3b6c..bc80989 100644 --- a/common/src/main/resources/assets/twitchspawn/lang/en_us.json +++ b/common/src/main/resources/assets/twitchspawn/lang/en_us.json @@ -1,4 +1,9 @@ { + "modloader.twitchspawn.error.title": "TwitchSpawn Errors", + "modloader.twitchspawn.error.continue": "Proceed to main menu", + "modloader.twitchspawn.error.folder": "Open Config Folder", + "modloader.twitchspawn.error.reload": "Reload Configs", + "modloader.twitchspawn.error.tsl": "TSL Error: §4{2}", "modloader.twitchspawn.error.json": "JSON Error: §4{2}", "modloader.twitchspawn.error.toml": "TOML Error: §4{2}", diff --git a/common/src/main/resources/assets/twitchspawn/lang/es_es.json b/common/src/main/resources/assets/twitchspawn/lang/es_es.json index f717319..5894de8 100644 --- a/common/src/main/resources/assets/twitchspawn/lang/es_es.json +++ b/common/src/main/resources/assets/twitchspawn/lang/es_es.json @@ -1,5 +1,10 @@ - + { + "modloader.twitchspawn.error.title": "TwitchSpawn Errors", + "modloader.twitchspawn.error.continue": "Proceed to main menu", + "modloader.twitchspawn.error.folder": "Open Config Folder", + "modloader.twitchspawn.error.reload": "Reload Configs", + "modloader.twitchspawn.error.tsl": "Error de TSL: §4{2}", "modloader.twitchspawn.error.json": "Error de JSON: §4{2}", "modloader.twitchspawn.error.toml": "Error de TOML: §4{2}", @@ -35,4 +40,4 @@ "commands.twitchspawn.test.success": "§a>> Se han puesto en cola las reglas para {0}", "errors.twitchspawn.loading": "No se puede cargar TwitchSpawn." -} \ No newline at end of file +} diff --git a/common/src/main/resources/assets/twitchspawn/lang/fr_fr.json b/common/src/main/resources/assets/twitchspawn/lang/fr_fr.json index afbedb2..621a104 100644 --- a/common/src/main/resources/assets/twitchspawn/lang/fr_fr.json +++ b/common/src/main/resources/assets/twitchspawn/lang/fr_fr.json @@ -1,4 +1,9 @@ { + "modloader.twitchspawn.error.title": "TwitchSpawn Errors", + "modloader.twitchspawn.error.continue": "Proceed to main menu", + "modloader.twitchspawn.error.folder": "Open Config Folder", + "modloader.twitchspawn.error.reload": "Reload Configs", + "modloader.twitchspawn.error.tsl": "Erreur TSL: §4{2}", "modloader.twitchspawn.error.json": "Erreur JSON: §4{2}", "modloader.twitchspawn.error.toml": "Erreur TOML: §4{2}", diff --git a/common/src/main/resources/assets/twitchspawn/lang/it_it.json b/common/src/main/resources/assets/twitchspawn/lang/it_it.json index fe64440..7ced012 100644 --- a/common/src/main/resources/assets/twitchspawn/lang/it_it.json +++ b/common/src/main/resources/assets/twitchspawn/lang/it_it.json @@ -1,4 +1,9 @@ { + "modloader.twitchspawn.error.title": "TwitchSpawn Errors", + "modloader.twitchspawn.error.continue": "Proceed to main menu", + "modloader.twitchspawn.error.folder": "Open Config Folder", + "modloader.twitchspawn.error.reload": "Reload Configs", + "modloader.twitchspawn.error.tsl": "TSL Error: §4{2}", "modloader.twitchspawn.error.json": "JSON Error: §4{2}", "modloader.twitchspawn.error.toml": "TOML Error: §4{2}", From 776fa7488f57764334b70bbdad0438d32ef47294 Mon Sep 17 00:00:00 2001 From: BONNe Date: Mon, 25 Dec 2023 02:09:05 +0200 Subject: [PATCH 09/15] Replace fabric screen implementation with new implementation in architectury api. --- .../events/fabric/CustomErrorScreen.java | 103 ------------------ .../fabric/TwitchSpawnEventHandlerImpl.java | 29 +---- .../mixin/fabric/MixinLoadingOverlay.java | 41 +++++++ .../mixin/fabric/ScreenAccessor.java | 27 ----- .../main/resources/twitchspawn.mixins.json | 2 +- 5 files changed, 43 insertions(+), 159 deletions(-) delete mode 100644 fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/CustomErrorScreen.java create mode 100644 fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/MixinLoadingOverlay.java delete mode 100644 fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/ScreenAccessor.java diff --git a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/CustomErrorScreen.java b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/CustomErrorScreen.java deleted file mode 100644 index 880f35c..0000000 --- a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/CustomErrorScreen.java +++ /dev/null @@ -1,103 +0,0 @@ -// -// Created by BONNe -// Copyright - 2023 -// - - -package net.programmer.igoodie.twitchspawn.events.fabric; - - -import com.electronwill.nightconfig.core.io.ParsingException; -import com.google.gson.JsonSyntaxException; -import java.util.List; - -import net.minecraft.ChatFormatting; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.MultiLineTextWidget; -import net.minecraft.client.gui.screens.ErrorScreen; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.util.FormattedCharSequence; -import net.programmer.igoodie.twitchspawn.mixin.fabric.ScreenAccessor; -import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; - - -/** - * Very simplistic error screen for fabric. - */ -public class CustomErrorScreen extends ErrorScreen -{ - private final List modLoadErrors; - - private Component errorHeader; - - - public CustomErrorScreen(List warnings) - { - super(Component.literal("Loading Error"), Component.literal("Twitch Spawn")); - this.modLoadErrors = warnings; - } - - - @Override - public void init() - { - super.init(); - this.clearWidgets(); - - this.errorHeader = Component.literal(ChatFormatting.WHITE + "Twitch Spawn Loading Error" + ChatFormatting.RESET); - - MutableComponent component = Component.empty(); - - this.modLoadErrors.forEach(exception -> - { - String i18nMessage; - - if (exception instanceof TSLSyntaxError) - { - i18nMessage = "modloader.twitchspawn.error.tsl"; - } - else if (exception instanceof ParsingException) - { - i18nMessage = "modloader.twitchspawn.error.toml"; - } - else if (exception instanceof JsonSyntaxException) - { - i18nMessage = "modloader.twitchspawn.error.json"; - } - else - { - i18nMessage = "modloader.twitchspawn.error.unknown"; - } - - component.append(Component.translatable(i18nMessage)). - append(Component.literal(exception.getMessage())). - append("\n"); - }); - - MultiLineTextWidget multiLineTextWidget = new MultiLineTextWidget(10, 45, component, this.font); - - this.addRenderableWidget(multiLineTextWidget); - } - - - @Override - public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) - { - this.renderBackground(guiGraphics, mouseX, mouseY, partialTick); - - drawMultiLineCenteredString(guiGraphics, font, errorHeader, this.width / 2, 10); - ((ScreenAccessor) this).getRenderables().forEach(button -> button.render(guiGraphics, mouseX, mouseY, partialTick)); - } - - - private void drawMultiLineCenteredString(GuiGraphics guiGraphics, Font fr, Component str, int x, int y) - { - for (FormattedCharSequence s : fr.split(str, this.width)) - { - guiGraphics.drawString(fr, s, (int) (x - fr.width(s) / 2.0), (int) y, 0xFFFFFF, true); - y += fr.lineHeight; - } - } -} diff --git a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/TwitchSpawnEventHandlerImpl.java b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/TwitchSpawnEventHandlerImpl.java index 00e429e..f7f964a 100644 --- a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/TwitchSpawnEventHandlerImpl.java +++ b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/events/fabric/TwitchSpawnEventHandlerImpl.java @@ -7,18 +7,6 @@ package net.programmer.igoodie.twitchspawn.events.fabric; -import dev.architectury.event.events.common.LifecycleEvent; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.screens.ErrorScreen; -import net.minecraft.client.gui.screens.Overlay; -import net.programmer.igoodie.twitchspawn.TwitchSpawn; -import net.programmer.igoodie.twitchspawn.events.TwitchSpawnCommonEvent; - - /** * This class manages the registration of events. */ @@ -29,21 +17,6 @@ public class TwitchSpawnEventHandlerImpl */ public static void registerClient() { - // Register error for incorrect configs. - TwitchSpawnCommonEvent.SETUP_EVENT.register(exception -> { - ClientLifecycleEvents.CLIENT_STARTED.register(client -> - Minecraft.getInstance().setOverlay(new Overlay() - { - @Override - public void render(GuiGraphics guiGraphics, int i, int j, float f) - { - ErrorScreen errorScreen = new CustomErrorScreen(exception.getExceptions()); - errorScreen.init(client, - client.getWindow().getGuiScaledWidth(), - client.getWindow().getGuiScaledHeight()); - errorScreen.render(guiGraphics, i, j, f); - } - })); - }); + // Fabric events are registered via mixins. } } diff --git a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/MixinLoadingOverlay.java b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/MixinLoadingOverlay.java new file mode 100644 index 0000000..7c7467c --- /dev/null +++ b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/MixinLoadingOverlay.java @@ -0,0 +1,41 @@ +// +// Created by BONNe +// Copyright - 2023 +// + + +package net.programmer.igoodie.twitchspawn.mixin.fabric; + + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.LoadingOverlay; +import net.programmer.igoodie.twitchspawn.events.TwitchSpawnClientGuiEvent; + + +/** + * This mixin is used to trigger the {@link TwitchSpawnClientGuiEvent#FINISH_LOADING_OVERLAY} event. + */ +@Mixin(value = LoadingOverlay.class, remap = false) +public class MixinLoadingOverlay +{ + @Shadow + @Final + private Minecraft minecraft; + + + @Inject(method = "render", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/Minecraft;setOverlay(Lnet/minecraft/client/gui/screens/Overlay;)V", + shift = At.Shift.AFTER)) + private void overlayRemoveEvent(CallbackInfo callbackInfo) + { + TwitchSpawnClientGuiEvent.FINISH_LOADING_OVERLAY.invoker().removeOverlay(this.minecraft, this.minecraft.screen); + } +} diff --git a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/ScreenAccessor.java b/fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/ScreenAccessor.java deleted file mode 100644 index 731e337..0000000 --- a/fabric/src/main/java/net/programmer/igoodie/twitchspawn/mixin/fabric/ScreenAccessor.java +++ /dev/null @@ -1,27 +0,0 @@ -// -// Created by BONNe -// Copyright - 2023 -// - - -package net.programmer.igoodie.twitchspawn.mixin.fabric; - - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.List; - -import net.minecraft.client.gui.components.Renderable; -import net.minecraft.client.gui.screens.Screen; - - -/** - * Accessor for screen rendables variable - */ -@Mixin(Screen.class) -public interface ScreenAccessor -{ - @Accessor - List getRenderables(); -} diff --git a/fabric/src/main/resources/twitchspawn.mixins.json b/fabric/src/main/resources/twitchspawn.mixins.json index e99789a..edaef3d 100644 --- a/fabric/src/main/resources/twitchspawn.mixins.json +++ b/fabric/src/main/resources/twitchspawn.mixins.json @@ -5,7 +5,7 @@ "compatibilityLevel": "JAVA_17", "client": [ "MixinGui", - "ScreenAccessor" + "MixinLoadingOverlay" ], "injectors": { "defaultRequire": 1 From ae3a1a80b353fd75920f12c527b9116ddc2f28eb Mon Sep 17 00:00:00 2001 From: BONNe Date: Mon, 25 Dec 2023 02:09:23 +0200 Subject: [PATCH 10/15] Replace forge error screen with new implementation from architectury api. --- .../TwitchSpawnEventHandlerClientImpl.java | 32 --------- .../forge/TwitchSpawnEventHandlerImpl.java | 66 +++++++------------ .../mixin/forge/MixinForgeLoadingOverlay.java | 41 ++++++++++++ .../main/resources/twitchspawn.mixins.json | 1 + 4 files changed, 64 insertions(+), 76 deletions(-) delete mode 100644 forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerClientImpl.java create mode 100644 forge/src/main/java/net/programmer/igoodie/twitchspawn/mixin/forge/MixinForgeLoadingOverlay.java diff --git a/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerClientImpl.java b/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerClientImpl.java deleted file mode 100644 index ac04174..0000000 --- a/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerClientImpl.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.programmer.igoodie.twitchspawn.events.forge; - - -import net.minecraftforge.client.event.CustomizeGuiOverlayEvent; -import net.minecraftforge.client.event.RenderGuiOverlayEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.programmer.igoodie.twitchspawn.events.TwitchSpawnClientGuiEvent; - - -/** - * This class manages the registration of events. - */ -public class TwitchSpawnEventHandlerClientImpl -{ - @SubscribeEvent - public static void onScreenGuiOverlayEvent(CustomizeGuiOverlayEvent.DebugText event) - { - TwitchSpawnClientGuiEvent.DEBUG_TEXT.invoker().renderHud(event.getGuiGraphics()); - } - - @SubscribeEvent - public static void onRenderGuiOverlayPre(RenderGuiOverlayEvent.Pre event) - { - TwitchSpawnClientGuiEvent.OVERLAY_RENDER_PRE.invoker().renderHud(event.getGuiGraphics(), event.getOverlay().id()); - } - - @SubscribeEvent - public static void onRenderGuiOverlayPost(RenderGuiOverlayEvent.Post event) - { - TwitchSpawnClientGuiEvent.OVERLAY_RENDER_POST.invoker().renderHud(event.getGuiGraphics(), event.getOverlay().id()); - } -} diff --git a/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerImpl.java b/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerImpl.java index d3ea853..f745fff 100644 --- a/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerImpl.java +++ b/forge/src/main/java/net/programmer/igoodie/twitchspawn/events/forge/TwitchSpawnEventHandlerImpl.java @@ -2,17 +2,13 @@ package net.programmer.igoodie.twitchspawn.events.forge; -import com.electronwill.nightconfig.core.io.ParsingException; -import com.google.gson.JsonSyntaxException; - import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.event.CustomizeGuiOverlayEvent; +import net.minecraftforge.client.event.RenderGuiOverlayEvent; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.*; -import net.minecraftforge.forgespi.language.IModInfo; -import net.programmer.igoodie.twitchspawn.TwitchSpawn; -import net.programmer.igoodie.twitchspawn.events.TwitchSpawnCommonEvent; -import net.programmer.igoodie.twitchspawn.tslanguage.parser.TSLSyntaxError; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.programmer.igoodie.twitchspawn.events.TwitchSpawnClientGuiEvent; /** @@ -24,47 +20,29 @@ public class TwitchSpawnEventHandlerImpl public static void registerClient() { // Register client events. - MinecraftForge.EVENT_BUS.register(TwitchSpawnEventHandlerClientImpl.class); - - // Register error for incorrect configs. - TwitchSpawnCommonEvent.SETUP_EVENT.register(error -> { - ModLoadingStage stage = ModLoadingStage.COMMON_SETUP; - - ModContainer modContainer = ModList.get().getModContainerById(TwitchSpawn.MOD_ID).get(); + MinecraftForge.EVENT_BUS.register(TwitchSpawnEventHandlerImpl.class); + } - IModInfo modInfo = modContainer.getModInfo(); - for (Exception exception : error.getExceptions()) - { - String i18nMessage; + @SubscribeEvent + public static void onScreenGuiOverlayEvent(CustomizeGuiOverlayEvent.DebugText event) + { + TwitchSpawnClientGuiEvent.DEBUG_TEXT.invoker().renderHud(event.getGuiGraphics()); + } - if (exception instanceof TSLSyntaxError) - { - i18nMessage = "modloader.twitchspawn.error.tsl"; - } - else if (exception instanceof ParsingException) - { - i18nMessage = "modloader.twitchspawn.error.toml"; - } - else if (exception instanceof JsonSyntaxException) - { - i18nMessage = "modloader.twitchspawn.error.json"; - } - else - { - i18nMessage = "modloader.twitchspawn.error.unknown"; - } - ModLoadingWarning warning = new ModLoadingWarning( - modInfo, stage, i18nMessage, - exception.getMessage(), - exception.getClass().getSimpleName() - ); + @SubscribeEvent + public static void onRenderGuiOverlayPre(RenderGuiOverlayEvent.Pre event) + { + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_PRE.invoker().renderHud(event.getGuiGraphics(), + event.getOverlay().id()); + } - ModLoader.get().addWarning(warning); - TwitchSpawn.LOGGER.error(exception.getMessage()); - } - }); + @SubscribeEvent + public static void onRenderGuiOverlayPost(RenderGuiOverlayEvent.Post event) + { + TwitchSpawnClientGuiEvent.OVERLAY_RENDER_POST.invoker().renderHud(event.getGuiGraphics(), + event.getOverlay().id()); } } diff --git a/forge/src/main/java/net/programmer/igoodie/twitchspawn/mixin/forge/MixinForgeLoadingOverlay.java b/forge/src/main/java/net/programmer/igoodie/twitchspawn/mixin/forge/MixinForgeLoadingOverlay.java new file mode 100644 index 0000000..9c3dd8a --- /dev/null +++ b/forge/src/main/java/net/programmer/igoodie/twitchspawn/mixin/forge/MixinForgeLoadingOverlay.java @@ -0,0 +1,41 @@ +// +// Created by BONNe +// Copyright - 2023 +// + + +package net.programmer.igoodie.twitchspawn.mixin.forge; + + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.Minecraft; +import net.minecraftforge.client.loading.ForgeLoadingOverlay; +import net.programmer.igoodie.twitchspawn.events.TwitchSpawnClientGuiEvent; + + +/** + * This mixin is used to trigger the {@link TwitchSpawnClientGuiEvent#FINISH_LOADING_OVERLAY} event. + */ +@Mixin(value = ForgeLoadingOverlay.class, remap = false) +public class MixinForgeLoadingOverlay +{ + @Shadow + @Final + private Minecraft minecraft; + + + @Inject(method = "render", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/Minecraft;setOverlay(Lnet/minecraft/client/gui/screens/Overlay;)V", + shift = At.Shift.AFTER)) + private void overlayRemoveEvent(CallbackInfo callbackInfo) + { + TwitchSpawnClientGuiEvent.FINISH_LOADING_OVERLAY.invoker().removeOverlay(this.minecraft, this.minecraft.screen); + } +} diff --git a/forge/src/main/resources/twitchspawn.mixins.json b/forge/src/main/resources/twitchspawn.mixins.json index 40ccef5..2b470a3 100644 --- a/forge/src/main/resources/twitchspawn.mixins.json +++ b/forge/src/main/resources/twitchspawn.mixins.json @@ -6,6 +6,7 @@ "mixins": [ ], "client": [ + "MixinForgeLoadingOverlay" ], "injectors": { "defaultRequire": 1 From 705b34b237b01dfd2300fb0ebea92a91e62838ea Mon Sep 17 00:00:00 2001 From: BONNe Date: Mon, 25 Dec 2023 02:17:22 +0200 Subject: [PATCH 11/15] Fixes an issue when wrong config would not allow to play. --- .../java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 c5b10ad..af0cf20 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/TwitchSpawn.java @@ -130,8 +130,8 @@ private static void initializeCommon() TwitchSpawnSoundEvent.REGISTRY.register(); TwitchSpawnArgumentTypes.registerArgumentType(); - ConfigManager.loadConfigs(); - NetworkManager.initialize(); + NetworkManager.initialize(); + ConfigManager.loadConfigs(); } catch (TwitchSpawnLoadingErrors exception) { From fe21047c5f44d1c5c003fcbc61c4bcede4d08aa0 Mon Sep 17 00:00:00 2001 From: BONNe Date: Mon, 25 Dec 2023 02:26:51 +0200 Subject: [PATCH 12/15] Add latvian language file --- .../assets/twitchspawn/lang/lv_lv.json | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 common/src/main/resources/assets/twitchspawn/lang/lv_lv.json diff --git a/common/src/main/resources/assets/twitchspawn/lang/lv_lv.json b/common/src/main/resources/assets/twitchspawn/lang/lv_lv.json new file mode 100644 index 0000000..a9a8deb --- /dev/null +++ b/common/src/main/resources/assets/twitchspawn/lang/lv_lv.json @@ -0,0 +1,42 @@ +{ + "modloader.twitchspawn.error.title": "TwitchSpawn Kļūdas", + "modloader.twitchspawn.error.continue": "Turpināt uz galveno izvēlni", + "modloader.twitchspawn.error.folder": "Atvērt konfigurācijas mapi", + "modloader.twitchspawn.error.reload": "Pārlādēd konfigurācijas", + + "modloader.twitchspawn.error.tsl": "TSL Kļūda: §4{2}", + "modloader.twitchspawn.error.json": "JSON Kļūda: §4{2}", + "modloader.twitchspawn.error.toml": "TOML Kļūda: §4{2}", + "modloader.twitchspawn.error.unknown": "Nezināma Kļūda: §4{2} ({3})", + + "commands.twitchspawn.reloadcfg.success": "§3>> Konfigurācijas faili pārlādēti!", + "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Kļūda pārlādējot. Sintakses kļūda:\n{0}", + "commands.twitchspawn.reloadcfg.already_started": "§4>> TwitchSpawn nepieciešams apturēt, lai pārlādētu konfigurācijas failus.", + "commands.twitchspawn.reloadcfg.no_perm": "§4>> Tev nav atļaujas pārlādēt TwitchSpawn konfigurāciju.", + + "commands.twitchspawn.status.on": "§3>> TwitchSpawn šobrīd strādā. [ON]", + "commands.twitchspawn.status.off": "§3>> TwitchSpawn šobrīd ir izslēgts. [OFF]", + + "commands.twitchspawn.start.success": "§A>> TwitchSpawn tagad ir startēts šajā serverī!", + "commands.twitchspawn.start.illegal_state": "§4>> TwitchSpawn jau darbojas.", + "commands.twitchspawn.start.no_perm": "§4>> Jums nav atļaujas startēt TwitchSpawn.", + + "commands.twitchspawn.stop.success": "§6>> TwitchSpawn apturēja {0} (iemesls: {1})", + "commands.twitchspawn.stop.illegal_state": "§4>> TwitchSpawn jau ir apturēts.", + "commands.twitchspawn.stop.no_perm": "§4>> Jums nav atļaujas apturēt TwitchSpawn.", + + "commands.twitchspawn.rules.list": "§3>> Noteikumu kopas priekš: {0}", + "commands.twitchspawn.rules.default": "§3>> ielādētā noklusējuma noteikumu kopa ietver:\n {1}", + "commands.twitchspawn.rules.one": "§3>> {0} ielādētā noteikumu kopa ietver:\n {1}", + "commands.twitchspawn.rules.one.fail": "§4>> {0} netika ielādēta noteikumu kopa", + + "commands.twitchspawn.simulate.missing": "§4 >> simulācijas objektā trūkst notikuma nosaukuma. Paredzēts notikums lauks.", + "commands.twitchspawn.simulate.invalid_event": "§4 >> Nederīgs notikuma nosaukums - > {0}", + "commands.twitchspawn.simulate.success": "§A >> simulācija sekmīgi izslēgta {0}", + "commands.twitchspawn.simulate.no_perm": "§4 >> Jums nav atļaujas simulēt notikumu.", + + "commands.twitchspawn.test.not_found": "§4 >> ar {0} nav saistīta noteikumu kopa", + "commands.twitchspawn.test.success": "§A >> {0} noteikumus ir sekmīgi ievietotas rindā", + + "errors.twitchspawn.loading": "Nevarēja ielādēt TwitchSpawn" +} From 1a853bbd363d86ca1726d2810b17eb440a8c2a67 Mon Sep 17 00:00:00 2001 From: BONNe Date: Mon, 25 Dec 2023 03:31:19 +0200 Subject: [PATCH 13/15] Fixes translation for fabric. --- .../gui/screens/LoadingErrorScreen.java | 3 +- .../assets/twitchspawn/lang/de_de.json | 28 +++++++++---------- .../assets/twitchspawn/lang/en_us.json | 28 +++++++++---------- .../assets/twitchspawn/lang/es_es.json | 28 +++++++++---------- .../assets/twitchspawn/lang/fr_fr.json | 28 +++++++++---------- .../assets/twitchspawn/lang/it_it.json | 28 +++++++++---------- .../assets/twitchspawn/lang/lv_lv.json | 28 +++++++++---------- 7 files changed, 85 insertions(+), 86 deletions(-) diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/screens/LoadingErrorScreen.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/screens/LoadingErrorScreen.java index 0a0d49e..baf0007 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/screens/LoadingErrorScreen.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/client/gui/screens/LoadingErrorScreen.java @@ -174,8 +174,7 @@ else if (exception instanceof JsonSyntaxException) } this.addEntry(new LoadingMessageEntry( - Component.translatable(i18nMessage).withStyle(ChatFormatting.DARK_RED). - append(Component.literal(exception.getMessage()).withStyle(ChatFormatting.WHITE)))); + Component.translatable(i18nMessage, exception.getMessage(), exception.getClass().toString()))); }); } diff --git a/common/src/main/resources/assets/twitchspawn/lang/de_de.json b/common/src/main/resources/assets/twitchspawn/lang/de_de.json index 06f64e2..b11a6b9 100644 --- a/common/src/main/resources/assets/twitchspawn/lang/de_de.json +++ b/common/src/main/resources/assets/twitchspawn/lang/de_de.json @@ -4,13 +4,13 @@ "modloader.twitchspawn.error.folder": "Open Config Folder", "modloader.twitchspawn.error.reload": "Reload Configs", - "modloader.twitchspawn.error.tsl": "TSL Error: §4{2}", - "modloader.twitchspawn.error.json": "JSON Error: §4{2}", - "modloader.twitchspawn.error.toml": "TOML Error: §4{2}", - "modloader.twitchspawn.error.unknown": "Unbekannter Fehler: §4{2} ({3})", + "modloader.twitchspawn.error.tsl": "TSL Error: §4%s", + "modloader.twitchspawn.error.json": "JSON Error: §4%s", + "modloader.twitchspawn.error.toml": "TOML Error: §4%s", + "modloader.twitchspawn.error.unknown": "Unbekannter Fehler: §4%s (%s)", "commands.twitchspawn.reloadcfg.success": "§3>> Alle Konfigurationen erfolgreich neu geladen", - "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Neu laden gescheitert. Syntax Fehler: \n{0}", + "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Neu laden gescheitert. Syntax Fehler: \n%s", "commands.twitchspawn.reloadcfg.already_started": "§4>> TwitchSpawn sollte angehalten werden, damit die Konfigurationen neu geladen werden können. ", "commands.twitchspawn.reloadcfg.no_perm": "§4>> Du hast keine Berechtigung die TwitchSpawn Konfigurationen neu zu laden.", @@ -21,22 +21,22 @@ "commands.twitchspawn.start.illegal_state": "§4>> TwitchSpawn läuft bereits.", "commands.twitchspawn.start.no_perm": "§4>> Du hast keine Berechtigung TwitchSpawn zu starten.", - "commands.twitchspawn.stop.success": "§6>> TwitchSpawn wurde von {0} angehalten (Ursache: {1})", + "commands.twitchspawn.stop.success": "§6>> TwitchSpawn wurde von %s angehalten (Ursache: %2$s)", "commands.twitchspawn.stop.illegal_state": "§4>> TwitchSpawn wurde bereits angehalten.", "commands.twitchspawn.stop.no_perm": "§4>> Du hast keine Berechtigung TwitchSpawn anzuhalten.", - "commands.twitchspawn.rules.list": "§3>> Regelset ist geladen für: {0}", - "commands.twitchspawn.rules.default": "§3>> Das geladene Standard-Regelset enthält folgendes:\n{1}", - "commands.twitchspawn.rules.one": "§3>> Das für {0} geladene Regelset enthält folgendes:\n{1}", - "commands.twitchspawn.rules.one.fail": "§4>> Für {0} wurde kein Regelset geladen", + "commands.twitchspawn.rules.list": "§3>> Regelset ist geladen für: %s", + "commands.twitchspawn.rules.default": "§3>> Das geladene Standard-Regelset enthält folgendes:\n%2$s", + "commands.twitchspawn.rules.one": "§3>> Das für %s geladene Regelset enthält folgendes:\n%2$s", + "commands.twitchspawn.rules.one.fail": "§4>> Für %s wurde kein Regelset geladen", "commands.twitchspawn.simulate.missing": "§4>> Im Simulationsobjekt fehlt ein Event-Name. Erwartet \"event\" Feld.", - "commands.twitchspawn.simulate.invalid_event": "§4>> Ungültiger Event-Name -> {0}", - "commands.twitchspawn.simulate.success": "§a>> Simulation erfolgreich ausgeführt {0}", + "commands.twitchspawn.simulate.invalid_event": "§4>> Ungültiger Event-Name -> %s", + "commands.twitchspawn.simulate.success": "§a>> Simulation erfolgreich ausgeführt %s", "commands.twitchspawn.simulate.no_perm": "§4>> Du hast keine Berechtigung ein Event zu simulieren.", - "commands.twitchspawn.test.not_found": "§4>> Kein Regelwerk mit {0} verbunden", - "commands.twitchspawn.test.success": "§a>> Erfolgreich Regeln für {0} in die Warteschlange gestellt", + "commands.twitchspawn.test.not_found": "§4>> Kein Regelwerk mit %s verbunden", + "commands.twitchspawn.test.success": "§a>> Erfolgreich Regeln für %s in die Warteschlange gestellt", "errors.twitchspawn.loading": "Kann TwitchSpawn nicht laden." } diff --git a/common/src/main/resources/assets/twitchspawn/lang/en_us.json b/common/src/main/resources/assets/twitchspawn/lang/en_us.json index bc80989..6739fb9 100644 --- a/common/src/main/resources/assets/twitchspawn/lang/en_us.json +++ b/common/src/main/resources/assets/twitchspawn/lang/en_us.json @@ -4,13 +4,13 @@ "modloader.twitchspawn.error.folder": "Open Config Folder", "modloader.twitchspawn.error.reload": "Reload Configs", - "modloader.twitchspawn.error.tsl": "TSL Error: §4{2}", - "modloader.twitchspawn.error.json": "JSON Error: §4{2}", - "modloader.twitchspawn.error.toml": "TOML Error: §4{2}", - "modloader.twitchspawn.error.unknown": "Unknown Error: §4{2} ({3})", + "modloader.twitchspawn.error.tsl": "§4TSL Error: §4%s", + "modloader.twitchspawn.error.json": "§4JSON Error: §4%s", + "modloader.twitchspawn.error.toml": "§4TOML Error: §4%s", + "modloader.twitchspawn.error.unknown": "§4Unknown Error: §4%s (%s)", "commands.twitchspawn.reloadcfg.success": "§3>> Successfully reloaded all the configs", - "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Failed to reload. Syntax errors:\n{0}", + "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Failed to reload. Syntax errors:\n%s", "commands.twitchspawn.reloadcfg.already_started": "§4>> TwitchSpawn should be stopped in order to be able to reload configs.", "commands.twitchspawn.reloadcfg.no_perm": "§4>> You do not have permission to reload TwitchSpawn configs.", @@ -21,22 +21,22 @@ "commands.twitchspawn.start.illegal_state": "§4>> TwitchSpawn is already running.", "commands.twitchspawn.start.no_perm": "§4>> You do not have permission to start TwitchSpawn.", - "commands.twitchspawn.stop.success": "§6>> TwitchSpawn stopped by {0} (Reason: {1})", + "commands.twitchspawn.stop.success": "§6>> TwitchSpawn stopped by %1$s (Reason: %2$s)", "commands.twitchspawn.stop.illegal_state": "§4>> TwitchSpawn is already stopped.", "commands.twitchspawn.stop.no_perm": "§4>> You do not have permission to stop TwitchSpawn.", - "commands.twitchspawn.rules.list": "§3>> Rulesets loaded for: {0}", - "commands.twitchspawn.rules.default": "§3>> Default ruleset loaded includes following:\n{1}", - "commands.twitchspawn.rules.one": "§3>> Ruleset loaded for {0} includes following:\n{1}", - "commands.twitchspawn.rules.one.fail": "§4>> No ruleset was loaded for {0}", + "commands.twitchspawn.rules.list": "§3>> Rulesets loaded for: %s", + "commands.twitchspawn.rules.default": "§3>> Default ruleset loaded includes following:\n%2$s", + "commands.twitchspawn.rules.one": "§3>> Ruleset loaded for %1$s includes following:\n%2$s", + "commands.twitchspawn.rules.one.fail": "§4>> No ruleset was loaded for %s", "commands.twitchspawn.simulate.missing": "§4>> Missing event name in simulation object. Expected \"event\" field.", - "commands.twitchspawn.simulate.invalid_event": "§4>> Invalid event name -> {0}", - "commands.twitchspawn.simulate.success": "§a>> Simulation fired off successfully {0}", + "commands.twitchspawn.simulate.invalid_event": "§4>> Invalid event name -> %s", + "commands.twitchspawn.simulate.success": "§a>> Simulation fired off successfully %s", "commands.twitchspawn.simulate.no_perm": "§4>> You do not have permission to simulate an event.", - "commands.twitchspawn.test.not_found": "§4>> No ruleset associated with {0}", - "commands.twitchspawn.test.success": "§a>> Successfully queued rules for {0}", + "commands.twitchspawn.test.not_found": "§4>> No ruleset associated with %s", + "commands.twitchspawn.test.success": "§a>> Successfully queued rules for %s", "errors.twitchspawn.loading": "Cannot load TwitchSpawn" } diff --git a/common/src/main/resources/assets/twitchspawn/lang/es_es.json b/common/src/main/resources/assets/twitchspawn/lang/es_es.json index 5894de8..ed1d547 100644 --- a/common/src/main/resources/assets/twitchspawn/lang/es_es.json +++ b/common/src/main/resources/assets/twitchspawn/lang/es_es.json @@ -5,13 +5,13 @@ "modloader.twitchspawn.error.folder": "Open Config Folder", "modloader.twitchspawn.error.reload": "Reload Configs", - "modloader.twitchspawn.error.tsl": "Error de TSL: §4{2}", - "modloader.twitchspawn.error.json": "Error de JSON: §4{2}", - "modloader.twitchspawn.error.toml": "Error de TOML: §4{2}", - "modloader.twitchspawn.error.unknown": "Error Desconocido: §4{2} ({3})", + "modloader.twitchspawn.error.tsl": "Error de TSL: §4%s", + "modloader.twitchspawn.error.json": "Error de JSON: §4%s", + "modloader.twitchspawn.error.toml": "Error de TOML: §4%s", + "modloader.twitchspawn.error.unknown": "Error Desconocido: §4%s (%s)", "commands.twitchspawn.reloadcfg.success": "§3>> ¡Se han recargado exitosamente todas las configuraciones!", - "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Recarga Fallida. Errores de Sintaxis:\n{0}", + "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Recarga Fallida. Errores de Sintaxis:\n%s", "commands.twitchspawn.reloadcfg.already_started": "§4>> TwitchSpawn debe ser detenido para poder recargar las configuraciones.", "commands.twitchspawn.reloadcfg.no_perm": "§4>> No tienes permiso para recargar las configuraciones de TwitchSpawn.", @@ -22,22 +22,22 @@ "commands.twitchspawn.start.illegal_state": "§4>> TwitchSpawn ya se esta ejecutando.", "commands.twitchspawn.start.no_perm": "§4>> No tienes permiso para iniciar TwitchSpawn.", - "commands.twitchspawn.stop.success": "§6>> TwitchSpawn se ha detenido por {0} (Razon: {1})", + "commands.twitchspawn.stop.success": "§6>> TwitchSpawn se ha detenido por %s (Razon: %2$s)", "commands.twitchspawn.stop.illegal_state": "§4>> TwitchSpawn ya esta apagado.", "commands.twitchspawn.stop.no_perm": "§4>> No tienes permiso para detener TwitchSpawn.", - "commands.twitchspawn.rules.list": "§3>> Lista de Reglas cargadas para: {0}", - "commands.twitchspawn.rules.default": "§3>> La Lista de Reglas por defecto incluye:\n{1}", - "commands.twitchspawn.rules.one": "§3>> Lista de Recarga caragada para {0} e incluye:\n{1}", - "commands.twitchspawn.rules.one.fail": "§4>> Ninguna Lista de Reglas ha sido cargada para {0}", + "commands.twitchspawn.rules.list": "§3>> Lista de Reglas cargadas para: %s", + "commands.twitchspawn.rules.default": "§3>> La Lista de Reglas por defecto incluye:\n%2$s", + "commands.twitchspawn.rules.one": "§3>> Lista de Recarga caragada para %s e incluye:\n%2$s", + "commands.twitchspawn.rules.one.fail": "§4>> Ninguna Lista de Reglas ha sido cargada para %s", "commands.twitchspawn.simulate.missing": "§4>> Falta el nombre del evento en el objeto de simulación. Esperado: \"event\" field.", - "commands.twitchspawn.simulate.invalid_event": "§4>> Nombre de evento invalido -> {0}", - "commands.twitchspawn.simulate.success": "§a>> Simulacion ejecutada {0}", + "commands.twitchspawn.simulate.invalid_event": "§4>> Nombre de evento invalido -> %s", + "commands.twitchspawn.simulate.success": "§a>> Simulacion ejecutada %s", "commands.twitchspawn.simulate.no_perm": "§4>> No tienes permiso para simular un evento.", - "commands.twitchspawn.test.not_found": "§4>> Ninguna Lista de Reglas asociada con {0}", - "commands.twitchspawn.test.success": "§a>> Se han puesto en cola las reglas para {0}", + "commands.twitchspawn.test.not_found": "§4>> Ninguna Lista de Reglas asociada con %s", + "commands.twitchspawn.test.success": "§a>> Se han puesto en cola las reglas para %s", "errors.twitchspawn.loading": "No se puede cargar TwitchSpawn." } diff --git a/common/src/main/resources/assets/twitchspawn/lang/fr_fr.json b/common/src/main/resources/assets/twitchspawn/lang/fr_fr.json index 621a104..1ba4dad 100644 --- a/common/src/main/resources/assets/twitchspawn/lang/fr_fr.json +++ b/common/src/main/resources/assets/twitchspawn/lang/fr_fr.json @@ -4,13 +4,13 @@ "modloader.twitchspawn.error.folder": "Open Config Folder", "modloader.twitchspawn.error.reload": "Reload Configs", - "modloader.twitchspawn.error.tsl": "Erreur TSL: §4{2}", - "modloader.twitchspawn.error.json": "Erreur JSON: §4{2}", - "modloader.twitchspawn.error.toml": "Erreur TOML: §4{2}", - "modloader.twitchspawn.error.unknown": "Erreur inconnue: §4{2} ({3})", + "modloader.twitchspawn.error.tsl": "Erreur TSL: §4%s", + "modloader.twitchspawn.error.json": "Erreur JSON: §4%s", + "modloader.twitchspawn.error.toml": "Erreur TOML: §4%s", + "modloader.twitchspawn.error.unknown": "Erreur inconnue: §4%s (%s)", "commands.twitchspawn.reloadcfg.success": "§3>> Chargement des configurations réussi.", - "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Echec du chargement. Erreur de syntaxe:\n{0}", + "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Echec du chargement. Erreur de syntaxe:\n%s", "commands.twitchspawn.reloadcfg.already_started": "§4>> TwitchSpawn doit être arrêté pour charger les configurations.", "commands.twitchspawn.reloadcfg.no_perm": "§4>> Vous n'avez pas de l'autorisation nécessaire pour charger les configurations de TwitchSpawn.", @@ -21,22 +21,22 @@ "commands.twitchspawn.start.illegal_state": "§4>> TwitchSpawn est déjà en cours d'utilisation.", "commands.twitchspawn.start.no_perm": "§4>> Vous n'avez l'autorisation nécessaire pour démarrer TwitchSpawn.", - "commands.twitchspawn.stop.success": "§6>> TwitchSpawn a été arrêté par {0} (Motif: {1})", + "commands.twitchspawn.stop.success": "§6>> TwitchSpawn a été arrêté par %s (Motif: %2$s)", "commands.twitchspawn.stop.illegal_state": "§4>> TwitchSpawn est déjà arrêté.", "commands.twitchspawn.stop.no_perm": "§4>> Vous n'avez l'autorisation nécessaire pour arrêter TwitchSpawn.", - "commands.twitchspawn.rules.list": "§3>> Rulesets chargé pour: {0}", - "commands.twitchspawn.rules.default": "§3>> Le ruleset par défaut chargé inclut les éléments suivants:\n{1}", - "commands.twitchspawn.rules.one": "§3>> Le ruleset chargé pour {0} inclut les éléments suivants:\n{1}", - "commands.twitchspawn.rules.one.fail": "§4>> Pas de ruleset chargé pour {0}", + "commands.twitchspawn.rules.list": "§3>> Rulesets chargé pour: %s", + "commands.twitchspawn.rules.default": "§3>> Le ruleset par défaut chargé inclut les éléments suivants:\n%2$s", + "commands.twitchspawn.rules.one": "§3>> Le ruleset chargé pour %s inclut les éléments suivants:\n%2$s", + "commands.twitchspawn.rules.one.fail": "§4>> Pas de ruleset chargé pour %s", "commands.twitchspawn.simulate.missing": "§4>> Évènement manquant dans la simulation de l'objet. Syntaxe attendue \"évènement\" champ.", - "commands.twitchspawn.simulate.invalid_event": "§4>> Non d'évènement invalide -> {0}", - "commands.twitchspawn.simulate.success": "§a>> Exécution de la simulation réussie {0}", + "commands.twitchspawn.simulate.invalid_event": "§4>> Non d'évènement invalide -> %s", + "commands.twitchspawn.simulate.success": "§a>> Exécution de la simulation réussie %s", "commands.twitchspawn.simulate.no_perm": "§4>> Vous n'avez pas l'autorisation de simuler un évènement.", - "commands.twitchspawn.test.not_found": "§4>> Aucun ruleset associé à {0}", - "commands.twitchspawn.test.success": "§a>> Ajout des règles à la file d'attente réussi pour {0}", + "commands.twitchspawn.test.not_found": "§4>> Aucun ruleset associé à %s", + "commands.twitchspawn.test.success": "§a>> Ajout des règles à la file d'attente réussi pour %s", "errors.twitchspawn.loading": "Impossible de charger TwitchSpawn" } diff --git a/common/src/main/resources/assets/twitchspawn/lang/it_it.json b/common/src/main/resources/assets/twitchspawn/lang/it_it.json index 7ced012..7d6ff82 100644 --- a/common/src/main/resources/assets/twitchspawn/lang/it_it.json +++ b/common/src/main/resources/assets/twitchspawn/lang/it_it.json @@ -4,13 +4,13 @@ "modloader.twitchspawn.error.folder": "Open Config Folder", "modloader.twitchspawn.error.reload": "Reload Configs", - "modloader.twitchspawn.error.tsl": "TSL Error: §4{2}", - "modloader.twitchspawn.error.json": "JSON Error: §4{2}", - "modloader.twitchspawn.error.toml": "TOML Error: §4{2}", - "modloader.twitchspawn.error.unknown": "Errore Sconosciuto: §4{2} ({3})", + "modloader.twitchspawn.error.tsl": "TSL Error: §4%s", + "modloader.twitchspawn.error.json": "JSON Error: §4%s", + "modloader.twitchspawn.error.toml": "TOML Error: §4%s", + "modloader.twitchspawn.error.unknown": "Errore Sconosciuto: §4%s (%s)", "commands.twitchspawn.reloadcfg.success": "§3>> Configurazioni ricaricate con successo", - "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Ricaricamento fallito. Errori di sintassi:\n{0}", + "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Ricaricamento fallito. Errori di sintassi:\n%s", "commands.twitchspawn.reloadcfg.already_started": "§4>> TwitchSpawn deve essere fermata per essere in grado fi ricaricare le configurazioni.", "commands.twitchspawn.reloadcfg.no_perm": "§4>> Non hai il permesso di ricaricare le configurazioni di TwitchSpawn.", @@ -21,22 +21,22 @@ "commands.twitchspawn.start.illegal_state": "§4>> TwitchSpawn è già in esecuzione.", "commands.twitchspawn.start.no_perm": "§4>> Non hai il permesso di avviare TwitchSpawn.", - "commands.twitchspawn.stop.success": "§6>> TwitchSpawn è stata fermata da {0} (Reason: {1})", + "commands.twitchspawn.stop.success": "§6>> TwitchSpawn è stata fermata da %s (Reason: %2$s)", "commands.twitchspawn.stop.illegal_state": "§4>> TwitchSpawn è già stata fermata.", "commands.twitchspawn.stop.no_perm": "§4>> Non hai il permesso di fermare TwitchSpawn.", - "commands.twitchspawn.rules.list": "§3>> Insieme di regole caricato per: {0}", - "commands.twitchspawn.rules.default": "§3>> L'insieme di regole default loaded include le seguenti regole:\n{1}", - "commands.twitchspawn.rules.one": "§3>> L'insieme di regole per {0} include le seguenti regole:\n{1}", - "commands.twitchspawn.rules.one.fail": "§4>> Nessun insieme di regole è caricato per {0}", + "commands.twitchspawn.rules.list": "§3>> Insieme di regole caricato per: %s", + "commands.twitchspawn.rules.default": "§3>> L'insieme di regole default loaded include le seguenti regole:\n%2$s", + "commands.twitchspawn.rules.one": "§3>> L'insieme di regole per %s include le seguenti regole:\n%2$s", + "commands.twitchspawn.rules.one.fail": "§4>> Nessun insieme di regole è caricato per %s", "commands.twitchspawn.simulate.missing": "§4>> Mancante il nome dell'evvento nella simulazione dell'oggetto. Ci si aspettava un campo \"event\".", - "commands.twitchspawn.simulate.invalid_event": "§4>> Nome dell'evento non valido -> {0}", - "commands.twitchspawn.simulate.success": "§a>> Simulazione terminata con successo {0}", + "commands.twitchspawn.simulate.invalid_event": "§4>> Nome dell'evento non valido -> %s", + "commands.twitchspawn.simulate.success": "§a>> Simulazione terminata con successo %s", "commands.twitchspawn.simulate.no_perm": "§4>> Non hai il permesso di simulare un evento.", - "commands.twitchspawn.test.not_found": "§4>> Nessun insieme di regole associato a {0}", - "commands.twitchspawn.test.success": "§a>> Iserimento della regola avvenuto con successo per {0}", + "commands.twitchspawn.test.not_found": "§4>> Nessun insieme di regole associato a %s", + "commands.twitchspawn.test.success": "§a>> Iserimento della regola avvenuto con successo per %s", "errors.twitchspawn.loading": "Impossibile caricare TwitchSpawn" } diff --git a/common/src/main/resources/assets/twitchspawn/lang/lv_lv.json b/common/src/main/resources/assets/twitchspawn/lang/lv_lv.json index a9a8deb..2378154 100644 --- a/common/src/main/resources/assets/twitchspawn/lang/lv_lv.json +++ b/common/src/main/resources/assets/twitchspawn/lang/lv_lv.json @@ -4,13 +4,13 @@ "modloader.twitchspawn.error.folder": "Atvērt konfigurācijas mapi", "modloader.twitchspawn.error.reload": "Pārlādēd konfigurācijas", - "modloader.twitchspawn.error.tsl": "TSL Kļūda: §4{2}", - "modloader.twitchspawn.error.json": "JSON Kļūda: §4{2}", - "modloader.twitchspawn.error.toml": "TOML Kļūda: §4{2}", - "modloader.twitchspawn.error.unknown": "Nezināma Kļūda: §4{2} ({3})", + "modloader.twitchspawn.error.tsl": "TSL Kļūda: §4%s", + "modloader.twitchspawn.error.json": "JSON Kļūda: §4%s", + "modloader.twitchspawn.error.toml": "TOML Kļūda: §4%s", + "modloader.twitchspawn.error.unknown": "Nezināma Kļūda: §4%s (%s)", "commands.twitchspawn.reloadcfg.success": "§3>> Konfigurācijas faili pārlādēti!", - "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Kļūda pārlādējot. Sintakses kļūda:\n{0}", + "commands.twitchspawn.reloadcfg.invalid_syntax": "§4>> Kļūda pārlādējot. Sintakses kļūda:\n%s", "commands.twitchspawn.reloadcfg.already_started": "§4>> TwitchSpawn nepieciešams apturēt, lai pārlādētu konfigurācijas failus.", "commands.twitchspawn.reloadcfg.no_perm": "§4>> Tev nav atļaujas pārlādēt TwitchSpawn konfigurāciju.", @@ -21,22 +21,22 @@ "commands.twitchspawn.start.illegal_state": "§4>> TwitchSpawn jau darbojas.", "commands.twitchspawn.start.no_perm": "§4>> Jums nav atļaujas startēt TwitchSpawn.", - "commands.twitchspawn.stop.success": "§6>> TwitchSpawn apturēja {0} (iemesls: {1})", + "commands.twitchspawn.stop.success": "§6>> TwitchSpawn apturēja %s (iemesls: %2$s)", "commands.twitchspawn.stop.illegal_state": "§4>> TwitchSpawn jau ir apturēts.", "commands.twitchspawn.stop.no_perm": "§4>> Jums nav atļaujas apturēt TwitchSpawn.", - "commands.twitchspawn.rules.list": "§3>> Noteikumu kopas priekš: {0}", - "commands.twitchspawn.rules.default": "§3>> ielādētā noklusējuma noteikumu kopa ietver:\n {1}", - "commands.twitchspawn.rules.one": "§3>> {0} ielādētā noteikumu kopa ietver:\n {1}", - "commands.twitchspawn.rules.one.fail": "§4>> {0} netika ielādēta noteikumu kopa", + "commands.twitchspawn.rules.list": "§3>> Noteikumu kopas priekš: %s", + "commands.twitchspawn.rules.default": "§3>> ielādētā noklusējuma noteikumu kopa ietver:\n %2$s", + "commands.twitchspawn.rules.one": "§3>> %s ielādētā noteikumu kopa ietver:\n %2$s", + "commands.twitchspawn.rules.one.fail": "§4>> %s netika ielādēta noteikumu kopa", "commands.twitchspawn.simulate.missing": "§4 >> simulācijas objektā trūkst notikuma nosaukuma. Paredzēts notikums lauks.", - "commands.twitchspawn.simulate.invalid_event": "§4 >> Nederīgs notikuma nosaukums - > {0}", - "commands.twitchspawn.simulate.success": "§A >> simulācija sekmīgi izslēgta {0}", + "commands.twitchspawn.simulate.invalid_event": "§4 >> Nederīgs notikuma nosaukums - > %s", + "commands.twitchspawn.simulate.success": "§A >> simulācija sekmīgi izslēgta %s", "commands.twitchspawn.simulate.no_perm": "§4 >> Jums nav atļaujas simulēt notikumu.", - "commands.twitchspawn.test.not_found": "§4 >> ar {0} nav saistīta noteikumu kopa", - "commands.twitchspawn.test.success": "§A >> {0} noteikumus ir sekmīgi ievietotas rindā", + "commands.twitchspawn.test.not_found": "§4 >> ar %s nav saistīta noteikumu kopa", + "commands.twitchspawn.test.success": "§A >> %s noteikumus ir sekmīgi ievietotas rindā", "errors.twitchspawn.loading": "Nevarēja ielādēt TwitchSpawn" } From f832a164d24054fd74ab42eb4010d81fee20b1bf Mon Sep 17 00:00:00 2001 From: BONNe Date: Mon, 25 Dec 2023 03:59:48 +0200 Subject: [PATCH 14/15] Fixes entity name parsing --- .../igoodie/twitchspawn/tslanguage/action/SummonAction.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java index 17f879e..bf38a91 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/SummonAction.java @@ -5,6 +5,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import java.util.List; +import net.minecraft.client.resources.language.I18n; import net.minecraft.nbt.TagParser; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; @@ -82,9 +83,8 @@ protected void performAction(ServerPlayer player, EventArguments args) { @Override protected String subtitleEvaluator(String expression, EventArguments args) { - // XXX: Dunno where that went... Fix that later? -// if (expression.equals("mobName")) -// return entityType.getName().getString(); + if (expression.equals("mobName")) + return I18n.get(entityType.getDescriptionId()); return null; } From 57200c7f5c15bb8e0980047e3309969056363892 Mon Sep 17 00:00:00 2001 From: BONNe Date: Mon, 25 Dec 2023 04:06:11 +0200 Subject: [PATCH 15/15] Change null-pointer check for subtest to a packet sending. --- .../igoodie/twitchspawn/tslanguage/action/TSLAction.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java index 109c354..782e30a 100644 --- a/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java +++ b/common/src/main/java/net/programmer/igoodie/twitchspawn/tslanguage/action/TSLAction.java @@ -231,16 +231,14 @@ protected void notifyPlayer(ServerPlayer player, String title, String subtitle) Component text = MCPHelpers.fromJsonLenient(title); Component subtext = MCPHelpers.fromJsonLenient(subtitle); - if (subtext == null) { - subtext = Component.nullToEmpty(""); // You cannot send NULL pockets. - } else if (subtext.getString().equals("NOTHING_0xDEADC0DE_0xDEADBEEF")) { + if (subtext != null && subtext.getString().equals("NOTHING_0xDEADC0DE_0xDEADBEEF")) { return; // Stop here since it was a DISPLAYING NOTHING statement } if (ConfigManager.PREFERENCES.messageDisplay == PreferencesConfig.MessageDisplay.TITLES) { // Form title and subtitle packets - ClientboundSetTitleTextPacket packet = new ClientboundSetTitleTextPacket(text); - ClientboundSetSubtitleTextPacket subtitlePacket = new ClientboundSetSubtitleTextPacket(subtext); // 20 + ClientboundSetTitleTextPacket packet = new ClientboundSetTitleTextPacket(text != null ? text : Component.empty()); + ClientboundSetSubtitleTextPacket subtitlePacket = new ClientboundSetSubtitleTextPacket(subtext != null ? subtext : Component.empty()); ClientboundSetTitlesAnimationPacket timePacket = new ClientboundSetTitlesAnimationPacket( (int) (ConfigManager.PREFERENCES.notificationDelay * 0.1f / 50), // 10 (int) (ConfigManager.PREFERENCES.notificationDelay * 0.7f / 50), // 70