@@ -10,13 +10,19 @@ namespace CurseForge.Minecraft.Serverpack.Launcher
1010{
1111 partial class Program
1212 {
13- private static async Task < int > InteractiveInstallation ( )
13+ private static async Task < int > InteractiveInstallation ( bool ? automaticInstaller , uint ? projectId , string fileId )
1414 {
1515 if ( ! CheckRequiredDependencies ( ) )
1616 {
1717 return - 1 ;
1818 }
1919
20+ if ( automaticInstaller . HasValue && automaticInstaller . Value )
21+ {
22+ Console . WriteLine ( "Automatic modpack server installer activated" ) ;
23+ Console . WriteLine ( "ProjectId: {0}, FileId: {1}" , projectId , fileId ) ;
24+ }
25+
2026 Console . WriteLine ( "Activating interactive mode. Please follow the instructions." ) ;
2127 Console . WriteLine ( "If you want to know other ways to use this, please use the argument --help" ) ;
2228 Console . WriteLine ( ) ;
@@ -51,48 +57,88 @@ private static async Task<int> InteractiveInstallation()
5157
5258 Console . WriteLine ( ) ;
5359
54- AnsiConsole . Write ( new Rule ( "Search modpack to install" ) ) ;
55-
56- var searchType = AnsiConsole . Prompt ( new SelectionPrompt < string > ( )
57- . Title ( "Do you want to search by [orange1 bold]project id[/] or [orange1 bold]project name[/]?" )
58- . AddChoices ( new [ ]
59- {
60- "Project Id" ,
61- "Project Name"
62- } )
63- . HighlightStyle ( new Style ( Color . Orange1 ) ) ) ;
64-
65- Console . WriteLine ( $ "Searching with { searchType } ") ;
66-
6760 GetCfApiInformation ( out var cfApiKey , out var cfPartnerId , out var cfContactEmail , out var errors ) ;
6861
6962 if ( errors . Count > 0 )
7063 {
71- AnsiConsole . WriteLine ( "[bold red]Please resolve the errors before continuing.[/]" ) ;
64+ AnsiConsole . MarkupLine ( "[bold red]Please resolve the errors before continuing.[/]" ) ;
7265 return - 1 ;
7366 }
7467
7568 using ApiClient cfApiClient = new ( cfApiKey , cfPartnerId , cfContactEmail ) ;
7669
77- try
70+ if ( ! projectId . HasValue )
7871 {
79- await cfApiClient . GetGamesAsync ( ) ;
80- }
81- catch
82- {
83- Console . WriteLine ( "Error: Could not contact the CurseForge API, please check your API key" ) ;
84- return - 1 ;
85- }
72+ AnsiConsole . Write ( new Rule ( "Search modpack to install" ) ) ;
8673
87- if ( searchType == "Project Id" )
88- {
89- while ( ! await HandleProjectIdSearch ( cfApiClient ) )
90- { }
74+ var searchType = AnsiConsole . Prompt ( new SelectionPrompt < string > ( )
75+ . Title ( "Do you want to search by [orange1 bold]project id[/] or [orange1 bold]project name[/]?" )
76+ . AddChoices ( new [ ]
77+ {
78+ "Project Id" ,
79+ "Project Name"
80+ } )
81+ . HighlightStyle ( new Style ( Color . Orange1 ) ) ) ;
82+
83+ Console . WriteLine ( $ "Searching with { searchType } ") ;
84+
85+ try
86+ {
87+ await cfApiClient . GetGamesAsync ( ) ;
88+ }
89+ catch
90+ {
91+ Console . WriteLine ( "Error: Could not contact the CurseForge API, please check your API key" ) ;
92+ return - 1 ;
93+ }
94+
95+ if ( searchType == "Project Id" )
96+ {
97+ while ( ! await HandleProjectIdSearch ( cfApiClient ) )
98+ { }
99+ }
100+ else
101+ {
102+ while ( ! await HandleProjectSearch ( cfApiClient ) )
103+ { }
104+ }
91105 }
92106 else
93107 {
94- while ( ! await HandleProjectSearch ( cfApiClient ) )
95- { }
108+ var _selectedMod = await cfApiClient . GetModAsync ( projectId . Value ) ;
109+ if ( _selectedMod ? . Data == null )
110+ {
111+ Console . Write ( $ "Error: Project { projectId } does not exist") ;
112+ return - 1 ;
113+ }
114+
115+ selectedMod = _selectedMod . Data ;
116+
117+ if ( fileId == "latest" )
118+ {
119+ var versions = await cfApiClient . GetModFilesAsync ( selectedMod . Id ) ;
120+ var validVersions = versions . Data . Where ( v => v . FileStatus == APIClient . Models . Files . FileStatus . Approved ) ;
121+
122+ var latestVersion = validVersions . OrderByDescending ( c => c . FileDate ) . First ( ) ;
123+
124+ selectedVersion = latestVersion ;
125+ }
126+ else
127+ {
128+ if ( ! uint . TryParse ( fileId , out var _fileId ) )
129+ {
130+ Console . WriteLine ( "Error: Use either \" latest\" or a file id for the version" ) ;
131+ return - 1 ;
132+ }
133+ var _selectedFile = await cfApiClient . GetModFileAsync ( projectId . Value , _fileId ) ;
134+ if ( _selectedFile ? . Data == null )
135+ {
136+ Console . Write ( $ "Error: File { fileId } does not exist") ;
137+ return - 1 ;
138+ }
139+
140+ selectedVersion = _selectedFile . Data ;
141+ }
96142 }
97143
98144 if ( selectedMod == null )
@@ -101,8 +147,11 @@ private static async Task<int> InteractiveInstallation()
101147 return - 1 ;
102148 }
103149
104- while ( ! await HandleProjectVersionSearch ( cfApiClient , selectedMod ) )
105- { }
150+ if ( selectedVersion == null )
151+ {
152+ while ( ! await HandleProjectVersionSearch ( cfApiClient , selectedMod ) )
153+ { }
154+ }
106155
107156 if ( selectedVersion == null )
108157 {
@@ -116,13 +165,9 @@ private static async Task<int> InteractiveInstallation()
116165 return 1 ;
117166 }
118167
119- var javaArgs = string . Empty ;
120168 var startServer = AnsiConsole . Confirm ( "Do you want to start the server directly?" ) ;
121169
122- if ( startServer )
123- {
124- javaArgs = AnsiConsole . Ask < string > ( "Do you want any [orange1 bold]java arguments[/] for the server?" ) ;
125- }
170+ var javaArgs = AnsiConsole . Ask < string > ( "Do you want any [orange1 bold]java arguments[/] for the server?" , "-Xms4G -Xmx4G" ) ;
126171
127172 await InstallServer ( selectedMod . Id , selectedVersion . Id , serverPath , javaArgs , startServer ) ;
128173
@@ -178,7 +223,7 @@ private static async Task<bool> HandleProjectSearch(ApiClient cfApiClient)
178223
179224 if ( modResults . Pagination . TotalCount > modResults . Pagination . ResultCount )
180225 {
181- int index = modResults . Pagination . Index ;
226+ uint index = modResults . Pagination . Index ;
182227 while ( modsFound . Count < modResults . Pagination . TotalCount )
183228 {
184229 ctx . Status ( $ "Fetching more results ({ modResults . Pagination . PageSize * ( index + 1 ) } / { modResults . Pagination . TotalCount } )") ;
@@ -216,7 +261,7 @@ private static async Task<bool> HandleProjectSearch(ApiClient cfApiClient)
216261 private static async Task < bool > HandleProjectIdSearch ( ApiClient cfApiClient )
217262 {
218263 var projectId = AnsiConsole . Prompt (
219- new TextPrompt < int > (
264+ new TextPrompt < uint > (
220265 "Enter [orange1 bold]Project Id[/] of the modpack"
221266 ) . ValidationErrorMessage ( "Please enter a valid [orange1 bold]Project Id[/] for a modpack from CurseForge" )
222267 . Validate ( l => l > 0 ? ValidationResult . Success ( ) : ValidationResult . Error ( "[orange1 bold]Project Ids[/] cannot be negative" ) )
0 commit comments