added configurable server hotjoin button

This commit is contained in:
LunarAkai 2025-08-30 18:10:56 +02:00
commit b80574858d
6 changed files with 176 additions and 3 deletions

View file

@ -29,7 +29,7 @@ mod_name=YukisStuff
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=GNU GPL 3.0
# The mod version. See https://semver.org/
mod_version=0.1.0
mod_version=0.1.1
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html

View file

@ -3,8 +3,10 @@ package de.lunarakai.yukisstuff;
import com.google.gson.GsonBuilder;
import dev.isxander.yacl3.api.ConfigCategory;
import dev.isxander.yacl3.api.Option;
import dev.isxander.yacl3.api.OptionDescription;
import dev.isxander.yacl3.api.YetAnotherConfigLib;
import dev.isxander.yacl3.api.controller.ColorControllerBuilder;
import dev.isxander.yacl3.api.controller.StringControllerBuilder;
import dev.isxander.yacl3.api.controller.TickBoxControllerBuilder;
import dev.isxander.yacl3.config.v2.api.ConfigClassHandler;
import dev.isxander.yacl3.config.v2.api.SerialEntry;
@ -35,6 +37,18 @@ public class Config {
@SerialEntry
public Color colorRGB = Color.decode("#FFFFFF");
@SerialEntry
public boolean showHotjoinButton = false;
@SerialEntry
public String hotjoinServerText = "";
@SerialEntry
public String hotjoinServerIP = "";
@SerialEntry
public String hotjoinServerPort = "25565";
public void registerYaclGui() {
ModLoadingContext.get().registerExtensionPoint(
IConfigScreenFactory.class,
@ -63,6 +77,53 @@ public class Config {
.build()
)
.build())
.category(ConfigCategory.createBuilder()
.name(Component.literal("Multiplayer"))
.tooltip(Component.literal("Multiplayer Related Config"))
.option(Option.<Boolean>createBuilder()
.name(net.minecraft.network.chat.Component.literal("Show Hotjoin Button"))
.binding(
false, // default
() -> Config.HANDLER.instance().showHotjoinButton, // getter
newValue -> Config.HANDLER.instance().showHotjoinButton = newValue // setter
)
.controller(TickBoxControllerBuilder::create)
.build())
.option(Option.<String>createBuilder()
.name(Component.literal("Hotjoin Server Button"))
.description((OptionDescription.of(Component.literal("The Text Shown on the Hotjoin Button, for example: Join example.net"))))
.binding(
"",
() -> Config.HANDLER.instance().hotjoinServerText,
newValue -> Config.HANDLER.instance().hotjoinServerText = newValue
)
.controller(StringControllerBuilder::create)
.build()
)
.option(Option.<String>createBuilder()
.name(Component.literal("Hotjoin Server IP"))
.description((OptionDescription.of(Component.literal("The Server IP of the server you wish to join via the hotjoin button, for example: 123.4.5.6"))))
.binding(
"",
() -> Config.HANDLER.instance().hotjoinServerIP,
newValue -> Config.HANDLER.instance().hotjoinServerIP = newValue
)
.controller(StringControllerBuilder::create)
.build()
)
.option(Option.<String>createBuilder()
.name(Component.literal("Hotjoin Server Port"))
.description((OptionDescription.of(Component.literal("The Port of the server you wish to join via the hotjoin button, for example: 25565"))))
.binding(
"25565",
() -> Config.HANDLER.instance().hotjoinServerPort,
newValue -> Config.HANDLER.instance().hotjoinServerPort = newValue
)
.controller(StringControllerBuilder::create)
.build()
)
.build()
)
.save(Config.HANDLER::save)
.build().generateScreen(parent));
}

View file

@ -0,0 +1,46 @@
package de.lunarakai.yukisstuff;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.util.List;
import java.util.Set;
public class MixinPlugin implements IMixinConfigPlugin {
@Override
public void onLoad(String mixinPackage) {
}
@Override
public String getRefMapperConfig() {
return "";
}
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
return true;
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
}
@Override
public List<String> getMixins() {
return List.of();
}
@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
}

View file

@ -0,0 +1,53 @@
package de.lunarakai.yukisstuff.mixin;
import de.lunarakai.yukisstuff.Config;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.ConnectScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.TitleScreen;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.multiplayer.resolver.ServerAddress;
import net.minecraft.network.chat.Component;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(TitleScreen.class)
public abstract class MixinCustomTitleScreen extends Screen {
protected MixinCustomTitleScreen(Component title) {
super(title);
}
@Unique
private ServerData selectedEntry;
@Inject(at = @At("TAIL"), method = "init")
private void init(CallbackInfo ci) {
selectedEntry = new ServerData(
Config.HANDLER.instance().hotjoinServerIP,
Config.HANDLER.instance().hotjoinServerIP,
ServerData.Type.OTHER);
}
@Inject(at = @At("HEAD"), method = "createNormalMenuOptions")
private void addCustomButton(int y, int spacingY, CallbackInfoReturnable<Integer> cir) {
if (Config.HANDLER.instance().showHotjoinButton && !Config.HANDLER.instance().hotjoinServerText.isBlank() && !Config.HANDLER.instance().hotjoinServerIP.isBlank()) {
this.addRenderableWidget(Button.builder(Component.literal(Config.HANDLER.instance().hotjoinServerText), button -> {
if (selectedEntry != null) {
ConnectScreen.startConnecting(
this,
Minecraft.getInstance(), new
ServerAddress(Config.HANDLER.instance().hotjoinServerIP, Integer.parseInt(Config.HANDLER.instance().hotjoinServerPort)),
selectedEntry,
false,
null);
}
}).size(80, 20).pos(this.width / 2 - 100 + 205, y + spacingY).build());
}
}
}

View file

@ -0,0 +1,13 @@
{
"required": true,
"minVersion": "0.8",
"package": "de.lunarakai.yukisstuff.mixin",
"compatibilityLevel": "JAVA_21",
"plugin": "de.lunarakai.yukisstuff.MixinPlugin",
"client": [
"MixinCustomTitleScreen"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -35,8 +35,8 @@ authors = "${mod_authors}" #optional
description = '''${mod_description}'''
# The [[mixins]] block allows you to declare your mixin config to FML so that it gets loaded.
#[[mixins]]
#config="${mod_id}.mixins.json"
[[mixins]]
config="${mod_id}.mixins.json"
# The [[accessTransformers]] block allows you to declare where your AT file is.
# If this block is omitted, a fallback attempt will be made to load an AT from META-INF/accesstransformer.cfg