Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mod download UI integration #761

Merged
merged 51 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
9ece5f7
refactor: run OnServerSelected in thread to allow waiting in it
Alystrasz Oct 23, 2023
b8d3d15
Merge branch 'R2Northstar:main' into feat/auto-dl
Alystrasz Oct 29, 2023
c183d4e
build: add NSIsModDownloadable to native functions
Alystrasz Oct 29, 2023
7bbdbb3
feat: error message tells if mod is not verified
Alystrasz Oct 29, 2023
9595bdf
feat: display a loading dialog while mod is being downloaded
Alystrasz Oct 29, 2023
afd748b
build: add NSDownloadMod to native functions
Alystrasz Oct 29, 2023
a43fbc9
feat: start mod downloading through native call
Alystrasz Oct 29, 2023
764b64e
build: add NSGetModInstallState to native functions
Alystrasz Oct 29, 2023
16e80d7
feat: add ModInstallState struct
Alystrasz Oct 29, 2023
085240e
feat: UpdateModDownloadDialog live-updates dialog with info from nati…
Alystrasz Oct 29, 2023
8115fe9
refactor: export code to dedicated package
Alystrasz Oct 29, 2023
22762dd
refactor: move eModInstallStatus enum to autodl package
Alystrasz Oct 29, 2023
2b910b1
feat: reload mods if some have been downloaded
Alystrasz Oct 29, 2023
c9470d4
feat: close dialog once mod download is over
Alystrasz Oct 30, 2023
584f3cc
feat: display an error message if download did not end well
Alystrasz Oct 30, 2023
40cd2e1
feat: display archive extraction progression
Alystrasz Oct 31, 2023
febb671
feat: display archive download progression
Alystrasz Nov 1, 2023
e63b12e
build: add controls.menu vanilla file
Alystrasz Nov 1, 2023
05e4b17
feat: add setting to allow mod autodownloading
Alystrasz Nov 5, 2023
9d6e95c
feat: customize missing mod message regarding mod autodownloading set…
Alystrasz Nov 5, 2023
8b98e21
Merge branch 'R2Northstar:main' into feat/auto-dl
Alystrasz Nov 12, 2023
a179dfd
fix: move native method signatures to UI part of nativefuncs manifesto
Alystrasz Nov 15, 2023
d16da9a
Merge branch 'main' into feat/auto-dl
Alystrasz Nov 22, 2023
1029b68
feat: localize user messages
Alystrasz Nov 23, 2023
e0d5a17
Revert "feat: add setting to allow mod autodownloading"
Alystrasz Nov 23, 2023
c6a2bc5
Revert "build: add controls.menu vanilla file"
Alystrasz Nov 23, 2023
5d6cfd1
feat: add cl_mod_download convar
Alystrasz Nov 23, 2023
cf2e810
fix: only display specific error when mod-dl is activated
Alystrasz Nov 23, 2023
d010223
fix: add missing ')'
Alystrasz Nov 23, 2023
58912a7
Merge branch 'main' into feat/auto-dl
Alystrasz Dec 1, 2023
61e6360
fix: update dialog text while checksuming mod
Alystrasz Dec 2, 2023
3747db5
Merge branch 'main' into feat/auto-dl
Alystrasz Dec 4, 2023
73ca7a9
Merge branch 'main' into feat/auto-dl
Alystrasz Dec 14, 2023
e2da09a
style: Add missing trailing newline
GeckoEidechse Dec 14, 2023
1f53a59
refactor: rename convar with meaningful name
Alystrasz Dec 14, 2023
be1d934
style: formatting
Alystrasz Dec 14, 2023
4d81495
style: formatting
Alystrasz Dec 14, 2023
8333cd0
style: formatting
Alystrasz Dec 14, 2023
639db2a
style: formatting
Alystrasz Dec 14, 2023
07a70a5
style: formatting
Alystrasz Dec 14, 2023
38602b6
style: formatting
Alystrasz Dec 14, 2023
1717ad8
style: formatting
Alystrasz Dec 14, 2023
71aebc5
style: formatting
Alystrasz Dec 14, 2023
c6faee9
style: formatting
Alystrasz Dec 14, 2023
ea1db4d
style: formatting
Alystrasz Dec 14, 2023
1d75ccc
style: formatting
Alystrasz Dec 14, 2023
1668a04
style: formatting
Alystrasz Dec 14, 2023
04ea7aa
style: move MB declaration to file top
Alystrasz Dec 14, 2023
bf843e7
refactor: remove console dialog script
Alystrasz Dec 14, 2023
dbd570c
refactor: specify global error code localization key
Alystrasz Dec 14, 2023
851d585
style: formatting
Alystrasz Dec 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/nativefuncs.json
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,25 @@
"returnTypeString":"array<string>",
"argTypes":"string modName"
},
{
"name": "NSIsModDownloadable",
"helpText": "checks whether a mod is verified and can be auto-downloaded",
"returnTypeString": "bool",
"argTypes": "string name, string version"

},
{
"name": "NSDownloadMod",
"helpText": "downloads a given mod from distant API to local game profile",
"returnTypeString": "void",
"argTypes": "string name, string version"
},
{
"name": "NSGetModInstallState",
"helpText": "get status of the mod currently being installed",
"returnTypeString": "ModInstallState",
"argTypes": ""
},
{
"name":"NSReloadMods",
"helpText":"",
Expand Down
8 changes: 8 additions & 0 deletions Northstar.Client/mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
"LoadPriority": 0,
"InitScript": "cl_northstar_client_init.nut",
"ConVars": [
{
"Name": "allow_mod_auto_download",
"DefaultValue": "0"
},
{
"Name": "filter_hide_empty",
"DefaultValue": "0"
Expand Down Expand Up @@ -82,6 +86,10 @@
"After": "NSUpdateGameStateClientStart"
}
},
{
"Path": "ui/menu_ns_moddownload.nut",
"RunOn": "UI"
},
{
"Path": "ui/menu_ns_serverbrowser.nut",
"RunOn": "UI",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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."
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,11 @@ global struct MasterServerAuthResult
string errorCode
string errorMessage
}

global struct ModInstallState
{
int status
int progress
int total
float ratio
}
117 changes: 117 additions & 0 deletions Northstar.Client/mod/scripts/vscripts/ui/menu_ns_moddownload.nut
Original file line number Diff line number Diff line change
@@ -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 )
}
59 changes: 49 additions & 10 deletions Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut
Original file line number Diff line number Diff line change
Expand Up @@ -951,33 +951,65 @@ 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
{
Expand Down Expand Up @@ -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()
Expand Down
Loading