aboutsummaryrefslogtreecommitdiff
path: root/Northstar.Client/mod
diff options
context:
space:
mode:
authorRémy Raes <raes.remy@gmail.com>2023-12-14 22:19:08 +0100
committerGitHub <noreply@github.com>2023-12-14 22:19:08 +0100
commite49e7e8321269a3de19f07981c8974e87e9fd938 (patch)
tree5fdfe89944360636f8cbf3450cac642222780697 /Northstar.Client/mod
parent6d678ac56b104a5c4aa2a2d9da05b163f2e1d6cd (diff)
downloadNorthstarMods-e49e7e8321269a3de19f07981c8974e87e9fd938.tar.gz
NorthstarMods-e49e7e8321269a3de19f07981c8974e87e9fd938.zip
Mod download UI integration (#761)v1.21.0-rc2v1.21.0
UI integration for the mod downloading feature. Feature activation locked behind a convar.
Diffstat (limited to 'Northstar.Client/mod')
-rw-r--r--Northstar.Client/mod/resource/northstar_client_localisation_english.txt20
-rw-r--r--Northstar.Client/mod/scripts/vscripts/cl_northstar_client_init.nut8
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_ns_moddownload.nut117
-rw-r--r--Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut59
4 files changed, 194 insertions, 10 deletions
diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt
index c7b25a70..9bb36940 100644
--- a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt
+++ b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt
@@ -366,5 +366,25 @@ Press Yes if you agree to this. This choice can be changed in the mods menu at a
"PROGRESSION_DISABLED_BODY" "^CCCC0000Progression has been disabled.^\n\nTitans, Weapons, Factions, Skins, etc. will all be unlocked and usable at any time.\n\nThis can be changed at any time in the multiplayer lobby."
"PROGRESSION_ANNOUNCEMENT_BODY" "^CCCC0000Progression can now be enabled!^\n\nNorthstar now supports vanilla progression, meaning you can choose to unlock Weapons, Skins, Titans, etc. through levelling up and completing challenges.\n\nYou can enable progression using the button at the bottom of the lobby screen.\n\nThis can be changed at any time."
+
+ // Mod downloading
+ "MISSING_MOD" "Missing mod \"%s1\" v%s2"
+ "MOD_NOT_VERIFIED" "(mod is not verified, and couldn't be downloaded automatically)"
+ "MOD_DL_DISABLED" "(automatic mod downloading is disabled)"
+ "DOWNLOADING_MOD_TITLE" "Downloading mod"
+ "DOWNLOADING_MOD_TITLE_W_PROGRESS" "Downloading mod (%s1%)"
+ "DOWNLOADING_MOD_TEXT" "Downloading %s1 v%s2..."
+ "DOWNLOADING_MOD_TEXT_W_PROGRESS" "Downloading %s1 v%s2...\n(%s3/%s4 MB)"
+ "CHECKSUMING_TITLE" "Checksuming mod"
+ "CHECKSUMING_TEXT" "Verifying contents of %s1 v%s2..."
+ "EXTRACTING_MOD_TITLE" "Extracting mod (%s1%)"
+ "EXTRACTING_MOD_TEXT" "Extracting %s1 v%s2...\n(%s3/%s4 MB)"
+ "FAILED_DOWNLOADING" "Failed downloading mod"
+ "FAILED_READING_ARCHIVE" "An error occurred while reading mod archive."
+ "FAILED_WRITING_TO_DISK" "An error occurred while extracting mod files to the filesystem."
+ "MOD_FETCHING_FAILED" "Mod archive could not be downloaded from Thunderstore."
+ "MOD_CORRUPTED" "Downloaded archive checksum does not match verified signature."
+ "NO_DISK_SPACE_AVAILABLE" "There is not enough space on your disk."
+ "MOD_FETCHING_FAILED_GENERAL" "Mod extraction failed. Check logs for more details."
}
}
diff --git a/Northstar.Client/mod/scripts/vscripts/cl_northstar_client_init.nut b/Northstar.Client/mod/scripts/vscripts/cl_northstar_client_init.nut
index 765d29c3..3560fd56 100644
--- a/Northstar.Client/mod/scripts/vscripts/cl_northstar_client_init.nut
+++ b/Northstar.Client/mod/scripts/vscripts/cl_northstar_client_init.nut
@@ -53,3 +53,11 @@ global struct MasterServerAuthResult
string errorCode
string errorMessage
}
+
+global struct ModInstallState
+{
+ int status
+ int progress
+ int total
+ float ratio
+}
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_moddownload.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_moddownload.nut
new file mode 100644
index 00000000..4d299362
--- /dev/null
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_moddownload.nut
@@ -0,0 +1,117 @@
+global function DownloadMod
+global function DisplayModDownloadErrorDialog
+
+global enum eModInstallStatus
+{
+ DOWNLOADING,
+ CHECKSUMING,
+ EXTRACTING,
+ DONE,
+ FAILED,
+ FAILED_READING_ARCHIVE,
+ FAILED_WRITING_TO_DISK,
+ MOD_FETCHING_FAILED,
+ MOD_CORRUPTED,
+ NO_DISK_SPACE_AVAILABLE,
+ NOT_FOUND
+}
+
+const int MB = 1024*1000;
+
+bool function DownloadMod( RequiredModInfo mod )
+{
+ // Downloading mod UI
+ DialogData dialogData
+ dialogData.header = Localize( "#DOWNLOADING_MOD_TITLE" )
+ dialogData.message = Localize( "#DOWNLOADING_MOD_TEXT", mod.name, mod.version )
+ dialogData.showSpinner = true;
+
+ // Prevent user from closing dialog
+ dialogData.forceChoice = true;
+ OpenDialog( dialogData )
+
+ // Save reference to UI elements, to update their content
+ var menu = GetMenu( "Dialog" )
+ var header = Hud_GetChild( menu, "DialogHeader" )
+ var body = GetSingleElementByClassname( menu, "DialogMessageClass" )
+
+ // Start actual mod downloading
+ NSDownloadMod( mod.name, mod.version )
+
+ ModInstallState state = NSGetModInstallState()
+ while ( state.status < eModInstallStatus.DONE )
+ {
+ state = NSGetModInstallState()
+ UpdateModDownloadDialog( mod, state, menu, header, body )
+ WaitFrame()
+ }
+
+ printt( "Mod status:", state.status )
+
+ // Close loading dialog
+ CloseActiveMenu()
+
+ return state.status == eModInstallStatus.DONE
+}
+
+void function UpdateModDownloadDialog( RequiredModInfo mod, ModInstallState state, var menu, var header, var body )
+{
+ switch ( state.status )
+ {
+ case eModInstallStatus.DOWNLOADING:
+ Hud_SetText( header, Localize( "#DOWNLOADING_MOD_TITLE_W_PROGRESS", string( state.ratio ) ) )
+ Hud_SetText( body, Localize( "#DOWNLOADING_MOD_TEXT_W_PROGRESS", mod.name, mod.version, floor( state.progress / MB ), floor( state.total / MB ) ) )
+ break
+ case eModInstallStatus.CHECKSUMING:
+ Hud_SetText( header, Localize( "#CHECKSUMING_TITLE" ) )
+ Hud_SetText( body, Localize( "#CHECKSUMING_TEXT", mod.name, mod.version ) )
+ break
+ case eModInstallStatus.EXTRACTING:
+ Hud_SetText( header, Localize( "#EXTRACTING_MOD_TITLE", string( state.ratio ) ) )
+ Hud_SetText( body, Localize( "#EXTRACTING_MOD_TEXT", mod.name, mod.version, floor( state.progress / MB ), floor( state.total / MB ) ) )
+ break
+ default:
+ break
+ }
+}
+
+void function DisplayModDownloadErrorDialog( string modName )
+{
+ ModInstallState state = NSGetModInstallState()
+
+ DialogData dialogData
+ dialogData.header = Localize( "#FAILED_DOWNLOADING", modName )
+ dialogData.image = $"ui/menu/common/dialog_error"
+
+ switch ( state.status )
+ {
+ case eModInstallStatus.FAILED_READING_ARCHIVE:
+ dialogData.message = Localize( "#FAILED_READING_ARCHIVE" )
+ break
+ case eModInstallStatus.FAILED_WRITING_TO_DISK:
+ dialogData.message = Localize( "#FAILED_WRITING_TO_DISK" )
+ break
+ case eModInstallStatus.MOD_FETCHING_FAILED:
+ dialogData.message = Localize( "#MOD_FETCHING_FAILED" )
+ break
+ case eModInstallStatus.MOD_CORRUPTED:
+ dialogData.message = Localize( "#MOD_CORRUPTED" )
+ break
+ case eModInstallStatus.NO_DISK_SPACE_AVAILABLE:
+ dialogData.message = Localize( "#NO_DISK_SPACE_AVAILABLE" )
+ break
+ case eModInstallStatus.NOT_FOUND:
+ dialogData.message = Localize( "#NOT_FOUND" )
+ break
+ case eModInstallStatus.FAILED:
+ default:
+ dialogData.message = Localize( "#MOD_FETCHING_FAILED_GENERAL" )
+ break
+ }
+
+ AddDialogButton( dialogData, "#DISMISS" )
+ AddDialogFooter( dialogData, "#A_BUTTON_SELECT" )
+ AddDialogFooter( dialogData, "#B_BUTTON_DISMISS_RUI" )
+
+ OpenDialog( dialogData )
+}
diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut
index efc8d66c..29c7621c 100644
--- a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut
+++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut
@@ -952,32 +952,64 @@ string function FillInServerModsLabel( array<RequiredModInfo> mods )
void function OnServerSelected( var button )
{
+ thread OnServerSelected_Threaded( button )
+}
+
+void function OnServerSelected_Threaded( var button )
+{
if ( NSIsRequestingServerList() || NSGetServerCount() == 0 || file.serverListRequestFailed )
return
ServerInfo server = file.focusedServer
-
file.lastSelectedServer = server
+ // Count mods that have been successfully downloaded
+ bool autoDownloadAllowed = GetConVarBool( "allow_mod_auto_download" )
+ int downloadedMods = 0;
+
foreach ( RequiredModInfo mod in server.requiredMods )
{
if ( !NSGetModNames().contains( mod.name ) )
{
- DialogData dialogData
- dialogData.header = "#ERROR"
- dialogData.message = format( "Missing mod \"%s\" v%s", mod.name, mod.version )
- dialogData.image = $"ui/menu/common/dialog_error"
+ // Check if mod can be auto-downloaded
+ bool modIsVerified = NSIsModDownloadable( mod.name, mod.version )
+
+ // Display an error message if not
+ if ( !modIsVerified || !autoDownloadAllowed )
+ {
+ DialogData dialogData
+ dialogData.header = "#ERROR"
+ dialogData.message = Localize( "#MISSING_MOD", mod.name, mod.version )
+ dialogData.image = $"ui/menu/common/dialog_error"
+
+ // Specify error (only if autoDownloadAllowed is set)
+ if ( autoDownloadAllowed )
+ {
+ dialogData.message += "\n" + Localize( "#MOD_NOT_VERIFIED" )
+ }
- #if PC_PROG
AddDialogButton( dialogData, "#DISMISS" )
AddDialogFooter( dialogData, "#A_BUTTON_SELECT" )
- #endif // PC_PROG
- AddDialogFooter( dialogData, "#B_BUTTON_DISMISS_RUI" )
+ AddDialogFooter( dialogData, "#B_BUTTON_DISMISS_RUI" )
- OpenDialog( dialogData )
+ OpenDialog( dialogData )
+
+ return
+ }
- return
+ else // Launch download
+ {
+ if ( DownloadMod( mod ) )
+ {
+ downloadedMods++
+ }
+ else
+ {
+ DisplayModDownloadErrorDialog( mod.name )
+ return
+ }
+ }
}
else
{
@@ -1018,6 +1050,13 @@ void function OnServerSelected( var button )
}
}
+ // Make Northstar aware new mods have been added
+ if ( downloadedMods > 0 )
+ {
+ print( "Some new mods have been downloaded or enabled, reloading mods." )
+ NSReloadMods();
+ }
+
if ( server.requiresPassword )
{
OnCloseServerBrowserMenu()