fixed forge window hide, made code more robust in general, support for custom start sounds

This commit is contained in:
2025-06-24 02:51:29 +02:00
parent 04ef9e6774
commit 3762a6d205
10 changed files with 27 additions and 57 deletions

View File

@@ -5,7 +5,7 @@ It is fully configurable in `config/loadsupport.toml`.
## Config 🚀 ## Config 🚀
The config in `config/loadsupport.toml` is pretty self explainatory: The config in `config/loadsupport.toml` is pretty self explainatory:
```toml ```toml
startSound = true loadFinishSound = "minecraft:ui.toast.challenge_complete"
minMemory = 4.0 minMemory = 4.0
errorTitle = "Error: Not enough Java memory!" errorTitle = "Error: Not enough Java memory!"
errorMinMemory = "Please allocate at least {minMemory} GB of Java memory to your Minecraft instance!" errorMinMemory = "Please allocate at least {minMemory} GB of Java memory to your Minecraft instance!"
@@ -15,7 +15,6 @@ memoryInfoLink = "https://github.com/vaporvee/LoadSupport/wiki/How-to-allocate-m
`{minMemory}` and `{currentMemory}` get replaced by their actual values. `{minMemory}` and `{currentMemory}` get replaced by their actual values.
## Planned Features 👀 ## Planned Features 👀
- 🔊 Customizable startup sound
- 🪛 Ingame settings (Modlist support) - 🪛 Ingame settings (Modlist support)
- 🧩 More features letting the player know why Minecraft is not loading - 🧩 More features letting the player know why Minecraft is not loading

View File

@@ -17,14 +17,9 @@ public class CommonClass {
return true; return true;
} }
public static Config config; public static Config config;
public static long window;
private static void InitConfig() { private static void InitConfig() {
AutoConfig.register(Config.class, Toml4jConfigSerializer::new); AutoConfig.register(Config.class, Toml4jConfigSerializer::new);
config = AutoConfig.getConfigHolder(Config.class).getConfig(); config = AutoConfig.getConfigHolder(Config.class).getConfig();
} }
public static void HideWindow() {
GLFW.glfwHideWindow(window);
}
} }

View File

