Mod nosingleplayer 1.1.0: menu custom (join serveur, fond wallpaper, sans logo/copyright)

This commit is contained in:
kisakay
2026-10-18 20:56:36 +02:00
parent bae95baed3
commit e8e99fdb9d
17 changed files with 116 additions and 10 deletions
@@ -0,0 +1,17 @@
package fr.surviepote.nosingleplayer.mixin;
import com.mojang.realmsclient.gui.screens.RealmsNotificationsScreen;
import net.minecraft.client.gui.GuiGraphicsExtractor;
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;
@Mixin(RealmsNotificationsScreen.class)
public class RealmsNotificationsMixin {
@Inject(method = "extractRenderState", at = @At("HEAD"), cancellable = true)
private void surviepote$hideRealmsNotifications(GuiGraphicsExtractor extractor, int mouseX, int mouseY, float partialTick, CallbackInfo ci) {
ci.cancel();
}
}
@@ -1,25 +1,87 @@
package fr.surviepote.nosingleplayer.mixin;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.FriendsButton;
import net.minecraft.client.gui.components.SpriteIconButton;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.components.Renderable;
import net.minecraft.client.gui.screens.ConnectScreen;
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 fr.surviepote.nosingleplayer.NoSingleplayer;
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;
@Mixin(TitleScreen.class)
public class TitleScreenMixin {
public abstract class TitleScreenMixin {
private static final String SERVER_HOST = "mcpv.ihorizon.org:25565";
@Shadow
protected int width;
@Shadow
protected int height;
@Shadow
protected abstract <T extends GuiEventListener & Renderable & NarratableEntry> T addRenderableWidget(T widget);
@Inject(method = "init", at = @At("TAIL"))
private void surviepote$disableSingleplayer(CallbackInfo ci) {
private void surviepote$customizeMenu(CallbackInfo ci) {
TitleScreen self = (TitleScreen) (Object) this;
Minecraft minecraft = Minecraft.getInstance();
String solo = Component.translatable("menu.singleplayer").getString();
String multi = Component.translatable("menu.multiplayer").getString();
String realms = Component.translatable("menu.online").getString();
int joinX = this.width / 2 - 100;
int joinY = this.height / 4 + 72;
boolean foundMulti = false;
List<SpriteIconButton> iconButtons = new ArrayList<>();
for (GuiEventListener child : self.children()) {
if (child instanceof Button button && button.getMessage().getString().equals(solo)) {
button.active = false;
if (child instanceof Button button) {
String msg = button.getMessage().getString();
if (msg.equals(solo)) {
button.active = false;
} else if (msg.equals(multi)) {
joinX = button.getX();
joinY = button.getY();
foundMulti = true;
button.visible = false;
} else if (msg.equals(realms)) {
button.visible = false;
}
} else if (child instanceof FriendsButton) {
((AbstractWidget) child).visible = false;
} else if (child instanceof SpriteIconButton iconButton) {
iconButtons.add(iconButton);
}
}
// Bas-gauche : langue + accessibilité (icônes).
for (SpriteIconButton iconButton : iconButtons) {
iconButton.visible = false;
}
// RealmsNotificationsScreen : rendu annulé via RealmsNotificationsMixin.
Button join = Button.builder(Component.literal("Rejoindre SurviePote"), pressed -> {
ServerData data = new ServerData("SurviePote", SERVER_HOST, ServerData.Type.OTHER);
ConnectScreen.startConnecting(self, minecraft, ServerAddress.parseString(SERVER_HOST), data, false, null);
}).bounds(joinX, joinY, 200, 20).build();
this.addRenderableWidget(join); if (!foundMulti) {
NoSingleplayer.LOGGER.warn("[SurviePote] Bouton Multi introuvable, Join placé par défaut.");
}
}
}
@@ -0,0 +1,26 @@
package fr.surviepote.nosingleplayer.mixin;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.gui.screens.TitleScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(TitleScreen.class)
public class TitleScreenTextMixin {
@Redirect(
method = "extractRenderState",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/gui/GuiGraphicsExtractor;text(Lnet/minecraft/client/gui/Font;Ljava/lang/String;III)V"
)
)
private void surviepote$versionLine(GuiGraphicsExtractor extractor, Font font, String text, int x, int y, int color) {
if (text.contains("Copyright") || text.contains("Mojang")) {
return;
}
extractor.text(font, "26.3 mc", x, y, color);
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

@@ -2,7 +2,7 @@
"required": true,
"package": "fr.surviepote.nosingleplayer.mixin",
"compatibilityLevel": "JAVA_25",
"client": ["TitleScreenMixin"],
"client": ["TitleScreenMixin", "TitleScreenTextMixin", "RealmsNotificationsMixin"],
"injectors": {
"defaultRequire": 1
}