@@ -21,6 +21,7 @@ import com.lambda.Lambda.mc
2121import com.lambda.event.events.GuiEvent
2222import com.lambda.event.listener.SafeListener.Companion.listen
2323import com.lambda.gui.LambdaScreen
24+ import com.lambda.gui.dsl.ImGuiBuilder
2425import com.lambda.gui.dsl.ImGuiBuilder.popupModal
2526import com.lambda.module.Module
2627import com.lambda.module.tag.ModuleTag
@@ -44,9 +45,12 @@ object AutoUpdater : Module(
4445 private val debug by setting(" Debug" , false , " Enable debug logging" )
4546 private val loaderBranch by setting(" Loader Branch" , Branch .Stable , " Select loader update branch" )
4647 private val clientBranch by setting(" Client Branch" , Branch .Snapshot , " Select client update branch" )
48+ private var loaderPromptHandled by setting(" Loader Prompt Handled" , false ) { false }
4749
50+ @JvmStatic var showFirstLaunchModal = false
4851 @JvmStatic var showInstallModal = false
4952 @JvmStatic var showUninstallModal = false
53+ private var firstLaunchStateInitialized = false
5054
5155 private const val MAVEN_URL = " https://maven.lambda-client.org"
5256 private const val LOADER_RELEASES_META = " $MAVEN_URL /releases/com/lambda/lambda-loader/maven-metadata.xml"
@@ -80,31 +84,50 @@ object AutoUpdater : Module(
8084 }
8185
8286 listen<GuiEvent .NewFrame >(alwaysListen = true ) {
87+ initializeFirstLaunchStateIfNeeded()
88+
89+ if (showFirstLaunchModal) {
90+ if (mc.currentScreen !is LambdaScreen ) return @listen
91+
92+ ImGui .openPopup(" Loader Installation Wizard" )
93+ popupModal(" Loader Installation Wizard" , WINDOW_FLAGS ) {
94+ renderLoaderInstallExplanation()
95+
96+ val buttonWidth = (ImGui .getContentRegionAvailX() - ImGui .getStyle().itemSpacing.x) / 2f
97+
98+ button(" Switch To Loader" , buttonWidth, 0f ) {
99+ completeFirstLaunchPrompt()
100+ showInstallModal = false
101+ showUninstallModal = false
102+ installLoader()
103+ }
104+
105+ sameLine()
106+
107+ button(" Keep Current Jar" , buttonWidth, 0f ) {
108+ completeFirstLaunchPrompt()
109+ }
110+ }
111+ return @listen
112+ }
113+
114+ showFirstLaunchModal = false
115+
83116 if (showInstallModal) {
84- ImGui .openPopup(" Installation Wizard" )
85- popupModal(" Installation Wizard" , WINDOW_FLAGS ) {
86- text(" Enable Auto Updater" )
87- separator()
88- spacing()
89- text(" The auto updater replaces your current version-specific Lambda mod file" )
90- text(" with a lightweight loader that automatically checks for the latest version" )
91- text(" on every launch and loads it for you." )
92- spacing()
93- text(" This means you'll always be running the newest version of Lambda" )
94- text(" without having to manually download and swap out the jar file." )
95- spacing()
96- separator()
97- text(" Note: The game will close after installation to apply the changes." )
98- spacing()
117+ ImGui .openPopup(" Loader Installation Wizard" )
118+ popupModal(" Loader Installation Wizard" , WINDOW_FLAGS ) {
119+ renderLoaderInstallExplanation()
99120
100- button(" Install" , 120f , 0f ) {
121+ val buttonWidth = (ImGui .getContentRegionAvailX() - ImGui .getStyle().itemSpacing.x) / 2f
122+
123+ button(" Switch To Loader" , buttonWidth, 0f ) {
101124 installLoader()
102125 showInstallModal = false
103126 }
104127
105128 sameLine()
106129
107- button(" Cancel" , 120f , 0f ) {
130+ button(" Cancel" , buttonWidth , 0f ) {
108131 disable()
109132 }
110133 }
@@ -366,9 +389,52 @@ object AutoUpdater : Module(
366389 return modContainer.get().origin.paths[0 ].toAbsolutePath()
367390 }
368391
392+ private fun initializeFirstLaunchStateIfNeeded () {
393+ if (firstLaunchStateInitialized) return
394+ firstLaunchStateInitialized = true
395+
396+ val usingLoader = FabricLoader .getInstance().isModLoaded(" lambda-loader" )
397+ if (usingLoader) {
398+ completeFirstLaunchPrompt()
399+ if (! isEnabled) enable()
400+ return
401+ }
402+
403+ showFirstLaunchModal = ! loaderPromptHandled
404+ }
405+
406+ private fun ImGuiBuilder.renderLoaderInstallExplanation () {
407+ text(" Switch to Lambda Loader?" )
408+ separator()
409+ spacing()
410+ text(" Lambda Loader replaces this version-specific Lambda jar" )
411+ text(" with a lightweight bootstrap that keeps Lambda up to date." )
412+ spacing()
413+ text(" Benefits:" )
414+ text(" - Automatic updates on launch" )
415+ text(" - No manual jar replacement" )
416+ spacing()
417+ text(" If you choose to switch, Lambda will install the loader" )
418+ text(" and close the game so changes apply on next start." )
419+ spacing()
420+ separator()
421+ text(" You can change this later from the AutoUpdater module." )
422+ spacing()
423+ }
424+
425+ @JvmStatic
426+ fun dismissFirstLaunchPrompt () {
427+ completeFirstLaunchPrompt()
428+ }
429+
430+ private fun completeFirstLaunchPrompt () {
431+ loaderPromptHandled = true
432+ showFirstLaunchModal = false
433+ }
434+
369435 private data class SnapshotInfo (
370436 val version : String ,
371437 val timestamp : String ,
372438 val buildNumber : String
373439 )
374- }
440+ }
0 commit comments