@@ -4,7 +4,7 @@ import me.shedaniel.autoconfig.ConfigData;
@me.shedaniel.autoconfig.annotation.Config(name = Constants.MOD_ID) @me.shedaniel.autoconfig.annotation.Config(name = Constants.MOD_ID)
public class Config implements ConfigData { public class Config implements ConfigData {
public boolean startSound = true; public String loadFinishSound = "minecraft:ui.toast.challenge_complete";
public float minMemory = 4.0f; public float minMemory = 4.0f;
public String errorTitle = "Error: Not enough Java memory!"; public String errorTitle = "Error: Not enough Java memory!";
public String errorMinMemory = "Please allocate at least {minMemory} GB of Java memory to your Minecraft instance!"; public String errorMinMemory = "Please allocate at least {minMemory} GB of Java memory to your Minecraft instance!";

View File

@@ -1,6 +1,7 @@
package com.vaporvee.loadsupport; package com.vaporvee.loadsupport;
import com.vaporvee.loadsupport.modules.StartSound; import com.vaporvee.loadsupport.modules.StartSound;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.AccessibilityOnboardingScreen; import net.minecraft.client.gui.screens.AccessibilityOnboardingScreen;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.TitleScreen; import net.minecraft.client.gui.screens.TitleScreen;

View File

@@ -2,16 +2,26 @@ package com.vaporvee.loadsupport.mixin;
import com.vaporvee.loadsupport.modules.Allocated; import com.vaporvee.loadsupport.modules.Allocated;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; 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.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Minecraft.class) @Mixin(Minecraft.class)
public class MinecraftPauseMixin { public class MinecraftUnloadMixin {
@Inject(method = "run", at = @At("HEAD"), cancellable = true) @Inject(method = "run", at = @At("HEAD"), cancellable = true)
private void onRunHead(CallbackInfo ci) { private void onRunHead(CallbackInfo ci) {
if (!Allocated.enoughMemory) { if (!Allocated.enoughMemory) {
long window = Minecraft.getInstance().getWindow().getWindow();
GLFW.glfwHideWindow(window);
while (Allocated.isWindowOpen()) { while (Allocated.isWindowOpen()) {
try { Thread.sleep(100); } catch (InterruptedException ignored) {} try { Thread.sleep(100); } catch (InterruptedException ignored) {}
} }

View File

@@ -1,35 +0,0 @@
package com.vaporvee.loadsupport.mixin;
import com.mojang.blaze3d.platform.DisplayData;
import com.mojang.blaze3d.platform.ScreenManager;
import com.mojang.blaze3d.platform.Window;
import com.mojang.blaze3d.platform.WindowEventHandler;
import com.vaporvee.loadsupport.CommonClass;
import com.vaporvee.loadsupport.modules.Allocated;
import com.vaporvee.loadsupport.platform.Services;
import org.lwjgl.glfw.GLFW;
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 java.util.Objects;
@Mixin(Window.class)
public class WindowHideMixin {
@Final
@Shadow
private long window;
@Inject(method = "<init>", at = @At("RETURN"))
private void afterInit(WindowEventHandler eventHandler, ScreenManager screenManager, DisplayData displayData, String preferredFullscreenVideoMode, String title, CallbackInfo ci) {
CommonClass.window = window;
if(Objects.equals(Services.PLATFORM.getPlatformName(), "Fabric") && !Allocated.enoughMemory){ // Fabric loads early enough to fire it here
CommonClass.HideWindow(); // Hide main Minecraft Window which gets frozen by mixin
}
}
}

View File

@@ -104,9 +104,6 @@ public class Allocated {
errorWindow.add(buttonPanel, BorderLayout.SOUTH); errorWindow.add(buttonPanel, BorderLayout.SOUTH);
errorWindow.setVisible(true); errorWindow.setVisible(true);
}); });
if(Objects.equals(Services.PLATFORM.getPlatformName(), "NeoForge")){// NeoForge loads too late so we need to fire it here
CommonClass.HideWindow(); // Hide main Minecraft Window which gets frozen by mixin
}
} }
} catch (RuntimeException | ClassNotFoundException | InstantiationException | IllegalAccessException e) { } catch (RuntimeException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
Constants.LOG.error(String.valueOf(e)); Constants.LOG.error(String.valueOf(e));

View File

@@ -1,19 +1,23 @@
package com.vaporvee.loadsupport.modules; package com.vaporvee.loadsupport.modules;
import com.vaporvee.loadsupport.CommonClass; import com.vaporvee.loadsupport.CommonClass;
import com.vaporvee.loadsupport.Constants;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.sounds.SoundEvents; import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
public class StartSound { public class StartSound {
private static boolean startedOnce = false; private static boolean startedOnce = false;
public static void play() { public static void play() {
if (!startedOnce && CommonClass.config.startSound) { if (startedOnce) return;
startedOnce = true; startedOnce = true;
Minecraft.getInstance().getSoundManager().play( ResourceLocation rl = ResourceLocation.tryParse(CommonClass.config.loadFinishSound);
SimpleSoundInstance.forUI(SoundEvents.UI_TOAST_CHALLENGE_COMPLETE, 1.0F) if(rl == null) {
); Constants.LOG.error("Cannot find load sound resource: \"{}\"", CommonClass.config.loadFinishSound);
return;
} }
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvent.createVariableRangeEvent(rl), 1.0F));
} }
} }

View File

@@ -6,8 +6,7 @@
"compatibilityLevel": "JAVA_18", "compatibilityLevel": "JAVA_18",
"mixins": [], "mixins": [],
"client": [ "client": [
"MinecraftPauseMixin", "MinecraftUnloadMixin"
"WindowHideMixin"
], ],
"server": [], "server": [],
"injectors": { "injectors": {

View File

@@ -2,7 +2,7 @@
# Every field you add must be added to buildSrc/src/main/groovy/multiloader-common.gradle expandProps map. # Every field you add must be added to buildSrc/src/main/groovy/multiloader-common.gradle expandProps map.
# Project # Project
version=1.2.0 version=1.2.1
group=com.vaporvee.loadsupport group=com.vaporvee.loadsupport
java_version=21 java_version=21