Skip to content

Commit 1525254

Browse files
committed
Fix Issues and Add KO Validate
1 parent b9732d3 commit 1525254

File tree

2 files changed

+36
-102
lines changed

2 files changed

+36
-102
lines changed

generator.js

Lines changed: 31 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ function downloadString(data, filename) {
1717
document.body.removeChild(element);
1818
}
1919

20+
ko.validation.init();
21+
2022
class generatorViewModel {
2123
constructor() {
2224
var self = this;
2325
this._availablePortOptions = ko.observableArray(['Custom Port', 'Main Game Port', 'Steam Query Port', 'RCON Port']);
2426
this._compatibility = ko.observable("None");
25-
this.Meta_DisplayName = ko.observable("");
27+
this.Meta_DisplayName = ko.observable("").extend({ required: "Please enter a first name" });
2628
this.Meta_Description = ko.observable("");
2729
this.Meta_Arch = ko.observable("x86_64");
2830
this._Meta_Author = ko.observable("");
@@ -119,14 +121,12 @@ class generatorViewModel {
119121
this.__NewAutoMap = ko.observable(true);
120122
this.__NewConfigType = ko.observable("");
121123

122-
this._UpdateSourceType = ko.observable("4");
123124
this._UpdateSourceURL = ko.observable("");
124125
this._UpdateSourceGitRepo = ko.observable("");
125126
this._UpdateSourceUnzip = ko.observable(false);
126127
this._DisplayImageSource = ko.observable("");
127128

128129
this._SteamServerAppID = ko.observable("");
129-
this._SteamClientAppID = ko.observable("");
130130

131131
this._WinExecutableName = ko.observable("");
132132
this._LinuxExecutableName = ko.observable("");
@@ -151,64 +151,30 @@ class generatorViewModel {
151151
this._Meta_PortsManifest = ko.computed(() => self.__SanitizedName() + "ports.json");
152152
this._Meta_StagesManifest = ko.computed(() => self.__SanitizedName() + "updates.json");
153153
this.Meta_ConfigRoot = ko.computed(() => self.__SanitizedName() + ".kvp");
154-
// this.Meta_DisplayImageSource = ko.computed(() => self._UpdateSourceType() == "4" ? "steam:" + self._SteamClientAppID() : "url:" + self._DisplayImageSource());
154+
this.App_RootDir = ko.computed(() => `./${self.__SanitizedName()}/`);
155155

156-
this.Meta_DisplayImageSource = ko.computed(() => {
156+
this._SteamCheck = ko.computed(() => {
157157
if (self._UpdateStages().length != 0) {
158158
var appIDCheck = "0";
159159
for (let i = 0; i < self._UpdateStages().length; i++) {
160160
if (self._UpdateStages()[i]._UpdateSource() == 8 && appIDCheck == 0) {
161161
appIDCheck = self._UpdateStages()[i].UpdateSourceArgs();
162162
}
163163
}
164-
if (appIDCheck != 0) {
165-
return 'steam:' + appIDCheck;
166-
} else {
167-
return 'url:' + self._DisplayImageSource();
168-
}
169-
} else {
170-
return 'url:' + self._DisplayImageSource();
171-
}
172-
});
173-
174-
this.App_RootDir = ko.computed(() => `./${self.__SanitizedName()}/`);
175-
176-
this.App_BaseDirectory = ko.computed(() => {
177-
if (self._UpdateStages().length != 0) {
178-
var appIDCheck = "0";
179-
for (let i = 0; i < self._UpdateStages().length; i++) {
180-
if (self._UpdateStages()[i]._UpdateSource() == 8 && appIDCheck == 0) {
181-
appIDCheck = self._UpdateStages()[i].UpdateSourceData();
182-
}
183-
}
184-
if (appIDCheck != 0) {
185-
return self.App_RootDir() + appIDCheck + '/';
186-
} else {
187-
return self.App_RootDir() + 'serverfiles/';
188-
}
189-
} else {
190-
return self.App_RootDir() + 'serverfiles/';
191-
}
192-
});
193-
194-
this.App_WorkingDir = ko.computed(() => {
195-
if (self._UpdateStages().length != 0) {
196-
var appIDCheck = "0";
197-
for (let i = 0; i < self._UpdateStages().length; i++) {
198-
if (self._UpdateStages()[i]._UpdateSource() == 8 && appIDCheck == 0) {
199-
appIDCheck = self._UpdateStages()[i].UpdateSourceData();
200-
}
201-
}
202164
if (appIDCheck != 0) {
203165
return appIDCheck;
204166
} else {
205-
return 'serverfiles';
167+
return '0';
206168
}
207169
} else {
208-
return 'serverfiles';
170+
return '0';
209171
}
210172
});
211173

174+
this.Meta_DisplayImageSource = ko.computed(() => self._SteamCheck() == 0 ? 'url:' + self._DisplayImageSource() : 'steam:' + self._SteamCheck());
175+
this.App_BaseDirectory = ko.computed(() => self._SteamCheck() == 0 ? self.App_RootDir() + 'serverfiles/' : self.App_RootDir() + self._SteamCheck() + '/');
176+
this.App_WorkingDir = ko.computed(() => self._SteamCheck() == 0 ? 'serverfiles' : self._SteamCheck());
177+
this._SteamClientAppID = ko.computed(() => self._SteamCheck() != 0 ? self._SteamCheck() : '');
212178
this.App_ExecutableWin = ko.computed(() => self.App_WorkingDir() == "" ? self._WinExecutableName() : `${self.App_WorkingDir()}\\${self._WinExecutableName()}`);
213179
this.App_ExecutableLinux = ko.computed(() => self._compatibility() == "None" ? (self.App_WorkingDir() == "" ? self._LinuxExecutableName() : `${self.App_WorkingDir()}/${self._LinuxExecutableName()}`) : (self._compatibility().substring(self._compatibility().length - 4) == "Xvfb" ? '/usr/bin/xvfb-run' : (self._compatibility() == "Wine" ? '/usr/bin/wine' : '1580130/proton')));
214180
this._App_LinuxCommandLineArgsCompat = ko.computed(() => self._compatibility() == "None" ? '' : (self._compatibility() == "WineXvfb" ? '-a wine \"./' + self._WinExecutableName() + '\"' : (self._compatibility() == "ProtonXvfb" ? '-a \"{{$FullRootDir}}1580130/proton\" run \"./' + self._WinExecutableName() + '\"' : (self._compatibility() == "Proton" ? 'run \"./' + self._WinExecutableName() + '\"' : '\"./' + self._WinExecutableName() + '\"'))));
@@ -260,7 +226,7 @@ class generatorViewModel {
260226
var data = [
261227
{
262228
"key": "Generated Name",
263-
"value": self.__SanitizedName(),
229+
"value": self.__SanitizedName()
264230
},
265231
{
266232
"key": "Config Root",
@@ -386,7 +352,11 @@ class generatorViewModel {
386352
self.__AddEditStage(new updateStageViewModel(self));
387353
$("#addEditStageModal").modal('show');
388354
};
389-
355+
this.Errors = ko.validation.group(self);
356+
this.isValid = ko.computed(function () {
357+
return self.Errors().length == 0;
358+
});
359+
390360
this.__DoAddStage = function () {
391361
self._UpdateStages.push(self.__AddEditStage());
392362
$("#addEditStageModal").modal('hide');
@@ -496,33 +466,17 @@ class generatorViewModel {
496466
lines.push(`${key.replace("_", ".")}=${self[key]()}`);
497467
}
498468

499-
/*
500-
switch (self._UpdateSourceType()) {
501-
case "1": //URL
502-
lines.push(`App.UpdateSources=[{\"UpdateStageName\": \"Server Download\",\"UpdateSourcePlatform\": \"All\", \"UpdateSource\": \"FetchURL\", \"UpdateSourceData\": \"${self._UpdateSourceURL()}\", \"UnzipUpdateSource\": ${self._UpdateSourceUnzip()}}]`);
503-
break;
504-
case "4": //Steam
505-
if (self._compatibility() == "Proton") {
506-
lines.push(`App.UpdateSources=[{\"UpdateStageName\": \"SteamCMD Download\",\"UpdateSourcePlatform\": \"All\", \"UpdateSource\": \"SteamCMD\", \"UpdateSourceData\": \"${self._SteamServerAppID()}\"},{\"UpdateStageName\": \"Proton Compatibility Layer\",\"UpdateSourcePlatform\": \"Linux\", \"UpdateSource\": \"SteamCMD\", \"UpdateSourceData\": \"1580130\"}]`);
507-
} else {
508-
lines.push(`App.UpdateSources=[{\"UpdateStageName\": \"SteamCMD Download\",\"UpdateSourcePlatform\": \"All\", \"UpdateSource\": \"SteamCMD\", \"UpdateSourceData\": \"${self._SteamServerAppID()}\"}]`);
509-
}
510-
break;
511-
case "16": //Github
512-
lines.push(`App.UpdateSources=[{\"UpdateStageName\": \"GitHub Release Download\",\"UpdateSourcePlatform\": \"All\", \"UpdateSource\": \"GithubRelease\", \"UpdateSourceData\": \"${self._UpdateSourceGitRepo()}\"}]`);
513-
break;
514-
}
515-
*/
516-
if (self._UpdateSourceType() == "4") //SteamCMD
517-
{
518-
if (self._compatibility() == "Proton" || self._compatibility() == "ProtonXvfb") {
519-
lines.push(`App.EnvironmentVariables={\"LD_LIBRARY_PATH\": \"./linux64:%LD_LIBRARY_PATH%\", \"SteamAppId\": \"${self._SteamClientAppID()}\", \"STEAM_COMPAT_DATA_PATH\": \"{{$FullRootDir}}1580130\", \"STEAM_COMPAT_CLIENT_INSTALL_PATH\": \"{{$FullRootDir}}1580130\"}`);
520-
} else {
521-
lines.push(`App.EnvironmentVariables={\"LD_LIBRARY_PATH\": \"./linux64:%LD_LIBRARY_PATH%\", \"SteamAppId\": \"${self._SteamClientAppID()}\"}`);
522-
}
469+
if ((self._compatibility() == "Proton" || self._compatibility() == "ProtonXvfb") && self._SteamCheck() != 0) {
470+
lines.push(`App.EnvironmentVariables={\"LD_LIBRARY_PATH\": \"{{$FullBaseDir}}linux64:{{$FullRootDir}}linux64:%LD_LIBRARY_PATH%\", \"SteamAppId\": \"${self._SteamClientAppID()}\", \"STEAM_COMPAT_DATA_PATH\": \"{{$FullRootDir}}1580130\", \"STEAM_COMPAT_CLIENT_INSTALL_PATH\": \"{{$FullRootDir}}1580130\"}`);
471+
} else if ((self._compatibility() == "Proton" || self._compatibility() == "ProtonXvfb") && self._SteamCheck() == 0) {
472+
lines.push(`App.EnvironmentVariables={\"LD_LIBRARY_PATH\": \"{{$FullBaseDir}}linux64:{{$FullRootDir}}linux64:%LD_LIBRARY_PATH%\"}`);
473+
} else if ((self._compatibility() == "Wine" || self._compatibility() == "WineXvfb") && self._SteamCheck() != 0) {
474+
lines.push(`App.EnvironmentVariables={\"LD_LIBRARY_PATH\": \"{{$FullBaseDir}}linux64:{{$FullRootDir}}linux64:%LD_LIBRARY_PATH%\", \"SteamAppId\": \"${self._SteamClientAppID()}\", \"WINEPREFIX\": \"{{$FullRootDir}}.wine\", \"WINEARCH\": \"win64\", \"WINEDEBUG\": \"-all\"}`);
475+
} else {
476+
lines.push(`App.EnvironmentVariables={\"LD_LIBRARY_PATH\": \"{{$FullBaseDir}}linux64:{{$FullRootDir}}linux64:%LD_LIBRARY_PATH%\", \"WINEPREFIX\": \"{{$FullRootDir}}.wine\", \"WINEARCH\": \"win64\", \"WINEDEBUG\": \"-all\"}`);
523477
}
524478

525-
var output = lines.sort().join("\n");
479+
var output = lines.join("\n");
526480
var asJSAppSettings = ko.toJS(self._AppSettings());
527481
var asJSUpdateStages = ko.toJS(self._UpdateStages());
528482
var asJSPortMappings = ko.toJS(self._PortMappings());
@@ -579,6 +533,10 @@ class generatorViewModel {
579533

580534
this.__ValidateConfig = function () {
581535
autoSave();
536+
if (!self.isValid()) {
537+
self.Errors.showAllMessages();
538+
return;
539+
}
582540
self.__ValidationResults.removeAll();
583541

584542
var failure = (issue, recommendation) => self.__ValidationResults.push(new validationResult("Failure", issue, recommendation));
@@ -627,32 +585,7 @@ class generatorViewModel {
627585
}
628586
*/ break;
629587
}
630-
/*
631-
switch (self._UpdateSourceType()) {
632-
case "1": //Fetch from URL
633-
if (self._UpdateSourceURL() == "") {
634-
failure("Update method is Fetch from URL, but no download URL was specified.", "Specify the 'Update source URL' under Update Sources.");
635-
}
636-
else if (self._UpdateSourceURL().toLowerCase().endsWith(".zip") && !self._UpdateSourceUnzip()) {
637-
info("Download URL is a zip file, but 'Unzip once downloaded' is not turned on.", "Turn on 'Unzip once downloaded' under 'Update Sources'", "Without this setting turned on, the archive will not be extracted. If this was intentional, you can ignore this message.");
638-
}
639-
break;
640-
case "4": //SteamCMD
641-
if (self._SteamServerAppID() == "") {
642-
failure("Update method is SteamCMD, but no server App ID is set.", "Specify the 'Server Steam App ID' under Update Sources.");
643-
}
644-
if (self._SteamClientAppID() == "") {
645-
warning("Update method is SteamCMD, but no client App ID is set.", "Specify the 'Server Client App ID' under Update Sources.", "The client app ID is used to source the background image for the resulting instance.");
646-
}
647-
break;
648-
}
649-
*/
650-
/*
651-
if (self.Console_AppReadyRegex() != "" && !self.Console_AppReadyRegex().match(/\^.+\$/)) { failure("Server ready expression does not match the entire line. Regular expressions for AMP must match the entire line, starting with a ^ and ending with a $.", "Update the Server Ready expression under Server Events to match the entire line."); }
652-
if (self.Console_UserJoinRegex() != "" && !self.Console_UserJoinRegex().match(/\^.+\$/)) { failure("User connected expression does not match the entire line. Regular expressions for AMP must match the entire line, starting with a ^ and ending with a $.", "Update the User connected expression under Server Events to match the entire line."); }
653-
if (self.Console_UserLeaveRegex() != "" && !self.Console_UserLeaveRegex().match(/\^.+\$/)) { failure("User disconnected expression does not match the entire line. Regular expressions for AMP must match the entire line, starting with a ^ and ending with a $.", "Update the User disconnected expression under Server Events to match the entire line."); }
654-
if (self.Console_UserChatRegex() != "" && !self.Console_UserChatRegex().match(/\^.+\$/)) { failure("User chat expression does not match the entire line. Regular expressions for AMP must match the entire line, starting with a ^ and ending with a $.", "Update the User chat expression under Server Events to match the entire line."); }
655-
*/
588+
656589
if ((self._compatibility() == "Wine" && !self._SupportsLinux()) || (self._compatibility() == "Proton" && !self._SupportsLinux())) { failure("A Linux compatibility layer was chosen, but Linux support is not checked.", "Please check both."); }
657590

658591
//Validation Summary

index.html

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap-night.min.css" rel="stylesheet" media="(prefers-color-scheme: dark)">
2020
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" media="(prefers-color-scheme: light)">
2121
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.0/knockout-min.js"></script>
22+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.4/knockout.validation.min.js"></script>
2223
<script type="text/javascript" src="FileSaver.min.js"></script>
2324
<script type="text/javascript" src="jszip.min.js"></script>
2425
<link href="style.css" rel="stylesheet">
@@ -627,11 +628,11 @@ <h5 id="configurationFiles">Configuration Files</h5>
627628
<h4 id="startupShutdown">Startup and Shutdown</h4>
628629
<h5>Application and Parameters</h5>
629630
<div class="row mb-3">
630-
<div class="mb-3 col-6" data-bind="visible: _SupportsWindows">
631+
<div class="mb-3 col-6" data-bind="visible: _SupportsWindows()">
631632
<label for="applicationWinExeField">Windows Executable</label>
632633
<input type="text" class="form-control" id="applicationWinExeField" data-bind="value: _WinExecutableName, valueUpdate: 'input'" placeholder="Application.exe">
633634
</div>
634-
<div class="mb-3 col-6" data-bind="visible: _SupportsLinux">
635+
<div class="mb-3 col-6" data-bind="visible: _SupportsLinux() && _compatibility() != 'Wine' && _compatibility() != 'WineXvfb' && _compatibility() != 'Proton' && _compatibility() != 'ProtonXvfb'">
635636
<label for="applicationLinExeField">Linux Executable</label>
636637
<input type="text" class="form-control" id="applicationLinExeField" data-bind="value: _LinuxExecutableName, valueUpdate: 'input'" placeholder="Application.x86_64">
637638
</div>
@@ -662,7 +663,7 @@ <h5>Application and Parameters</h5>
662663
</div>
663664
<div class="row">
664665
<div class="mb-3 col-6">
665-
<label for="applicationArgumentsFormatField">Command line paramter format</label>
666+
<label for="applicationArgumentsFormatField">Command line parameter format</label>
666667
<div class="form-text">
667668
The format to be used to add settings specified above to the command line in place of {{$FormattedArgs}}. {0} is the field name and {1} the value.
668669
</div>
@@ -1265,7 +1266,7 @@ <h5 class="modal-title">Source Type Details</h5>
12651266
This will show as the notification while updating.
12661267
</small>
12671268
</label>
1268-
<input type="text" class="form-control" id="stageNameField" data-bind="value: UpdateStageName" placeholder="Config File Download" required>
1269+
<input type="text" class="form-control" id="stageNameField" data-bind="value: UpdateStageName, validationElement: UpdateStageName" placeholder="Config File Download" required>
12691270
</div>
12701271
</div>
12711272
<div class="row">

0 commit comments

Comments
 (0)