587 lines
33 KiB
Plaintext
587 lines
33 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<base href="<%= basePath %>">
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
|
<meta name="description" content="txAdmin - remotely Manage & Monitor your GTA5 FiveM Server">
|
|
<meta name="author" content="André Tabarra">
|
|
<title>Server Deployer</title>
|
|
<link href="css/simple-line-icons.css?txVer=<%= txAdminVersion %>" rel="stylesheet">
|
|
<link href="css/coreui.min.css?txVer=<%= txAdminVersion %>" rel="stylesheet">
|
|
<link href="css/dark.css?txVer=<%= txAdminVersion %>" rel="stylesheet">
|
|
<link rel="shortcut icon" type="image/png" href="img/favicon_default.png" id="favicon" />
|
|
<link rel="stylesheet" href="css/txAdmin.css?txVer=<%= txAdminVersion %>">
|
|
|
|
<!-- Page CSS -->
|
|
<!-- <link rel="stylesheet" href="css/codemirror.css"> -->
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.61.1/codemirror.min.css"
|
|
integrity="sha512-xIf9AdJauwKIVtrVRZ0i4nHP61Ogx9fSRAkCLecmE2dL/U8ioWpDvFCAy4dcfecN72HHB9+7FfQj3aiO68aaaw=="
|
|
crossorigin="anonymous" referrerpolicy="no-referrer" />
|
|
<link rel="stylesheet" href="css/codemirror_lucario.css?txVer=<%= txAdminVersion %>">
|
|
<style>
|
|
.inline-code{
|
|
color: #321fdb!important;
|
|
}
|
|
body.theme--dark .inline-code {
|
|
color: #00bf8f !important;
|
|
}
|
|
.cm-s-lucario{
|
|
font-size: 1.05rem !important;
|
|
}
|
|
.deployer-stepper > .card-header,
|
|
.deployer-stepper > .card-footer{
|
|
font-size: large;
|
|
}
|
|
|
|
#step3Log {
|
|
white-space: break-spaces;
|
|
word-break: break-all;
|
|
}
|
|
</style>
|
|
|
|
<!-- injected consts -->
|
|
<script><%- jsInjection %></script>
|
|
</head>
|
|
|
|
<body class="c-app flex-row <%= uiTheme %>">
|
|
<div class="container">
|
|
|
|
<!-- Stepper Row -->
|
|
<div class="row justify-content-center">
|
|
<div class="col-12">
|
|
<div class="card fade-in deployer-stepper">
|
|
<% if (step === 'review') { %>
|
|
<style>
|
|
.CodeMirror{
|
|
max-height: 300px;
|
|
}
|
|
</style>
|
|
<div class="card-header font-weight-bold">Step 1: Review Recipe</div>
|
|
<div class="card-body">
|
|
<div class="row mb-1 mt-0 text-center">
|
|
<div class="col-8 mx-auto card d-block border-primary p-2 mb-1">
|
|
Please review the Recipe below and apply any changes you want, <br>
|
|
then press the <strong>Run Recipe</strong> button below.
|
|
|
|
<% if (!recipe.isTrustedSource) { %>
|
|
<br><span class="text-danger font-weight-bold">Warning: Only run Recipes from trusted sources!</span>
|
|
<% } %>
|
|
</div>
|
|
</div>
|
|
<p class="mb-1">
|
|
<strong style="word-wrap: break-word;"><%= recipe.name %></strong>
|
|
<% if (recipe.author !== '') { %>
|
|
by <%= recipe.author %>
|
|
<% } %>
|
|
<% if (recipe.description !== '') { %>
|
|
<br>
|
|
<%= recipe.description %>
|
|
<% } %>
|
|
</p>
|
|
<textarea
|
|
id="codeMirrorTarget"
|
|
style="width: 100%;"
|
|
class="cms-s-lucario"
|
|
name="code"
|
|
>
|
|
<%= recipe.raw %>
|
|
</textarea>
|
|
<div class="row justify-content-center m-2">
|
|
<button class="btn btn-outline-danger" type="button"
|
|
onclick="cancelAction()">Cancel and Return to Setup</button>
|
|
|
|
<button class="btn btn-info" type="button"
|
|
onclick="step1Action();" autofocus>Next</button>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer text-muted">Step 2: Input Parameters</div>
|
|
<div class="card-footer text-muted">Step 3: Run Recipe</div>
|
|
<div class="card-footer text-muted">Step 4: Configure server.cfg</div>
|
|
|
|
<% } else if (step === 'input') { %>
|
|
<div class="card-header">Step 1: Review Recipe ✔️</div>
|
|
<div class="card-header font-weight-bold ">Step 2: Input Parameters</div>
|
|
<div class="card-body">
|
|
<% if (defaults.autofilled) { %>
|
|
<div class="row mb-3 mt-0 text-center">
|
|
<div class="col-8 mx-auto card d-block border-warning p-2 mb-1">
|
|
<strong>Note:</strong> The following configs were auto-filled by <strong><%= hostConfigSource %></strong>. <br>
|
|
You <i>may</i> edit those, but it's strongly disencouraged.
|
|
</div>
|
|
</div>
|
|
<% } %>
|
|
<form id="step2-form" style="max-width: 732px; margin-left: auto; margin-right: auto;">
|
|
<div class="form-group row">
|
|
<label for="step2-svLicense" class="col-md-3 col-form-label">
|
|
Server Registration Key
|
|
<span class="text-danger">*</span>
|
|
</label>
|
|
<div class="col-md-9">
|
|
<input type="text" class="form-control blur-input" id="step2-svLicense" maxlength="86"
|
|
autocomplete="off" placeholder="cfxk_xxxxxxxxxxxxxxxxxxxx_xxxxx"
|
|
value="<%= defaults.license %>" required autofocus>
|
|
<span class="form-text text-muted">
|
|
Formely known as <strong>License Key</strong>, it can be obtained in the <a href="https://portal.cfx.re/servers/registration-keys" target="_blank" rel="noopener noreferrer">Cfx.re Portal</a>. <br>
|
|
For more info, check the guide: <a href="https://support.cfx.re/hc/en-us/articles/16539369935900-How-to-create-a-registration-key" target="_blank" rel="noopener noreferrer">How to create a registration key</a>.
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<% if (requireDBConfig) { %>
|
|
<div class="row justify-content-center m-2">
|
|
<a class="btn btn-small btn-outline-secondary" data-toggle="collapse" href="#collapseDbOptions" aria-expanded="true" aria-controls="collapseDbOptions">
|
|
Show/Hide Database options (advanced)
|
|
</a>
|
|
</div>
|
|
<div class="collapse" id="collapseDbOptions">
|
|
<div class="form-group row">
|
|
<label for="step2-dbHost" class="col-md-3 col-form-label">
|
|
Database Host
|
|
<span class="text-danger">*</span>
|
|
</label>
|
|
<div class="col-md-9">
|
|
<input type="text" class="form-control" id="step2-dbHost"
|
|
placeholder="<%= defaults.mysqlHost %>" value="<%= defaults.mysqlHost %>" required>
|
|
<span class="form-text text-muted">
|
|
The IP/Hostname for the database server (usually <code><%= defaults.mysqlHost %></code>).
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<label for="step2-dbPort" class="col-md-3 col-form-label">
|
|
Database Port
|
|
<span class="text-danger">*</span>
|
|
</label>
|
|
<div class="col-md-9">
|
|
<input type="number" class="form-control" id="step2-dbPort"
|
|
placeholder="<%= defaults.mysqlPort %>" value="<%= defaults.mysqlPort %>" required>
|
|
<span class="form-text text-muted">
|
|
The port for the database server (usually <code><%= defaults.mysqlPort %></code>).
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<label for="step2-dbUsername" class="col-md-3 col-form-label">
|
|
Database Username
|
|
<span class="text-danger">*</span>
|
|
</label>
|
|
<div class="col-md-9">
|
|
<input type="text" class="form-control" id="step2-dbUsername"
|
|
placeholder="<%= defaults.mysqlUser %>" value="<%= defaults.mysqlUser %>" required>
|
|
<span class="form-text text-muted">
|
|
The database username (usually <code>root</code>).
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<label for="step2-dbPassword" class="col-md-3 col-form-label">
|
|
Database Password
|
|
</label>
|
|
<div class="col-md-9">
|
|
<input type="text" class="form-control blur-input" id="step2-dbPassword"
|
|
autocomplete="off" placeholder="leave it blank" value="<%= defaults.mysqlPassword %>">
|
|
<span class="form-text text-muted">
|
|
The database password (usually blank).
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<label for="step2-dbName" class="col-md-3 col-form-label">
|
|
Database Name
|
|
</label>
|
|
<div class="col-md-9">
|
|
<input type="text" class="form-control" id="step2-dbName"
|
|
placeholder="<%= defaults.mysqlDatabase %>" value="<%= defaults.mysqlDatabase %>">
|
|
<span class="form-text text-muted">
|
|
The name of the database to be used or created. <br>
|
|
If left empty, the deployment ID (<code><%= deploymentID %></code>) will be used instead.
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<label for="step2-dbDelete" class="col-md-3 col-form-label">
|
|
Delete Database
|
|
</label>
|
|
<div class="col-md-9">
|
|
<label class="c-switch c-switch-label c-switch-pill c-switch-success fix-pill-form">
|
|
<input class="c-switch-input" type="checkbox" id="step2-dbDelete" checked>
|
|
<span class="c-switch-slider" data-checked="On" data-unchecked="Off"></span>
|
|
</label>
|
|
<span class="form-text text-muted">
|
|
If already exists, automatically deletes the database with the name provided above. <br>
|
|
<strong>Warning:</strong> all data will be lost.
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% } %>
|
|
<% if (inputVars.length) { %>
|
|
<div class="hrsep hrsep-small mb-3">Custom Variables</div>
|
|
<% for (const [key, inputVar] of inputVars.entries()) { %>
|
|
<div class="form-group row">
|
|
<label for="step2-customVar<%= key %>" class="col-md-3 col-form-label">
|
|
<%= inputVar.name %>
|
|
</label>
|
|
<div class="col-md-9">
|
|
<input type="text" class="form-control customRecipeVars" id="step2-customVar<%= key %>"
|
|
data-varName="<%= inputVar.name %>" placeholder="<%= inputVar.value %>" value="<%= inputVar.value %>">
|
|
<% if (inputVar.description) { %>
|
|
<span class="form-text text-muted">
|
|
<%- inputVar.description %>
|
|
</span>
|
|
<% } %>
|
|
</div>
|
|
</div>
|
|
<% } %>
|
|
<% } %>
|
|
</form>
|
|
<div class="row justify-content-center m-2 mt-3">
|
|
<button class="btn btn-outline-danger" type="button"
|
|
onclick="cancelAction()">Cancel and Return to Setup</button>
|
|
|
|
<button class="btn btn-success" type="button"
|
|
onclick="step2Action();">Run Recipe</button>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer text-muted">Step 3: Run Recipe</div>
|
|
<div class="card-footer text-muted">Step 4: Configure server.cfg</div>
|
|
|
|
<% } else if (step === 'run') { %>
|
|
<div class="card-header">Step 1: Review Recipe ✔️</div>
|
|
<div class="card-header">Step 2: Input Parameters ✔️</div>
|
|
<div class="card-header font-weight-bold ">Step 3: Run Recipe</div>
|
|
<div class="card-body">
|
|
<div class="row mb-1 mt-0 text-center">
|
|
<div class="col-8 mx-auto card d-block border-primary p-2 mb-1">
|
|
Your recipe is being executed, the server will be deployed to: <br>
|
|
<code class="inline-code"><%= deployPath %></code>
|
|
</div>
|
|
</div>
|
|
<div class="row mb-3">
|
|
<div class="col-10 mx-auto card d-block p-2 m-0">
|
|
<pre id="step3Log" class="text-body"><h3 class="text-center">🐌🐌🐌</h3></pre>
|
|
</div>
|
|
</div>
|
|
<div class="mx-auto col-8">
|
|
<div class="progress">
|
|
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar"
|
|
aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"
|
|
style="width: 0%" id="step3Progress">0%</div>
|
|
</div>
|
|
<span class="text-danger font-weight-bold d-none" id="step3Error"></span>
|
|
</div>
|
|
<div class="row justify-content-center m-2">
|
|
<button class="btn btn-outline-danger d-none" type="button"
|
|
onclick="cancelAction();" id="step3CancelButton">Cancel and Return to Setup</button>
|
|
<button type="button" class="btn btn-info d-none"
|
|
onclick="window.location.reload();" id="step3NextButton">Next</button>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer text-muted">Step 3: Configure server.cfg</div>
|
|
|
|
<% } else if (step === 'configure') { %>
|
|
<style>
|
|
.CodeMirror{
|
|
height: auto;
|
|
}
|
|
</style>
|
|
<div class="card-header">Step 1: Review Recipe ✔️</div>
|
|
<div class="card-header">Step 2: Input Parameters ✔️</div>
|
|
<div class="card-header">Step 3: Run Recipe ✔️</div>
|
|
<div class="card-header font-weight-bold">Step 4: Configure server.cfg</div>
|
|
<div class="card-body">
|
|
<div class="row mb-1 mt-0 text-center">
|
|
<div class="col-8 mx-auto card d-block border-primary p-2 mb-1">
|
|
Configure your <code class="inline-code">server.cfg</code> file to your liking, <br>
|
|
then press the <strong>Save & Run Server</strong> button below.
|
|
</div>
|
|
</div>
|
|
|
|
<textarea id="codeMirrorTarget" style="width: 100%;" class="cms-s-lucario" name="code"><%= serverCFG %></textarea>
|
|
<div class="row justify-content-center m-2">
|
|
<button class="btn btn-outline-danger" type="button" onclick="cancelAction()">Cancel and Return to Setup</button>
|
|
|
|
<button class="btn btn-success" type="button" onclick="step4Action();">Save & Run Server</button>
|
|
</div>
|
|
</div>
|
|
|
|
<% } else { %>
|
|
<div class="card-body text-center">
|
|
Something is wrong 🤔
|
|
</div>
|
|
<% } %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<!-- CoreUI and necessary plugins-->
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
|
|
integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ=="
|
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/marked@4.0.16/lib/marked.umd.min.js"></script>
|
|
<script src="js/coreui.bundle.min.js?txVer=<%= txAdminVersion %>"></script>
|
|
<script src="js/bootstrap-notify.min.js?txVer=<%= txAdminVersion %>"></script>
|
|
<script src="js/txadmin/base.js?txVer=<%= txAdminVersion %>"></script>
|
|
|
|
<!-- JS -->
|
|
<!-- <script src="js/codeEditor/codemirror.js?txVer=<%= txAdminVersion %>"></script> -->
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.61.1/codemirror.min.js"
|
|
integrity="sha512-ZTpbCvmiv7Zt4rK0ltotRJVRaSBKFQHQTrwfs6DoYlBYzO1MA6Oz2WguC+LkV8pGiHraYLEpo7Paa+hoVbCfKw=="
|
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
<script src="js/codeEditor/mode/simple.js?txVer=<%= txAdminVersion %>"></script>
|
|
<script src="js/codeEditor/mode/fivem-cfg.js?txVer=<%= txAdminVersion %>"></script>
|
|
<script src="js/codeEditor/mode/yaml.js?txVer=<%= txAdminVersion %>"></script>
|
|
<script>
|
|
//============================================== CodeMirror & Page Setup
|
|
const currentStep = '<%= step %>';
|
|
const codeMirrorTarget = document.getElementById("codeMirrorTarget");
|
|
|
|
window.onload = function () {
|
|
if(currentStep == 'review' || currentStep == 'configure'){
|
|
window.CMInstance = CodeMirror.fromTextArea(codeMirrorTarget, {
|
|
mode: (currentStep == 'review')? 'yaml' : 'fivem-cfg',
|
|
lineNumbers: true,
|
|
lineWrapping: true,
|
|
viewportMargin: Infinity,
|
|
theme: "lucario" //NOTE: I modified the theme a bit
|
|
});
|
|
}
|
|
};
|
|
|
|
|
|
//============================================== Step1 action
|
|
function step1Action(){
|
|
const editor = window.CMInstance;
|
|
if(editor.getValue().includes('This is just a placeholder')){
|
|
return $.notify({ message: `If you are not trying to write a recipe, click on the cancel button below to return to the setup page, where you can select a recommended template. Otherwise, jut remove the placeholder warning comment.` }, { type: 'warning' });
|
|
}
|
|
editor.setValue(editor.getValue().replace(/\t/g, ' '.repeat(4)));
|
|
const recipe = editor.getValue();
|
|
if(recipe.length < 256){
|
|
return $.notify({ message: `Your Recipe file is too small, there is a good chance you deleted something you shouldn't.` }, { type: 'warning' });
|
|
}
|
|
const notify = $.notify({ message: '<p class="text-center">Saving...</p>' }, {});
|
|
|
|
txAdminAPI({
|
|
type: "POST",
|
|
url: '/deployer/recipe/confirmRecipe',
|
|
timeout: REQ_TIMEOUT_LONG,
|
|
data: {recipe},
|
|
success: function (data) {
|
|
if (checkApiLogoutRefresh(data)) return;
|
|
if (data.success == true){
|
|
window.location.reload(true);
|
|
}else{
|
|
notify.update('progress', 0);
|
|
notify.update('type', data.type);
|
|
notify.update('message', data.message);
|
|
}
|
|
|
|
},
|
|
error: function (xmlhttprequest, textstatus, message) {
|
|
notify.update('progress', 0);
|
|
notify.update('type', 'danger');
|
|
notify.update('message', message);
|
|
}
|
|
});
|
|
}
|
|
|
|
//============================================== Step2 action
|
|
const requireDBConfig = ('<%= requireDBConfig %>' == 'true');
|
|
const step2elements = {
|
|
form: document.getElementById('step2-form'),
|
|
svLicense: document.getElementById('step2-svLicense'),
|
|
}
|
|
if(requireDBConfig){
|
|
step2elements.dbHost = document.getElementById('step2-dbHost');
|
|
step2elements.dbPort = document.getElementById('step2-dbPort');
|
|
step2elements.dbUsername = document.getElementById('step2-dbUsername');
|
|
step2elements.dbPassword = document.getElementById('step2-dbPassword');
|
|
step2elements.dbName = document.getElementById('step2-dbName');
|
|
step2elements.dbDelete = document.getElementById('step2-dbDelete');
|
|
|
|
step2elements.dbName.addEventListener("keyup", () => {
|
|
const dbName = step2elements.dbName.value.trim()
|
|
step2elements.dbDelete.checked = (dbName == step2elements.dbName.placeholder || !dbName.length);
|
|
});
|
|
}
|
|
|
|
if(step2elements.form){
|
|
step2elements.form.addEventListener('submit', (e) => {
|
|
e.preventDefault();
|
|
step2Action();
|
|
});
|
|
}
|
|
|
|
function step2Action(){
|
|
if(!step2elements.form.reportValidity()) return;
|
|
const postData = {
|
|
svLicense: step2elements.svLicense.value.trim()
|
|
}
|
|
if(requireDBConfig){
|
|
postData.dbHost = step2elements.dbHost.value.trim();
|
|
postData.dbPort = step2elements.dbPort.value.trim();
|
|
postData.dbUsername = step2elements.dbUsername.value.trim();
|
|
postData.dbPassword = step2elements.dbPassword.value.trim();
|
|
postData.dbName = step2elements.dbName.value.trim();
|
|
postData.dbDelete = step2elements.dbDelete.checked;
|
|
|
|
if(!postData.dbName.length){
|
|
postData.dbName = step2elements.dbName.placeholder;
|
|
}
|
|
if(!postData.dbHost || !postData.dbPort || !postData.dbUsername){
|
|
return $.notify({ message: `The database host, port and username are required.` }, { type: 'warning' });
|
|
}
|
|
}
|
|
|
|
//Getting custom forms:
|
|
const customVarInputs = step2elements.form.getElementsByClassName("customRecipeVars");
|
|
for(const input of customVarInputs){
|
|
if(!input.dataset.varname) continue;
|
|
postData[input.dataset.varname] = input.value.trim();
|
|
}
|
|
|
|
const notify = $.notify({ message: '<p class="text-center">Saving...</p>' }, {});
|
|
txAdminAPI({
|
|
type: "POST",
|
|
url: '/deployer/recipe/setVariables',
|
|
timeout: REQ_TIMEOUT_LONG,
|
|
data: postData,
|
|
success: function (data) {
|
|
if (checkApiLogoutRefresh(data)) return;
|
|
if (data.success == true){
|
|
window.location.reload(true);
|
|
}else{
|
|
notify.update('progress', 0);
|
|
notify.update('type', data.type);
|
|
notify.update('message', data.message);
|
|
}
|
|
|
|
},
|
|
error: function (xmlhttprequest, textstatus, message) {
|
|
notify.update('progress', 0);
|
|
notify.update('type', 'danger');
|
|
notify.update('message', message);
|
|
}
|
|
});
|
|
}
|
|
|
|
//============================================== Step3 action
|
|
const step3elements = {
|
|
log: document.getElementById('step3Log'),
|
|
progress: document.getElementById('step3Progress'),
|
|
error: document.getElementById('step3Error'),
|
|
cancelButton: document.getElementById('step3CancelButton'),
|
|
nextButton: document.getElementById('step3NextButton'),
|
|
}
|
|
const refreshStatus = async () => {
|
|
txAdminAPI({
|
|
type: "GET",
|
|
url: '/deployer/status',
|
|
timeout: REQ_TIMEOUT_LONG,
|
|
success: function (data) {
|
|
if (checkApiLogoutRefresh(data)) return;
|
|
step3elements.error.classList.add('d-none');
|
|
step3elements.log.innerText = data.log;
|
|
|
|
if(data.status == 'done'){
|
|
step3elements.progress.classList.remove('progress-bar-animated', 'progress-bar-striped');
|
|
step3elements.progress.classList.add('bg-success');
|
|
step3elements.nextButton.classList.remove('d-none');
|
|
step3elements.progress.ariaValueNow = 100;
|
|
step3elements.progress.style.width = '100%';
|
|
step3elements.progress.innerText = 'DONE';
|
|
|
|
}else if(data.status == 'failed'){
|
|
step3elements.progress.classList.remove('progress-bar-animated', 'progress-bar-striped');
|
|
step3elements.progress.classList.add('bg-danger');
|
|
step3elements.cancelButton.classList.remove('d-none');
|
|
step3elements.progress.ariaValueNow = 100;
|
|
step3elements.progress.style.width = '100%';
|
|
step3elements.progress.innerText = 'FAILED';
|
|
|
|
}else{
|
|
const ariaMin = (data.progress > 5)? data.progress : 5;
|
|
step3elements.progress.ariaValueNow = ariaMin;
|
|
step3elements.progress.style.width = ariaMin + '%';
|
|
step3elements.progress.innerText = data.progress + '%';
|
|
step3elements.progress.scrollIntoView();
|
|
|
|
}
|
|
},
|
|
error: function (xmlhttprequest, textstatus, message) {
|
|
step3elements.error.innerText = `Error: ${textstatus}`;
|
|
step3elements.error.classList.remove('d-none');
|
|
}
|
|
});
|
|
}
|
|
|
|
if(currentStep == 'run') setInterval(refreshStatus, 1000);
|
|
|
|
|
|
//============================================== Step4 action
|
|
function step4Action(){
|
|
const serverCFG = window.CMInstance.getValue();
|
|
if(serverCFG.length < 256){
|
|
return $.notify({ message: `Your settings.cfg file is too small, there is a good chance it is not valid.` }, { type: 'warning' });
|
|
}
|
|
const notify = $.notify({ message: '<p class="text-center">Saving...</p>' }, {});
|
|
|
|
if(serverCFG.includes(`sv_licenseKey "changeme"`)){
|
|
return $.notify({ message: `Please change the <strong>sv_licenseKey</strong>.` }, { type: 'danger' });
|
|
}
|
|
|
|
txAdminAPI({
|
|
type: "POST",
|
|
url: '/deployer/recipe/commit',
|
|
timeout: REQ_TIMEOUT_LONG,
|
|
data: {serverCFG},
|
|
success: function (data) {
|
|
if (checkApiLogoutRefresh(data)) return;
|
|
if (data.success == true){
|
|
navigateParentTo('/server/console');
|
|
}else{
|
|
updateMarkdownNotification(data, notify);
|
|
}
|
|
},
|
|
error: function (xmlhttprequest, textstatus, message) {
|
|
notify.update('progress', 0);
|
|
notify.update('type', 'danger');
|
|
notify.update('message', message);
|
|
}
|
|
});
|
|
}
|
|
|
|
//============================================== cancel action
|
|
function cancelAction(){
|
|
const notify = $.notify({ message: '<p class="text-center">Cancelling...</p>' }, {});
|
|
txAdminAPI({
|
|
type: "POST",
|
|
url: '/deployer/recipe/cancel',
|
|
timeout: REQ_TIMEOUT_LONG,
|
|
success: function (data) {
|
|
if (checkApiLogoutRefresh(data)) return;
|
|
if (data.success == true){
|
|
navigateParentTo('/server/setup');
|
|
}else{
|
|
notify.update('progress', 0);
|
|
notify.update('type', data.type);
|
|
notify.update('message', data.message);
|
|
}
|
|
},
|
|
error: function (xmlhttprequest, textstatus, message) {
|
|
notify.update('progress', 0);
|
|
notify.update('type', 'danger');
|
|
notify.update('message', message);
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html>
|