nosingleplayer 1.1.3: fix connexion + bouton Quitter SurviePote
- TitleScreenMixin : TransferState null sur startConnecting -> connexion normale, corrige "This server does not accept transfers". - PauseScreenMixin (nouveau) : renomme le bouton de deconnexion du menu Echap en "Quitter SurviePote" et redirige vers l'ecran d'accueil (TitleScreen) au lieu de la liste des serveurs. - build.gradle : tache runClient (dev sans loom) reutilisant ~/.surviepote/common. - Jar 1.1.3 copie dans l'atlas + distribution.json regenere.
This commit is contained in:
@@ -407,13 +407,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "fr.surviepote:nosingleplayer:1.1.2@jar",
|
"id": "fr.surviepote:nosingleplayer:1.1.3@jar",
|
||||||
"name": "NoSingleplayer (SurviePote)",
|
"name": "NoSingleplayer (SurviePote)",
|
||||||
"type": "FabricMod",
|
"type": "FabricMod",
|
||||||
"artifact": {
|
"artifact": {
|
||||||
"size": 2292471,
|
"size": 2294172,
|
||||||
"url": "https://git.kisakay.com/k/mc/raw/branch/main/atlas/root/servers/SurviePote-26.3/fabricmods/required/nosingleplayer-1.1.2.jar",
|
"url": "https://git.kisakay.com/k/mc/raw/branch/main/atlas/root/servers/SurviePote-26.3/fabricmods/required/nosingleplayer-1.1.3.jar",
|
||||||
"MD5": "2ba50ec99adb670cdb34fe41b0e3d7dd"
|
"MD5": "577674ec296cbc75ac9da009b8d6532e"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
BIN
Binary file not shown.
@@ -1,6 +1,11 @@
|
|||||||
# nosingleplayer (mod maison SurviePote)
|
# nosingleplayer (mod maison SurviePote)
|
||||||
|
|
||||||
Désactive le bouton **Solo** du menu principal (Mixin sur `TitleScreen.init`).
|
Désactive le bouton **Solo** du menu principal (Mixin sur `TitleScreen.init`) et adapte l'UI
|
||||||
|
au serveur unique :
|
||||||
|
- Menu titre : bouton **Rejoindre SurviePote** (connexion directe à `mcpv.ihorizon.org:25565`,
|
||||||
|
sans transfert) ; Solo, Multi, Realms, réseau social et icônes bas retirés.
|
||||||
|
- Menu Échap : le bouton de déconnexion devient **Quitter SurviePote** et renvoie à l'écran
|
||||||
|
d'accueil du jeu (et non la liste des serveurs).
|
||||||
- MC 26.3, Fabric Loader 0.20.0, Java 25, `environment: client`.
|
- MC 26.3, Fabric Loader 0.20.0, Java 25, `environment: client`.
|
||||||
- Particularité 26.x : Mojang ne publie plus de mappings (ni Yarn ni `client_mappings`) et le
|
- Particularité 26.x : Mojang ne publie plus de mappings (ni Yarn ni `client_mappings`) et le
|
||||||
jeu n'est plus obfusqué → **pas de Loom**, compilation directe contre le jar client Mojang
|
jeu n'est plus obfusqué → **pas de Loom**, compilation directe contre le jar client Mojang
|
||||||
@@ -8,4 +13,4 @@ Désactive le bouton **Solo** du menu principal (Mixin sur `TitleScreen.init`).
|
|||||||
pas de refmap nécessaire.
|
pas de refmap nécessaire.
|
||||||
|
|
||||||
Build : `cd mods/nosingleplayer && ./gradlew build` (dans nix-shell racine pour Java 25).
|
Build : `cd mods/nosingleplayer && ./gradlew build` (dans nix-shell racine pour Java 25).
|
||||||
Jar : `build/libs/nosingleplayer-1.0.0.jar` → copié dans `atlas/.../fabricmods/required/`.
|
Jar : `build/libs/nosingleplayer-1.1.3.jar` → copié dans `atlas/.../fabricmods/required/`.
|
||||||
|
|||||||
@@ -64,3 +64,97 @@ processResources {
|
|||||||
java {
|
java {
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Dev : lance le vrai client MC 26.3 + nosingleplayer (build sans loom).
|
||||||
|
// Réutilise l'installation commune du launcher SurviePote (~/.surviepote/common :
|
||||||
|
// versions, libraries, assets — remplie au premier lancement). Le mod est copié
|
||||||
|
// dans runClient/game/mods/ (Knot le découvre comme un mod Fabric classique).
|
||||||
|
// Usage : ./gradlew runClient
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
def survieCommon = new File(System.getProperty('user.home'), '.surviepote/common')
|
||||||
|
def mcVersion = project.minecraft_version
|
||||||
|
def loaderVersion = project.loader_version
|
||||||
|
|
||||||
|
tasks.register('extractClientNatives', Copy) {
|
||||||
|
def versionJson = new groovy.json.JsonSlurper().parse(
|
||||||
|
new File(survieCommon, "versions/${mcVersion}/${mcVersion}.json"))
|
||||||
|
from(versionJson.libraries.findAll { lib ->
|
||||||
|
lib.name.contains(':natives-linux') && (lib.rules == null || lib.rules.any { it.action == 'allow' && (it.os == null || it.os.name == 'linux') })
|
||||||
|
}.collect { lib ->
|
||||||
|
zipTree(new File(survieCommon, "libraries/${lib.downloads.artifact.path}"))
|
||||||
|
})
|
||||||
|
into(layout.buildDirectory.dir('runClient/natives'))
|
||||||
|
include('**/*.so')
|
||||||
|
eachFile { f -> f.path = f.name }
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register('runClient', JavaExec) {
|
||||||
|
dependsOn('extractClientNatives', 'jar')
|
||||||
|
group = 'fabric'
|
||||||
|
description = 'Lance le client Minecraft avec le mod (dev visuel, sans loom).'
|
||||||
|
|
||||||
|
def versionJson = new groovy.json.JsonSlurper().parse(
|
||||||
|
new File(survieCommon, "versions/${mcVersion}/${mcVersion}.json"))
|
||||||
|
def fabricJson = new groovy.json.JsonSlurper().parse(
|
||||||
|
new File(survieCommon, "versions/${mcVersion}-fabric-${loaderVersion}/${mcVersion}-fabric-${loaderVersion}.json"))
|
||||||
|
def mavenToPath = { String coord ->
|
||||||
|
def parts = coord.split(':')
|
||||||
|
return "${parts[0].replace('.', '/')}/${parts[1]}/${parts[2]}/${parts[1]}-${parts[2]}.jar"
|
||||||
|
}
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
def modsDir = layout.buildDirectory.dir('runClient/game/mods').get().asFile
|
||||||
|
delete(modsDir)
|
||||||
|
modsDir.mkdirs()
|
||||||
|
copy {
|
||||||
|
from(tasks.named('jar'))
|
||||||
|
into(modsDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NixOS : dlopen ne voit ni libGL ni libvulkan sans LD_LIBRARY_PATH (cf launcher).
|
||||||
|
def nixStore = new File('/nix/store')
|
||||||
|
def glDirs = []
|
||||||
|
['/run/opengl-driver/lib', '/run/current-system/sw/lib'].each { d ->
|
||||||
|
if (new File(d).exists()) glDirs << d
|
||||||
|
}
|
||||||
|
if (nixStore.exists()) {
|
||||||
|
nixStore.eachDir { e ->
|
||||||
|
def n = e.name
|
||||||
|
if (n.contains('libglvnd') || n.contains('vulkan-loader') || n.contains('alsa-lib')
|
||||||
|
|| n.contains('pulseaudio') || (n.contains('pipewire') && !n.contains('python'))) {
|
||||||
|
def lib = new File(e, 'lib')
|
||||||
|
if (lib.exists()) glDirs << lib.absolutePath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def prevLd = System.getenv('LD_LIBRARY_PATH')
|
||||||
|
environment('LD_LIBRARY_PATH', (prevLd ? prevLd + ':' : '') + glDirs.join(':'))
|
||||||
|
if (!System.getenv('SDL_VIDEODRIVER') && (System.getenv('WAYLAND_DISPLAY') || new File('/run/user/1000/wayland-1').exists())) {
|
||||||
|
environment('SDL_VIDEODRIVER', 'wayland')
|
||||||
|
}
|
||||||
|
|
||||||
|
javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(25) }
|
||||||
|
classpath = files(
|
||||||
|
new File(survieCommon, "versions/${mcVersion}/${mcVersion}.jar"),
|
||||||
|
versionJson.libraries.findAll { lib ->
|
||||||
|
!(lib.name.contains(':natives-')) && (lib.rules == null || lib.rules.any { it.action == 'allow' && (it.os == null || it.os.name == 'linux') })
|
||||||
|
}.collect { new File(survieCommon, "libraries/${it.downloads.artifact.path}") },
|
||||||
|
fabricJson.libraries.collect { new File(survieCommon, "libraries/${mavenToPath(it.name)}") }
|
||||||
|
)
|
||||||
|
mainClass = 'net.fabricmc.loader.impl.launch.knot.KnotClient'
|
||||||
|
args = [
|
||||||
|
'--gameDir', layout.buildDirectory.dir('runClient/game').get().asFile.absolutePath,
|
||||||
|
'--assetsDir', new File(survieCommon, 'assets').absolutePath,
|
||||||
|
'--assetIndex', versionJson.assetIndex.id,
|
||||||
|
'--version', "${project.archives_base_name}-dev",
|
||||||
|
'--username', 'Dev', '--uuid', '00000000-0000-0000-0000-000000000000',
|
||||||
|
'--accessToken', '0', '--versionType', 'release'
|
||||||
|
]
|
||||||
|
jvmArgs = [
|
||||||
|
"-Djava.library.path=${layout.buildDirectory.dir('runClient/natives').get().asFile.absolutePath}",
|
||||||
|
'-Xmx4G'
|
||||||
|
]
|
||||||
|
systemProperties['org.lwjgl.util.Debug'] = 'false'
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ loader_version=0.20.0
|
|||||||
loom_version=1.19.1
|
loom_version=1.19.1
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=1.1.2
|
mod_version=1.1.3
|
||||||
maven_group=fr.surviepote
|
maven_group=fr.surviepote
|
||||||
archives_base_name=nosingleplayer
|
archives_base_name=nosingleplayer
|
||||||
|
|
||||||
|
|||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
package fr.surviepote.nosingleplayer.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.components.Button;
|
||||||
|
import net.minecraft.client.gui.screens.PauseScreen;
|
||||||
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.network.chat.CommonComponents;
|
||||||
|
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.Redirect;
|
||||||
|
|
||||||
|
@Mixin(PauseScreen.class)
|
||||||
|
public abstract class PauseScreenMixin {
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static final Component SURVIEPOTE_QUIT = Component.literal("Quitter SurviePote");
|
||||||
|
|
||||||
|
// Quitte le monde comme le bouton vanilla, mais renvoie vers l'écran d'accueil
|
||||||
|
// (au lieu de la liste des serveurs pour un serveur distant).
|
||||||
|
@Unique
|
||||||
|
private static void surviepote$quitToTitle(Button button) {
|
||||||
|
button.active = false;
|
||||||
|
Minecraft minecraft = Minecraft.getInstance();
|
||||||
|
// Conserve la gestion vanilla du brouillon de signalement, puis redirige.
|
||||||
|
minecraft.getReportingContext().draftReportHandled(minecraft, minecraft.gui.screen(), () -> {
|
||||||
|
minecraft.disconnectFromWorld(ClientLevel.DEFAULT_QUIT_MESSAGE);
|
||||||
|
minecraft.setScreenAndShow(new TitleScreen());
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(method = "createPauseMenu",
|
||||||
|
at = @At(value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/client/gui/components/Button;builder(Lnet/minecraft/network/chat/Component;Lnet/minecraft/client/gui/components/Button$OnPress;)Lnet/minecraft/client/gui/components/Button$Builder;"))
|
||||||
|
private static Button.Builder surviepote$relabelDisconnect(Component message, Button.OnPress onPress) {
|
||||||
|
// createPauseMenu ne crée que deux boutons via Button.builder : "Retour au jeu"
|
||||||
|
// et "Déconnexion". On ne remplace que ce dernier.
|
||||||
|
if (message.getString().equals(CommonComponents.GUI_DISCONNECT.getString())) {
|
||||||
|
return Button.builder(SURVIEPOTE_QUIT, PauseScreenMixin::surviepote$quitToTitle);
|
||||||
|
}
|
||||||
|
return Button.builder(message, onPress);
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-4
@@ -2,7 +2,6 @@ package fr.surviepote.nosingleplayer.mixin;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.components.AbstractWidget;
|
import net.minecraft.client.gui.components.AbstractWidget;
|
||||||
import net.minecraft.client.gui.components.Button;
|
import net.minecraft.client.gui.components.Button;
|
||||||
@@ -13,7 +12,6 @@ import net.minecraft.client.gui.components.events.GuiEventListener;
|
|||||||
import net.minecraft.client.gui.screens.ConnectScreen;
|
import net.minecraft.client.gui.screens.ConnectScreen;
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
import net.minecraft.client.multiplayer.ServerData;
|
import net.minecraft.client.multiplayer.ServerData;
|
||||||
import net.minecraft.client.multiplayer.TransferState;
|
|
||||||
import net.minecraft.client.multiplayer.resolver.ServerAddress;
|
import net.minecraft.client.multiplayer.resolver.ServerAddress;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import fr.surviepote.nosingleplayer.NoSingleplayer;
|
import fr.surviepote.nosingleplayer.NoSingleplayer;
|
||||||
@@ -86,8 +84,9 @@ public abstract class TitleScreenMixin {
|
|||||||
|
|
||||||
Button join = Button.builder(Component.literal("Rejoindre SurviePote"), pressed -> {
|
Button join = Button.builder(Component.literal("Rejoindre SurviePote"), pressed -> {
|
||||||
ServerData data = new ServerData("SurviePote", SERVER_HOST, ServerData.Type.OTHER);
|
ServerData data = new ServerData("SurviePote", SERVER_HOST, ServerData.Type.OTHER);
|
||||||
ConnectScreen.startConnecting(self, minecraft, ServerAddress.parseString(SERVER_HOST), data, false,
|
// TransferState null = connexion normale. En passer un déclenche une connexion
|
||||||
new TransferState(Map.of(), Map.of(), false));
|
// de type "transfert", que le serveur refuse ("This server does not accept transfers").
|
||||||
|
ConnectScreen.startConnecting(self, minecraft, ServerAddress.parseString(SERVER_HOST), data, false, null);
|
||||||
}).bounds(joinX, joinY, 200, 20).build();
|
}).bounds(joinX, joinY, 200, 20).build();
|
||||||
((ScreenAccessor) self).surviepote$getRenderables().add(join);
|
((ScreenAccessor) self).surviepote$getRenderables().add(join);
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"TitleScreenRenderMixin",
|
"TitleScreenRenderMixin",
|
||||||
"TitleScreenTextMixin",
|
"TitleScreenTextMixin",
|
||||||
"RealmsNotificationsMixin",
|
"RealmsNotificationsMixin",
|
||||||
|
"PauseScreenMixin",
|
||||||
"ScreenAccessor"
|
"ScreenAccessor"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
|
|||||||
+3
-2
@@ -54,10 +54,11 @@ cp -u "$HOME/.local/share/PrismLauncher/instances/26.3/minecraft/resourcepacks/F
|
|||||||
cp -u "$HOME/.local/share/PrismLauncher/instances/26.3/minecraft/shaderpacks/Revelation-dev.zip" "atlas/root/servers/SurviePote-26.3/files/shaderpacks/" 2>/dev/null || true
|
cp -u "$HOME/.local/share/PrismLauncher/instances/26.3/minecraft/shaderpacks/Revelation-dev.zip" "atlas/root/servers/SurviePote-26.3/files/shaderpacks/" 2>/dev/null || true
|
||||||
|
|
||||||
echo "== mod maison nosingleplayer (build si besoin) =="
|
echo "== mod maison nosingleplayer (build si besoin) =="
|
||||||
if [ ! -f mods/nosingleplayer/build/libs/nosingleplayer-1.1.2.jar ]; then
|
if [ ! -f mods/nosingleplayer/build/libs/nosingleplayer-1.1.3.jar ]; then
|
||||||
(cd mods/nosingleplayer && ./gradlew build 2>&1 | tail -n 2) || echo "BUILD nosingleplayer échoué (réseau/gradle requis)"
|
(cd mods/nosingleplayer && ./gradlew build 2>&1 | tail -n 2) || echo "BUILD nosingleplayer échoué (réseau/gradle requis)"
|
||||||
fi
|
fi
|
||||||
cp -u mods/nosingleplayer/build/libs/nosingleplayer-1.1.2.jar "$ATLAS_MODS/" 2>/dev/null || true
|
cp -u mods/nosingleplayer/build/libs/nosingleplayer-1.1.3.jar "$ATLAS_MODS/" 2>/dev/null || true
|
||||||
|
rm -f "$ATLAS_MODS"/nosingleplayer-1.1.2.jar "$ATLAS_MODS"/nosingleplayer-1.1.1.jar "$ATLAS_MODS"/nosingleplayer-1.1.0.jar "$ATLAS_MODS"/nosingleplayer-1.0.0.jar
|
||||||
# Note : environment=client (menu titre), inutile côté serveur.
|
# Note : environment=client (menu titre), inutile côté serveur.
|
||||||
|
|
||||||
echo "== regen distribution.json =="
|
echo "== regen distribution.json =="
|
||||||
|
|||||||
Reference in New Issue
Block a user