mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-15 21:03:55 -07:00
Use @stylistic/brace-style for eslint
Up to now `eslint-plugin-brace-rules` was used to enforce a common brace style for JavaScript code. This plugin was however updated the last time over 9 years ago and will be incompatible with ESLint v10, as that [removes `context.getSourceCode()`][1], the plugin relies on. To keep the eslint config working with ESLint v10, this replaces `eslint-plugin-brace-rules` with the [`@stylistic/brace-style`][2] rule from `@stylistic/eslint-plugin`, a package we already use. While `@stylistic/brace-style` doesn't offer an option to format braces in exactly the same way as before, the "allman" style seems to be the one closest to the existing code. [1]: https://eslint.org/blog/2025/11/eslint-v10.0.0-alpha.0-released/#removed-deprecated-rule-context-members [2]: https://eslint.style/rules/brace-style
This commit is contained in:
parent
8f8d1195c2
commit
93ce94655d
259 changed files with 4643 additions and 3421 deletions
|
|
@ -83,13 +83,12 @@ repos:
|
|||
args:
|
||||
- --strict
|
||||
- repo: https://github.com/eslint/eslint
|
||||
rev: v9.33.0
|
||||
rev: v9.39.2
|
||||
hooks:
|
||||
- id: eslint
|
||||
language_version: 22.14.0
|
||||
additional_dependencies:
|
||||
- eslint-plugin-brace-rules@0.1.6
|
||||
- "@stylistic/eslint-plugin@4.4.0"
|
||||
- "@stylistic/eslint-plugin@5.6.1"
|
||||
args:
|
||||
- --max-warnings=0
|
||||
- --no-warn-ignored
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ var obj1 = Engine.GetGUIObjectByName("obj1");
|
|||
var obj3 = Engine.GetGUIObjectByName("obj3");
|
||||
|
||||
obj1.onTick = () => { ++called1; };
|
||||
Engine.GetGUIObjectByName("obj2").onTick = () => {
|
||||
Engine.GetGUIObjectByName("obj2").onTick = () =>
|
||||
{
|
||||
++called2;
|
||||
delete obj1.onTick;
|
||||
delete obj3.onTick;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ try
|
|||
{
|
||||
Engine.callback();
|
||||
}
|
||||
catch (e)
|
||||
catch(e)
|
||||
{
|
||||
log(e.message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ async function waitAndIncrement(promise)
|
|||
|
||||
{
|
||||
let resolve;
|
||||
const promise = new Promise(res => {
|
||||
const promise = new Promise(res =>
|
||||
{
|
||||
incrementTest();
|
||||
resolve = res;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ function TestScript2A() {}
|
|||
|
||||
TestScript2A.prototype.Schema = "<ref name='anything'/>";
|
||||
|
||||
TestScript2A.prototype.Init = function() {
|
||||
TestScript2A.prototype.Init = function()
|
||||
{
|
||||
this.x = eval(this.template.y);
|
||||
};
|
||||
|
||||
TestScript2A.prototype.GetX = function() {
|
||||
TestScript2A.prototype.GetX = function()
|
||||
{
|
||||
return this.x;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,20 @@
|
|||
function TestScript1A() {}
|
||||
|
||||
TestScript1A.prototype.GetX = function() {
|
||||
TestScript1A.prototype.GetX = function()
|
||||
{
|
||||
// Test that .entity is readonly
|
||||
try {
|
||||
try
|
||||
{
|
||||
delete this.entity;
|
||||
Engine.TS_FAIL("Missed exception");
|
||||
} catch (e) { /* noop */ }
|
||||
try {
|
||||
}
|
||||
catch(e) { /* noop */ }
|
||||
try
|
||||
{
|
||||
this.entity = -1;
|
||||
Engine.TS_FAIL("Missed exception");
|
||||
} catch (e) { /* noop */ }
|
||||
}
|
||||
catch(e) { /* noop */ }
|
||||
|
||||
// and return the value
|
||||
return this.entity;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
function TestScript1_Helper() {}
|
||||
|
||||
TestScript1_Helper.prototype.GetX = function() {
|
||||
TestScript1_Helper.prototype.GetX = function()
|
||||
{
|
||||
return AdditionHelper(1, 2);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ function HotloadA() {}
|
|||
|
||||
HotloadA.prototype.Schema = "<ref name='anything'/>";
|
||||
|
||||
HotloadA.prototype.Init = function() {
|
||||
HotloadA.prototype.Init = function()
|
||||
{
|
||||
this.x = +this.template.x;
|
||||
};
|
||||
|
||||
HotloadA.prototype.GetX = function() {
|
||||
HotloadA.prototype.GetX = function()
|
||||
{
|
||||
return this.x;
|
||||
};
|
||||
|
||||
|
|
@ -15,11 +17,13 @@ Engine.RegisterComponentType(IID_Test1, "HotloadA", HotloadA);
|
|||
|
||||
function HotloadB() {}
|
||||
|
||||
HotloadB.prototype.Init = function() {
|
||||
HotloadB.prototype.Init = function()
|
||||
{
|
||||
this.x = +this.template.x;
|
||||
};
|
||||
|
||||
HotloadB.prototype.GetX = function() {
|
||||
HotloadB.prototype.GetX = function()
|
||||
{
|
||||
return this.x * 2;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ function HotloadA() {}
|
|||
|
||||
HotloadA.prototype.Schema = "<ref name='anything'/>";
|
||||
|
||||
HotloadA.prototype.Init = function() {
|
||||
HotloadA.prototype.Init = function()
|
||||
{
|
||||
this.x = +this.template.x;
|
||||
};
|
||||
|
||||
HotloadA.prototype.GetX = function() {
|
||||
HotloadA.prototype.GetX = function()
|
||||
{
|
||||
return this.x*10;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ function Modding() {}
|
|||
|
||||
Modding.prototype.Schema = "<ref name='anything'/>";
|
||||
|
||||
Modding.prototype.Init = function() {
|
||||
Modding.prototype.Init = function()
|
||||
{
|
||||
this.x = +this.template.x;
|
||||
};
|
||||
|
||||
Modding.prototype.GetX = function() {
|
||||
Modding.prototype.GetX = function()
|
||||
{
|
||||
return this.x;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
Modding.prototype.GetX = function() {
|
||||
Modding.prototype.GetX = function()
|
||||
{
|
||||
return this.x * 10;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
function TestScript1A() {}
|
||||
|
||||
TestScript1A.prototype.Init = function() {
|
||||
TestScript1A.prototype.Init = function()
|
||||
{
|
||||
this.x = 100;
|
||||
};
|
||||
|
||||
TestScript1A.prototype.GetX = function() {
|
||||
TestScript1A.prototype.GetX = function()
|
||||
{
|
||||
return this.x;
|
||||
};
|
||||
|
||||
TestScript1A.prototype.OnUpdate = function(msg) {
|
||||
TestScript1A.prototype.OnUpdate = function(msg)
|
||||
{
|
||||
this.x += msg.turnLength;
|
||||
};
|
||||
|
||||
|
|
@ -18,15 +21,18 @@ Engine.RegisterComponentType(IID_Test1, "TestScript1A", TestScript1A);
|
|||
|
||||
function TestScript1B() {}
|
||||
|
||||
TestScript1B.prototype.Init = function() {
|
||||
TestScript1B.prototype.Init = function()
|
||||
{
|
||||
this.x = 100;
|
||||
};
|
||||
|
||||
TestScript1B.prototype.GetX = function() {
|
||||
TestScript1B.prototype.GetX = function()
|
||||
{
|
||||
return this.x;
|
||||
};
|
||||
|
||||
TestScript1B.prototype.OnGlobalUpdate = function(msg) {
|
||||
TestScript1B.prototype.OnGlobalUpdate = function(msg)
|
||||
{
|
||||
this.x += msg.turnLength;
|
||||
};
|
||||
|
||||
|
|
@ -36,11 +42,13 @@ Engine.RegisterComponentType(IID_Test1, "TestScript1B", TestScript1B);
|
|||
|
||||
function TestScript2A() {}
|
||||
|
||||
TestScript2A.prototype.Init = function() {
|
||||
TestScript2A.prototype.Init = function()
|
||||
{
|
||||
this.x = 200;
|
||||
};
|
||||
|
||||
TestScript2A.prototype.GetX = function() {
|
||||
TestScript2A.prototype.GetX = function()
|
||||
{
|
||||
Engine.BroadcastMessage(MT_Update, { "turnLength": 50 });
|
||||
Engine.PostMessage(1, MT_Update, { "turnLength": 500 });
|
||||
Engine.PostMessage(2, MT_Update, { "turnLength": 5000 });
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
function TestScript1_Init() {}
|
||||
|
||||
TestScript1_Init.prototype.Init = function() {
|
||||
TestScript1_Init.prototype.Init = function()
|
||||
{
|
||||
var param = this.template;
|
||||
// print("# ",uneval(param),"\n");
|
||||
if (param)
|
||||
|
|
@ -9,7 +10,8 @@ TestScript1_Init.prototype.Init = function() {
|
|||
this.x = 100;
|
||||
};
|
||||
|
||||
TestScript1_Init.prototype.GetX = function() {
|
||||
TestScript1_Init.prototype.GetX = function()
|
||||
{
|
||||
return this.x;
|
||||
};
|
||||
|
||||
|
|
@ -19,12 +21,18 @@ Engine.RegisterComponentType(IID_Test1, "TestScript1_Init", TestScript1_Init);
|
|||
|
||||
function TestScript1_readonly() {}
|
||||
|
||||
TestScript1_readonly.prototype.GetX = function() {
|
||||
try { this.template = null; } catch (e) { /* noop */ }
|
||||
try { delete this.template; } catch (e) { /* noop */ }
|
||||
try { this.template.x += 1000; } catch (e) { /* noop */ }
|
||||
try { delete this.template.x; } catch (e) { /* noop */ }
|
||||
try { this.template.y = 2000; } catch (e) { /* noop */ }
|
||||
TestScript1_readonly.prototype.GetX = function()
|
||||
{
|
||||
try { this.template = null; }
|
||||
catch(e) { /* noop */ }
|
||||
try { delete this.template; }
|
||||
catch(e) { /* noop */ }
|
||||
try { this.template.x += 1000; }
|
||||
catch(e) { /* noop */ }
|
||||
try { delete this.template.x; }
|
||||
catch(e) { /* noop */ }
|
||||
try { this.template.y = 2000; }
|
||||
catch(e) { /* noop */ }
|
||||
return +(this.template.x || 1) + +(this.template.y || 2);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
function TestScript1A() {}
|
||||
|
||||
TestScript1A.prototype.Init = function() {
|
||||
TestScript1A.prototype.Init = function()
|
||||
{
|
||||
this.x = 100;
|
||||
};
|
||||
|
||||
TestScript1A.prototype.GetX = function() {
|
||||
TestScript1A.prototype.GetX = function()
|
||||
{
|
||||
var test2 = Engine.QueryInterface(this.entity, IID_Test2);
|
||||
return test2.GetX() + (test2.x || 0);
|
||||
};
|
||||
|
|
@ -15,11 +17,13 @@ Engine.RegisterComponentType(IID_Test1, "TestScript1A", TestScript1A);
|
|||
|
||||
function TestScript2A() {}
|
||||
|
||||
TestScript2A.prototype.Init = function() {
|
||||
TestScript2A.prototype.Init = function()
|
||||
{
|
||||
this.x = 200;
|
||||
};
|
||||
|
||||
TestScript2A.prototype.GetX = function() {
|
||||
TestScript2A.prototype.GetX = function()
|
||||
{
|
||||
return this.x;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
function TestScript1_values() {}
|
||||
|
||||
TestScript1_values.prototype.Init = function() {
|
||||
TestScript1_values.prototype.Init = function()
|
||||
{
|
||||
this.x = +this.template.x;
|
||||
this.str = "this is a string";
|
||||
this.things = { "a": 1, "b": "2", "c": [3, "4", [5, []]] };
|
||||
};
|
||||
|
||||
TestScript1_values.prototype.GetX = function() {
|
||||
TestScript1_values.prototype.GetX = function()
|
||||
{
|
||||
// print(uneval(this));
|
||||
return this.x;
|
||||
};
|
||||
|
|
@ -17,16 +19,21 @@ Engine.RegisterComponentType(IID_Test1, "TestScript1_values", TestScript1_values
|
|||
|
||||
function TestScript1_entity() {}
|
||||
|
||||
TestScript1_entity.prototype.GetX = function() {
|
||||
TestScript1_entity.prototype.GetX = function()
|
||||
{
|
||||
// Test that .entity is readonly
|
||||
try {
|
||||
try
|
||||
{
|
||||
delete this.entity;
|
||||
Engine.TS_FAIL("Missed exception");
|
||||
} catch (e) { /* OK */ }
|
||||
try {
|
||||
}
|
||||
catch(e) { /* OK */ }
|
||||
try
|
||||
{
|
||||
this.entity = -1;
|
||||
Engine.TS_FAIL("Missed exception");
|
||||
} catch (e) { /* OK */ }
|
||||
}
|
||||
catch(e) { /* OK */ }
|
||||
|
||||
// and return the value
|
||||
return this.entity;
|
||||
|
|
@ -38,13 +45,15 @@ Engine.RegisterComponentType(IID_Test1, "TestScript1_entity", TestScript1_entity
|
|||
|
||||
function TestScript1_nontree() {}
|
||||
|
||||
TestScript1_nontree.prototype.Init = function() {
|
||||
TestScript1_nontree.prototype.Init = function()
|
||||
{
|
||||
var n = [1];
|
||||
this.x = [n, n, null, { "y": n }];
|
||||
this.x[2] = this.x;
|
||||
};
|
||||
|
||||
TestScript1_nontree.prototype.GetX = function() {
|
||||
TestScript1_nontree.prototype.GetX = function()
|
||||
{
|
||||
// print(uneval(this)+"\n");
|
||||
this.x[0][0] += 1;
|
||||
return this.x[0][0] + this.x[1][0] + this.x[2][0][0] + this.x[3].y[0];
|
||||
|
|
@ -56,15 +65,18 @@ Engine.RegisterComponentType(IID_Test1, "TestScript1_nontree", TestScript1_nontr
|
|||
|
||||
function TestScript1_custom() {}
|
||||
|
||||
TestScript1_custom.prototype.Init = function() {
|
||||
TestScript1_custom.prototype.Init = function()
|
||||
{
|
||||
this.y = 2;
|
||||
};
|
||||
|
||||
TestScript1_custom.prototype.Serialize = function() {
|
||||
TestScript1_custom.prototype.Serialize = function()
|
||||
{
|
||||
return { "c": 1 };
|
||||
};
|
||||
|
||||
TestScript1_custom.prototype.Deserialize = function(data) {
|
||||
TestScript1_custom.prototype.Deserialize = function(data)
|
||||
{
|
||||
this.c = data.c;
|
||||
};
|
||||
|
||||
|
|
@ -74,7 +86,8 @@ Engine.RegisterComponentType(IID_Test1, "TestScript1_custom", TestScript1_custom
|
|||
|
||||
function TestScript1_getter() {}
|
||||
|
||||
TestScript1_getter.prototype.Init = function() {
|
||||
TestScript1_getter.prototype.Init = function()
|
||||
{
|
||||
this.x = 100;
|
||||
this.__defineGetter__('x', function() { print("FAIL\n"); die(); return 200; });
|
||||
};
|
||||
|
|
@ -87,17 +100,20 @@ function TestScript1_consts() {}
|
|||
|
||||
TestScript1_consts.prototype.Schema = "<ref name='anything'/>";
|
||||
|
||||
TestScript1_consts.prototype.Init = function() {
|
||||
TestScript1_consts.prototype.Init = function()
|
||||
{
|
||||
this.cached = (+this.entity) + (+this.template.x);
|
||||
};
|
||||
|
||||
TestScript1_consts.prototype.Serialize = null;
|
||||
|
||||
TestScript1_consts.prototype.Deserialize = function(data) {
|
||||
TestScript1_consts.prototype.Deserialize = function(data)
|
||||
{
|
||||
this.Init();
|
||||
};
|
||||
|
||||
TestScript1_consts.prototype.GetX = function() {
|
||||
TestScript1_consts.prototype.GetX = function()
|
||||
{
|
||||
return this.cached;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
function TestScript1A() {}
|
||||
|
||||
TestScript1A.prototype.Init = function() {
|
||||
TestScript1A.prototype.Init = function()
|
||||
{
|
||||
this.x = 101000;
|
||||
};
|
||||
|
||||
TestScript1A.prototype.GetX = function() {
|
||||
TestScript1A.prototype.GetX = function()
|
||||
{
|
||||
return this.x;
|
||||
};
|
||||
|
||||
TestScript1A.prototype.OnTurnStart = function(msg) {
|
||||
TestScript1A.prototype.OnTurnStart = function(msg)
|
||||
{
|
||||
this.x += 1;
|
||||
};
|
||||
|
||||
|
|
@ -20,7 +23,8 @@ function TestScript1B() {}
|
|||
|
||||
TestScript1B.prototype = Object.create(TestScript1A.prototype);
|
||||
|
||||
TestScript1B.prototype.Init = function() {
|
||||
TestScript1B.prototype.Init = function()
|
||||
{
|
||||
this.x = 102000;
|
||||
};
|
||||
|
||||
|
|
@ -30,15 +34,18 @@ Engine.RegisterComponentType(IID_Test1, "TestScript1B", TestScript1B);
|
|||
|
||||
function TestScript2A() {}
|
||||
|
||||
TestScript2A.prototype.Init = function() {
|
||||
TestScript2A.prototype.Init = function()
|
||||
{
|
||||
this.x = 201000;
|
||||
};
|
||||
|
||||
TestScript2A.prototype.GetX = function() {
|
||||
TestScript2A.prototype.GetX = function()
|
||||
{
|
||||
return this.x;
|
||||
};
|
||||
|
||||
TestScript2A.prototype.OnUpdate = function(msg) {
|
||||
TestScript2A.prototype.OnUpdate = function(msg)
|
||||
{
|
||||
this.x += msg.turnLength;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ export async function init(initialColor)
|
|||
|
||||
const splitColor = initialColor.split(" ");
|
||||
|
||||
const chanels = labels.map((label, i) => {
|
||||
const chanels = labels.map((label, i) =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("colorLabel[" + i + "]").caption = label;
|
||||
resizeChanel(i);
|
||||
|
||||
|
|
@ -70,8 +71,10 @@ export async function init(initialColor)
|
|||
while (true)
|
||||
{
|
||||
colorDisplay.sprite = "color:" + currentColor();
|
||||
const chanelPromises = chanels.map(chanel => {
|
||||
return new Promise(resolve => {
|
||||
const chanelPromises = chanels.map(chanel =>
|
||||
{
|
||||
return new Promise(resolve =>
|
||||
{
|
||||
chanel.slider.onValueChange = resolve.bind(undefined, { "value": chanel });
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -23,8 +23,10 @@ function distributeButtonsHorizontally(button, captions)
|
|||
|
||||
function setButtonCaptionsAndVisibility(buttons, captions, cancelHotkey, name)
|
||||
{
|
||||
return new Promise(resolve => {
|
||||
captions.forEach((caption, i) => {
|
||||
return new Promise(resolve =>
|
||||
{
|
||||
captions.forEach((caption, i) =>
|
||||
{
|
||||
buttons[i] = Engine.GetGUIObjectByName(name + (i + 1));
|
||||
buttons[i].caption = caption;
|
||||
buttons[i].hidden = false;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ var g_IncompatibleModsFile = "gui/incompatible_mods/incompatible_mods.txt";
|
|||
function init(data)
|
||||
{
|
||||
Engine.GetGUIObjectByName("mainText").caption = Engine.TranslateLines(Engine.ReadFile(g_IncompatibleModsFile));
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("btnClose").onPress = closePageCallback;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,12 +27,14 @@ var g_ModIOState = {
|
|||
/**
|
||||
* Finished status indicators
|
||||
*/
|
||||
"ready": (progressData, closePageCallback) => {
|
||||
"ready": (progressData, closePageCallback) =>
|
||||
{
|
||||
// GameID acquired, ready to fetch mod list
|
||||
if (!g_RequestCancelled)
|
||||
updateModList(closePageCallback);
|
||||
},
|
||||
"listed": progressData => {
|
||||
"listed": progressData =>
|
||||
{
|
||||
// List of available mods acquired
|
||||
|
||||
// Only run this once (for each update).
|
||||
|
|
@ -44,7 +46,8 @@ var g_ModIOState = {
|
|||
g_ModsAvailableOnline = Engine.ModIoGetMods();
|
||||
displayMods();
|
||||
},
|
||||
"success": progressData => {
|
||||
"success": progressData =>
|
||||
{
|
||||
// Successfully acquired a mod file
|
||||
hideDialog();
|
||||
Engine.GetGUIObjectByName("downloadButton").enabled = true;
|
||||
|
|
@ -52,20 +55,24 @@ var g_ModIOState = {
|
|||
/**
|
||||
* In-progress status indicators.
|
||||
*/
|
||||
"gameid": progressData => {
|
||||
"gameid": progressData =>
|
||||
{
|
||||
// Acquiring GameID from mod.io
|
||||
},
|
||||
"listing": progressData => {
|
||||
"listing": progressData =>
|
||||
{
|
||||
// Acquiring list of available mods from mod.io
|
||||
},
|
||||
"downloading": progressData => {
|
||||
"downloading": progressData =>
|
||||
{
|
||||
// Downloading a mod file
|
||||
updateProgressBar(progressData.progress, g_ModsAvailableOnline[selectedModIndex()].filesize);
|
||||
},
|
||||
/**
|
||||
* Error/Failure status indicators.
|
||||
*/
|
||||
"failed_gameid": async(progressData, closePageCallback) => {
|
||||
"failed_gameid": async(progressData, closePageCallback) =>
|
||||
{
|
||||
// Game ID couldn't be retrieved
|
||||
const promise = showErrorMessageBox(
|
||||
sprintf(translateWithContext("mod.io error message", "Game ID could not be retrieved.\n\n%(technicalDetails)s"), {
|
||||
|
|
@ -80,7 +87,8 @@ var g_ModIOState = {
|
|||
else
|
||||
init();
|
||||
},
|
||||
"failed_listing": async(progressData, closePageCallback) => {
|
||||
"failed_listing": async(progressData, closePageCallback) =>
|
||||
{
|
||||
// Mod list couldn't be retrieved
|
||||
const promise = showErrorMessageBox(
|
||||
sprintf(translateWithContext("mod.io error message", "Mod List could not be retrieved.\n\n%(technicalDetails)s"), {
|
||||
|
|
@ -95,7 +103,8 @@ var g_ModIOState = {
|
|||
else
|
||||
updateModList(closePageCallback);
|
||||
},
|
||||
"failed_downloading": async(progressData) => {
|
||||
"failed_downloading": async(progressData) =>
|
||||
{
|
||||
// File couldn't be retrieved
|
||||
const promise = showErrorMessageBox(
|
||||
sprintf(translateWithContext("mod.io error message", "File download failed.\n\n%(technicalDetails)s"), {
|
||||
|
|
@ -110,7 +119,8 @@ var g_ModIOState = {
|
|||
else
|
||||
downloadMod();
|
||||
},
|
||||
"failed_filecheck": async(progressData) => {
|
||||
"failed_filecheck": async(progressData) =>
|
||||
{
|
||||
// The file is corrupted
|
||||
const promise = showErrorMessageBox(
|
||||
sprintf(translateWithContext("mod.io error message", "File verification error.\n\n%(technicalDetails)s"), {
|
||||
|
|
@ -126,7 +136,8 @@ var g_ModIOState = {
|
|||
/**
|
||||
* Default
|
||||
*/
|
||||
"none": progressData => {
|
||||
"none": progressData =>
|
||||
{
|
||||
// Nothing has happened yet.
|
||||
}
|
||||
};
|
||||
|
|
@ -144,7 +155,8 @@ function init(data)
|
|||
|
||||
return Promise.race([
|
||||
promise,
|
||||
new Promise(closePageCallback => {
|
||||
new Promise(closePageCallback =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("backButton").onPress = closePageCallback;
|
||||
Engine.GetGUIObjectByName("modio").onTick = onTick.bind(null, closePageCallback);
|
||||
})
|
||||
|
|
@ -327,7 +339,8 @@ async function progressDialog(dialogCaption, dialogTitle, showProgressBar, butto
|
|||
|
||||
const downloadDialog_button = Engine.GetGUIObjectByName("downloadDialog_button");
|
||||
downloadDialog_button.caption = buttonCaption;
|
||||
await new Promise(resolve => {
|
||||
await new Promise(resolve =>
|
||||
{
|
||||
downloadDialog_button.onPress = resolve;
|
||||
});
|
||||
cancelRequest();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
function init(data)
|
||||
{
|
||||
Engine.GetGUIObjectByName("mainText").caption = Engine.TranslateLines(Engine.ReadFile("gui/modmod/help/help.txt"));
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("closeButton").onPress = closePageCallback;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ function init(data, hotloadData)
|
|||
if (g_HasIncompatibleMods)
|
||||
Engine.OpenChildPage("page_incompatible_mods.xml", {});
|
||||
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("quitButton").onPress = closePageCallback;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ async function init(data)
|
|||
initURLButtons(data.termsURL, data.urlButtons);
|
||||
initLanguageSelection();
|
||||
|
||||
const accepted = await new Promise(resolve => {
|
||||
const accepted = await new Promise(resolve =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("cancelButton").onPress = resolve.bind(null, false);
|
||||
Engine.GetGUIObjectByName("connectButton").onPress = resolve.bind(null, true);
|
||||
});
|
||||
|
|
@ -40,14 +41,16 @@ function initURLButtons(termsURL, urlButtons)
|
|||
"url": termsURL
|
||||
});
|
||||
|
||||
urlButtons.forEach((urlButton, i) => {
|
||||
urlButtons.forEach((urlButton, i) =>
|
||||
{
|
||||
const button = Engine.GetGUIObjectByName("button[" + i + "]");
|
||||
button.caption = urlButton.caption;
|
||||
button.hidden = false;
|
||||
button.tooltip = sprintf(translate("Open %(url)s in the browser."), {
|
||||
"url": urlButton.url
|
||||
});
|
||||
button.onPress = () => {
|
||||
button.onPress = () =>
|
||||
{
|
||||
openURL(urlButton.url);
|
||||
};
|
||||
});
|
||||
|
|
@ -62,7 +65,8 @@ function initLanguageSelection()
|
|||
const languageDropdown = Engine.GetGUIObjectByName("languageDropdown");
|
||||
languageDropdown.size = (languageLabelWidth + 10) + " 4 100% 100%";
|
||||
|
||||
languageDropdown.list = (() => {
|
||||
languageDropdown.list = (() =>
|
||||
{
|
||||
const displayNames = Engine.GetSupportedLocaleDisplayNames();
|
||||
const baseNames = Engine.GetSupportedLocaleBaseNames();
|
||||
|
||||
|
|
@ -80,7 +84,8 @@ function initLanguageSelection()
|
|||
return list;
|
||||
})();
|
||||
|
||||
languageDropdown.onSelectionChange = () => {
|
||||
languageDropdown.onSelectionChange = () =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("mainText").caption =
|
||||
sprintf(
|
||||
languageDropdown.selected == 1 ?
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ print("<th>GL_RENDERER");
|
|||
print("<th>Output");
|
||||
print("<th>Warnings");
|
||||
|
||||
hwdetectTestData.sort(function(a, b) {
|
||||
hwdetectTestData.sort(function(a, b)
|
||||
{
|
||||
if (a.renderer_backend.GL_RENDERER < b.renderer_backend.GL_RENDERER)
|
||||
return -1;
|
||||
if (b.renderer_backend.GL_RENDERER < a.renderer_backend.GL_RENDERER)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
import { Plugin } from 'tools/dap/plugin.js';
|
||||
|
||||
class DapCommands extends Plugin {
|
||||
constructor(jsDebugger, dapHandler) {
|
||||
class DapCommands extends Plugin
|
||||
{
|
||||
constructor(jsDebugger, dapHandler)
|
||||
{
|
||||
super('DapCommonCommand', 'command');
|
||||
|
||||
jsDebugger.registerHookName('onInitialize', this.name);
|
||||
dapHandler.registerCommand('initialize', (req) => {
|
||||
dapHandler.registerCommand('initialize', (req) =>
|
||||
{
|
||||
this.logger.info('Handling initialize command');
|
||||
return dapHandler.successResponse(req, {
|
||||
'supportsConfigurationDoneRequest': true,
|
||||
|
|
@ -13,26 +16,30 @@ class DapCommands extends Plugin {
|
|||
});
|
||||
});
|
||||
|
||||
dapHandler.registerCommand('disconnect', (req) => {
|
||||
dapHandler.registerCommand('disconnect', (req) =>
|
||||
{
|
||||
this.logger.info('Handling disconnect command');
|
||||
jsDebugger.setAttached(false);
|
||||
Engine.EndWaitingForMessage();
|
||||
return dapHandler.successResponse(req, undefined);
|
||||
});
|
||||
|
||||
dapHandler.registerCommand('attach', (req) => {
|
||||
dapHandler.registerCommand('attach', (req) =>
|
||||
{
|
||||
this.logger.info('Handling attach command');
|
||||
jsDebugger.setAttached(true);
|
||||
jsDebugger.pushEvent('initialized', undefined, this.name);
|
||||
return dapHandler.successResponse(req, undefined);
|
||||
});
|
||||
|
||||
dapHandler.registerCommand('configurationDone', (req) => {
|
||||
dapHandler.registerCommand('configurationDone', (req) =>
|
||||
{
|
||||
this.logger.info('Handling configurationDone command');
|
||||
return dapHandler.successResponse(req, undefined);
|
||||
});
|
||||
|
||||
dapHandler.registerCommand('threads', (req) => {
|
||||
dapHandler.registerCommand('threads', (req) =>
|
||||
{
|
||||
this.logger.info('Handling threads command');
|
||||
jsDebugger.triggerHook('onInitialize', undefined);
|
||||
return dapHandler.successResponse(req, {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,22 @@
|
|||
import { logger } from 'tools/dap/logger.js';
|
||||
|
||||
export class DapProtocolHandler {
|
||||
constructor(jsDebugger) {
|
||||
export class DapProtocolHandler
|
||||
{
|
||||
constructor(jsDebugger)
|
||||
{
|
||||
this.commands = {};
|
||||
this.jsDebugger = jsDebugger;
|
||||
this.logger = logger.getLogger("DAPProtocolHandler");
|
||||
}
|
||||
|
||||
registerCommand(name, fn) {
|
||||
registerCommand(name, fn)
|
||||
{
|
||||
this.logger.info(`Registering command: ${name}`);
|
||||
this.commands[name] = fn;
|
||||
}
|
||||
|
||||
handleRequest(req) {
|
||||
handleRequest(req)
|
||||
{
|
||||
if (req.type !== 'request' || !req.command)
|
||||
{
|
||||
this.logger.error(`Invalid request: ${JSON.stringify(req)}`);
|
||||
|
|
@ -28,7 +32,7 @@ export class DapProtocolHandler {
|
|||
this.logger.info(`Handling command: ${req.command}`);
|
||||
return handler(req);
|
||||
}
|
||||
catch (error)
|
||||
catch(error)
|
||||
{
|
||||
this.logger.error(`Error handling command ${req.command}:`, error);
|
||||
this.logger.error(uneval(error.stack));
|
||||
|
|
@ -36,7 +40,8 @@ export class DapProtocolHandler {
|
|||
}
|
||||
}
|
||||
|
||||
successResponse(req, result) {
|
||||
successResponse(req, result)
|
||||
{
|
||||
this.logger.info(`Response to ${req.command}`, result);
|
||||
const response = {
|
||||
'type': 'response',
|
||||
|
|
@ -48,7 +53,8 @@ export class DapProtocolHandler {
|
|||
return response;
|
||||
}
|
||||
|
||||
errorResponse(req, error) {
|
||||
errorResponse(req, error)
|
||||
{
|
||||
this.logger.error(`Error in ${req.command}: ${error}`);
|
||||
const response = {
|
||||
'type': 'response',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import { logger } from 'tools/dap/logger.js';
|
||||
|
||||
export class JsDebugger {
|
||||
constructor() {
|
||||
export class JsDebugger
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
this.debugger = new Debugger();
|
||||
this.logger = logger.getLogger("SpiderDebugger");
|
||||
this.events = [];
|
||||
|
|
@ -19,30 +21,36 @@ export class JsDebugger {
|
|||
'onRsumeInFrame': [],
|
||||
};
|
||||
|
||||
this.debugger.uncaughtExceptionHook = (e) => {
|
||||
this.debugger.uncaughtExceptionHook = (e) =>
|
||||
{
|
||||
this._runHooks('onUncaughtException', e);
|
||||
};
|
||||
|
||||
this.debugger.onNewGlobalObject = (global) => {
|
||||
this.debugger.onNewGlobalObject = (global) =>
|
||||
{
|
||||
this._runHooks('onNewGlobalObject', global);
|
||||
};
|
||||
|
||||
this.debugger.onDebuggerStatement = (frame) => {
|
||||
this.debugger.onDebuggerStatement = (frame) =>
|
||||
{
|
||||
this._runHooks('onDebuggerStatement', frame);
|
||||
};
|
||||
|
||||
this.debugger.onNewScript = (script, global) => {
|
||||
this.debugger.onNewScript = (script, global) =>
|
||||
{
|
||||
this._runHooks('onNewScript', { script, global });
|
||||
};
|
||||
|
||||
this.debugger.onEnterFrame = (frame) => {
|
||||
this.debugger.onEnterFrame = (frame) =>
|
||||
{
|
||||
this._runHooks('onEnterFrame', frame);
|
||||
};
|
||||
|
||||
this.debuggerAttached = false;
|
||||
}
|
||||
|
||||
_runHooks(event, data) {
|
||||
_runHooks(event, data)
|
||||
{
|
||||
this.logger.trace(`Running hook for ${event}`);
|
||||
for (const hookInfo of this.hooks[event])
|
||||
{
|
||||
|
|
@ -53,16 +61,20 @@ export class JsDebugger {
|
|||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
hookInfo.callback(data);
|
||||
} catch (e) {
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
this.logger.error(`Error in hook for ${hookInfo.source}-${event}: ${e.message}`);
|
||||
this.logger.error(uneval(e.stack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
on(event, callback, source) {
|
||||
on(event, callback, source)
|
||||
{
|
||||
if (!event || typeof event !== 'string')
|
||||
{
|
||||
this.logger.warn('Invalid event name');
|
||||
|
|
@ -90,11 +102,13 @@ export class JsDebugger {
|
|||
this.logger.debug(`Hook added for event: ${event}`);
|
||||
}
|
||||
|
||||
get instance() {
|
||||
get instance()
|
||||
{
|
||||
return this.debugger;
|
||||
}
|
||||
|
||||
setAttached(attached) {
|
||||
setAttached(attached)
|
||||
{
|
||||
this.debuggerAttached = attached;
|
||||
if (attached)
|
||||
{
|
||||
|
|
@ -108,7 +122,8 @@ export class JsDebugger {
|
|||
}
|
||||
}
|
||||
|
||||
pushEvent(eventName, eventData, source) {
|
||||
pushEvent(eventName, eventData, source)
|
||||
{
|
||||
if (!eventName || typeof eventName !== 'string')
|
||||
{
|
||||
this.logger.warn('Invalid event name');
|
||||
|
|
@ -128,7 +143,8 @@ export class JsDebugger {
|
|||
});
|
||||
}
|
||||
|
||||
stopInframe(frame, onHandler) {
|
||||
stopInframe(frame, onHandler)
|
||||
{
|
||||
if (!frame || !(frame instanceof Debugger.Frame))
|
||||
{
|
||||
this.logger.error('Invalid frame provided to stopInframe');
|
||||
|
|
@ -150,7 +166,8 @@ export class JsDebugger {
|
|||
this.logger.debug("Client continue");
|
||||
}
|
||||
|
||||
registerHookName(event, source) {
|
||||
registerHookName(event, source)
|
||||
{
|
||||
if (!event || typeof event !== 'string')
|
||||
{
|
||||
this.logger.warn('Invalid event name');
|
||||
|
|
@ -173,7 +190,8 @@ export class JsDebugger {
|
|||
this.logger.debug(`Hook registered for event: ${event} from source: ${source}`);
|
||||
}
|
||||
|
||||
triggerHook(event, data) {
|
||||
triggerHook(event, data)
|
||||
{
|
||||
if (!event || typeof event !== 'string')
|
||||
{
|
||||
this.logger.warn('Invalid event name');
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
class Logger {
|
||||
class Logger
|
||||
{
|
||||
levels = ['trace', 'debug', 'info', 'warn', 'error'];
|
||||
// Default = 'info'.
|
||||
levelIndex = 2;
|
||||
|
||||
setLevel(level) {
|
||||
setLevel(level)
|
||||
{
|
||||
const index = this.levels.indexOf(level);
|
||||
if (index === -1)
|
||||
{
|
||||
|
|
@ -12,9 +14,12 @@ class Logger {
|
|||
this.levelIndex = index;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.levels.forEach((level, index) => {
|
||||
this[level] = (...args) => {
|
||||
constructor()
|
||||
{
|
||||
this.levels.forEach((level, index) =>
|
||||
{
|
||||
this[level] = (...args) =>
|
||||
{
|
||||
if (index < this.levelIndex)
|
||||
return;
|
||||
|
||||
|
|
@ -28,14 +33,18 @@ class Logger {
|
|||
});
|
||||
}
|
||||
|
||||
getLevel() {
|
||||
getLevel()
|
||||
{
|
||||
return this.levels[this.levelIndex];
|
||||
}
|
||||
|
||||
getLogger(className) {
|
||||
getLogger(className)
|
||||
{
|
||||
const scopedLogger = {};
|
||||
this.levels.forEach((level) => {
|
||||
scopedLogger[level] = (msg) => {
|
||||
this.levels.forEach((level) =>
|
||||
{
|
||||
scopedLogger[level] = (msg) =>
|
||||
{
|
||||
this[level](`[${className}]`, msg);
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,21 +1,26 @@
|
|||
import { Plugin } from 'tools/dap/plugin.js';
|
||||
|
||||
class AttachManager extends Plugin {
|
||||
constructor(jsDebugger, dapHandler) {
|
||||
class AttachManager extends Plugin
|
||||
{
|
||||
constructor(jsDebugger, dapHandler)
|
||||
{
|
||||
super('AttachManager', 'manager');
|
||||
|
||||
this.logger.debug('Setting up AttachManager');
|
||||
jsDebugger.on('onDebuggerAttached', () => {
|
||||
jsDebugger.on('onDebuggerAttached', () =>
|
||||
{
|
||||
this.logger.debug('Debugger attached');
|
||||
jsDebugger.instance.addAllGlobalsAsDebuggees();
|
||||
}, this.name);
|
||||
|
||||
jsDebugger.on('onDebuggerDetached', () => {
|
||||
jsDebugger.on('onDebuggerDetached', () =>
|
||||
{
|
||||
this.logger.debug('Debugger detached');
|
||||
jsDebugger.instance.removeAllDebuggees();
|
||||
}, this.name);
|
||||
|
||||
jsDebugger.on('onNewGlobalObject', (global) => {
|
||||
jsDebugger.on('onNewGlobalObject', (global) =>
|
||||
{
|
||||
if (!jsDebugger.debuggerAttached)
|
||||
return;
|
||||
|
||||
|
|
@ -23,7 +28,8 @@ class AttachManager extends Plugin {
|
|||
jsDebugger.instance.addDebuggee(global);
|
||||
}, this.name);
|
||||
|
||||
jsDebugger.on('onUncaughtException', (e) => {
|
||||
jsDebugger.on('onUncaughtException', (e) =>
|
||||
{
|
||||
this.logger.error(`Uncaught exception: ${e}`);
|
||||
}, this.name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
import { Plugin } from 'tools/dap/plugin.js';
|
||||
|
||||
class BreakpointManager extends Plugin {
|
||||
constructor(jsDebugger, dapHandler) {
|
||||
class BreakpointManager extends Plugin
|
||||
{
|
||||
constructor(jsDebugger, dapHandler)
|
||||
{
|
||||
super('BreakpointManager', 'manager');
|
||||
this.breakpoints = [];
|
||||
|
||||
this.dbg = jsDebugger.instance;
|
||||
this.jsDebugger = jsDebugger;
|
||||
this.logger.debug('Setting up BreakpointManager');
|
||||
jsDebugger.on('onNewScript', ({ script, global }) => {
|
||||
jsDebugger.on('onNewScript', ({ script, global }) =>
|
||||
{
|
||||
if (!jsDebugger.debuggerAttached)
|
||||
return;
|
||||
|
||||
|
|
@ -24,7 +27,8 @@ class BreakpointManager extends Plugin {
|
|||
|
||||
this.logger.debug(`Setting breakpoints for script: ${script.url}`);
|
||||
const sourceReferenceIndex = jsDebugger.sourcesReferences.findIndex((src) => src.path === url);
|
||||
this.breakpoints[index].lines.forEach((bp, i) => {
|
||||
this.breakpoints[index].lines.forEach((bp, i) =>
|
||||
{
|
||||
jsDebugger.pushEvent('breakpoint', {
|
||||
'reason': 'changed',
|
||||
'breakpoint': {
|
||||
|
|
@ -40,13 +44,15 @@ class BreakpointManager extends Plugin {
|
|||
});
|
||||
}, this.name);
|
||||
|
||||
jsDebugger.on('onDebuggerDetached', () => {
|
||||
jsDebugger.on('onDebuggerDetached', () =>
|
||||
{
|
||||
this.logger.debug('Debugger detached');
|
||||
this.dbg.clearAllBreakpoints();
|
||||
this.breakpoints = [];
|
||||
}, this.name);
|
||||
|
||||
dapHandler.registerCommand('setBreakpoints', (req) => {
|
||||
dapHandler.registerCommand('setBreakpoints', (req) =>
|
||||
{
|
||||
const path = req.arguments.source.path;
|
||||
const name = req.arguments.source.name;
|
||||
this.logger.debug(`Handling setBreakpoints command for source: ${req.arguments.source.path}`);
|
||||
|
|
@ -76,7 +82,8 @@ class BreakpointManager extends Plugin {
|
|||
});
|
||||
}
|
||||
|
||||
createOrUpdateBreakpoint(name, url, lines) {
|
||||
createOrUpdateBreakpoint(name, url, lines)
|
||||
{
|
||||
let index = this.breakpoints.findIndex((bp) => (!name || bp.name === name) && bp.url === url);
|
||||
if (index === -1)
|
||||
{
|
||||
|
|
@ -89,7 +96,8 @@ class BreakpointManager extends Plugin {
|
|||
return index + 1;
|
||||
}
|
||||
|
||||
addBreakpointsByPath(path, instance_script) {
|
||||
addBreakpointsByPath(path, instance_script)
|
||||
{
|
||||
const infoBk = this.breakpoints.find((bp) => bp.url === path);
|
||||
|
||||
if (!infoBk)
|
||||
|
|
@ -100,15 +108,18 @@ class BreakpointManager extends Plugin {
|
|||
return false;
|
||||
|
||||
this.logger.trace(`Found ${scripts.length} scripts for path: ${path}`);
|
||||
this.scriptTreeWalk(scripts, (script) => {
|
||||
this.scriptTreeWalk(scripts, (script) =>
|
||||
{
|
||||
script.clearAllBreakpoints();
|
||||
});
|
||||
|
||||
infoBk.lines.forEach((bp) => {
|
||||
infoBk.lines.forEach((bp) =>
|
||||
{
|
||||
this.logger.debug(`Setting breakpoint at: ${uneval(bp)}`);
|
||||
bp.verified = false;
|
||||
bp.message = "No offset found";
|
||||
this.scriptTreeWalk(scripts, (script) => {
|
||||
this.scriptTreeWalk(scripts, (script) =>
|
||||
{
|
||||
const offsets = script.getPossibleBreakpointOffsets({
|
||||
'line': bp.line,
|
||||
});
|
||||
|
|
@ -128,7 +139,8 @@ class BreakpointManager extends Plugin {
|
|||
return true;
|
||||
}
|
||||
|
||||
scriptTreeWalk(script, callback) {
|
||||
scriptTreeWalk(script, callback)
|
||||
{
|
||||
if (!script || script.length === 0)
|
||||
return;
|
||||
|
||||
|
|
@ -143,8 +155,10 @@ class BreakpointManager extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
handleBreakpoint(frame) {
|
||||
this.jsDebugger.stopInframe(frame, () => {
|
||||
handleBreakpoint(frame)
|
||||
{
|
||||
this.jsDebugger.stopInframe(frame, () =>
|
||||
{
|
||||
this.jsDebugger.pushEvent('stopped', {
|
||||
'reason': 'breakpoint',
|
||||
'threadId': 1,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import { Plugin } from 'tools/dap/plugin.js';
|
||||
|
||||
class FrameManager extends Plugin {
|
||||
constructor(jsDebugger, dapHandler) {
|
||||
class FrameManager extends Plugin
|
||||
{
|
||||
constructor(jsDebugger, dapHandler)
|
||||
{
|
||||
super('FrameManager', 'manager');
|
||||
|
||||
this.logger.debug('Setting up FrameManager');
|
||||
|
|
@ -12,7 +14,8 @@ class FrameManager extends Plugin {
|
|||
jsDebugger.registerHookName('onStepIn', this.name);
|
||||
jsDebugger.registerHookName('onStepOut', this.name);
|
||||
|
||||
jsDebugger.on('onDebuggerDetached', () => {
|
||||
jsDebugger.on('onDebuggerDetached', () =>
|
||||
{
|
||||
this.logger.debug('Debugger detached');
|
||||
let frame = jsDebugger.currentFrame;
|
||||
while (frame)
|
||||
|
|
@ -24,8 +27,10 @@ class FrameManager extends Plugin {
|
|||
jsDebugger.currentFrame = undefined;
|
||||
}, this.name);
|
||||
|
||||
jsDebugger.on('onDebuggerStatement', (frame) => {
|
||||
jsDebugger.stopInframe(frame, () => {
|
||||
jsDebugger.on('onDebuggerStatement', (frame) =>
|
||||
{
|
||||
jsDebugger.stopInframe(frame, () =>
|
||||
{
|
||||
this.logger.debug(`Paused on debugger statement in frame: ${frame.script.url}`);
|
||||
jsDebugger.pushEvent('stopped', {
|
||||
'reason': 'debugger',
|
||||
|
|
@ -35,7 +40,8 @@ class FrameManager extends Plugin {
|
|||
});
|
||||
}, this.name);
|
||||
|
||||
jsDebugger.on('onEnterFrame', (frame) => {
|
||||
jsDebugger.on('onEnterFrame', (frame) =>
|
||||
{
|
||||
if (!frame || !frame.older || !frame.older.stepIn || frame.onStep !== undefined)
|
||||
return;
|
||||
|
||||
|
|
@ -43,7 +49,8 @@ class FrameManager extends Plugin {
|
|||
this.hookFrameDebugger(frame, "stepIn", "Paused on stepIn");
|
||||
}, this.name);
|
||||
|
||||
dapHandler.registerCommand('stackTrace', (req) => {
|
||||
dapHandler.registerCommand('stackTrace', (req) =>
|
||||
{
|
||||
this.logger.debug('Handling stackTrace command');
|
||||
if (!jsDebugger.currentFrame)
|
||||
{
|
||||
|
|
@ -71,7 +78,8 @@ class FrameManager extends Plugin {
|
|||
return dapHandler.successResponse(req, { 'stackFrames': stackFrames });
|
||||
});
|
||||
|
||||
dapHandler.registerCommand('continue', (req) => {
|
||||
dapHandler.registerCommand('continue', (req) =>
|
||||
{
|
||||
this.logger.debug('Handling continue command');
|
||||
let frame = jsDebugger.currentFrame;
|
||||
while (frame)
|
||||
|
|
@ -84,7 +92,8 @@ class FrameManager extends Plugin {
|
|||
return dapHandler.successResponse(req, { 'allThreadsContinued': true });
|
||||
});
|
||||
|
||||
dapHandler.registerCommand('next', (req) => {
|
||||
dapHandler.registerCommand('next', (req) =>
|
||||
{
|
||||
this.logger.debug('Handling next command');
|
||||
if (!jsDebugger.currentFrame)
|
||||
{
|
||||
|
|
@ -103,7 +112,8 @@ class FrameManager extends Plugin {
|
|||
return dapHandler.successResponse(req, undefined);
|
||||
});
|
||||
|
||||
dapHandler.registerCommand('stepIn', (req) => {
|
||||
dapHandler.registerCommand('stepIn', (req) =>
|
||||
{
|
||||
this.logger.debug('Handling stepIn command');
|
||||
if (!jsDebugger.currentFrame)
|
||||
{
|
||||
|
|
@ -122,7 +132,8 @@ class FrameManager extends Plugin {
|
|||
return dapHandler.successResponse(req, undefined);
|
||||
});
|
||||
|
||||
dapHandler.registerCommand('stepOut', (req) => {
|
||||
dapHandler.registerCommand('stepOut', (req) =>
|
||||
{
|
||||
this.logger.debug('Handling stepOut command');
|
||||
if (!jsDebugger.currentFrame)
|
||||
{
|
||||
|
|
@ -142,28 +153,32 @@ class FrameManager extends Plugin {
|
|||
});
|
||||
}
|
||||
|
||||
extractScriptName(url) {
|
||||
extractScriptName(url)
|
||||
{
|
||||
if (!url)
|
||||
return "[No Name]";
|
||||
const parts = url.split('\\');
|
||||
return parts[parts.length - 1] || "[No Name]";
|
||||
}
|
||||
|
||||
hookFrameDebugger(frame, reason, msg) {
|
||||
hookFrameDebugger(frame, reason, msg)
|
||||
{
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
const that = this;
|
||||
if (frame.onStep === undefined)
|
||||
{
|
||||
frame.onStep = function() {
|
||||
frame.onStep = function()
|
||||
{
|
||||
if (this.stepOut === true && this.stepOver !== true)
|
||||
return;
|
||||
const currentLocation = this.script.getOffsetLocation(frame.offset);
|
||||
if (this.currentLocation?.lineNumber === currentLocation.lineNumber)
|
||||
return;
|
||||
|
||||
that.jsDebugger.stopInframe(this, () => {
|
||||
that.jsDebugger.stopInframe(this, () =>
|
||||
{
|
||||
that.jsDebugger.pushEvent('stopped', {
|
||||
'reason': reason,
|
||||
'threadId': 1,
|
||||
|
|
@ -176,7 +191,8 @@ class FrameManager extends Plugin {
|
|||
|
||||
if (frame.onPop === undefined)
|
||||
{
|
||||
frame.onPop = function() {
|
||||
frame.onPop = function()
|
||||
{
|
||||
if (this.stepIn || this.stepOut)
|
||||
that.hookFrameDebugger(this.older, reason, msg);
|
||||
that.cleanFrameDebugger(this);
|
||||
|
|
@ -184,7 +200,8 @@ class FrameManager extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
cleanFrameDebugger(frame) {
|
||||
cleanFrameDebugger(frame)
|
||||
{
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,28 @@
|
|||
import { Plugin } from 'tools/dap/plugin.js';
|
||||
|
||||
class InspectorManager extends Plugin {
|
||||
constructor(jsDebugger, dapHandler) {
|
||||
class InspectorManager extends Plugin
|
||||
{
|
||||
constructor(jsDebugger, dapHandler)
|
||||
{
|
||||
super('InspectorManager', 'manager');
|
||||
this.variableReferences = [];
|
||||
|
||||
this.logger.debug('Setting up InspectorManager');
|
||||
|
||||
jsDebugger.on('onDebuggerDetached', () => {
|
||||
jsDebugger.on('onDebuggerDetached', () =>
|
||||
{
|
||||
this.logger.debug('Debugger attached');
|
||||
this.variableReferences = [];
|
||||
}, this.name);
|
||||
|
||||
jsDebugger.on('onContinue', () => {
|
||||
jsDebugger.on('onContinue', () =>
|
||||
{
|
||||
this.logger.debug('Continuing execution');
|
||||
this.variableReferences = [];
|
||||
}, this.name);
|
||||
|
||||
dapHandler.registerCommand('scopes', (req) => {
|
||||
dapHandler.registerCommand('scopes', (req) =>
|
||||
{
|
||||
this.logger.debug('Handling scopes command');
|
||||
if (!jsDebugger.currentFrame)
|
||||
{
|
||||
|
|
@ -49,7 +54,8 @@ class InspectorManager extends Plugin {
|
|||
return dapHandler.successResponse(req, { 'scopes': this.createScopeAndVariableReferences(frame, req.arguments.frameId) });
|
||||
});
|
||||
|
||||
dapHandler.registerCommand('variables', (req) => {
|
||||
dapHandler.registerCommand('variables', (req) =>
|
||||
{
|
||||
this.logger.debug('Handling variables command');
|
||||
if (!jsDebugger.currentFrame)
|
||||
{
|
||||
|
|
@ -61,7 +67,8 @@ class InspectorManager extends Plugin {
|
|||
return dapHandler.successResponse(req, { 'variables': variables });
|
||||
});
|
||||
|
||||
dapHandler.registerCommand('evaluate', (req) => {
|
||||
dapHandler.registerCommand('evaluate', (req) =>
|
||||
{
|
||||
this.logger.debug('Handling evaluate command');
|
||||
if (!jsDebugger.currentFrame)
|
||||
{
|
||||
|
|
@ -91,7 +98,7 @@ class InspectorManager extends Plugin {
|
|||
});
|
||||
return dapHandler.successResponse(req, { 'result': JSON.stringify(result) || "null", 'variablesReference': 0 });
|
||||
}
|
||||
catch (error)
|
||||
catch(error)
|
||||
{
|
||||
this.logger.error(`Error evaluating expression: ${error.message}`);
|
||||
return dapHandler.errorResponse(req, `Error evaluating expression: ${error.message}`);
|
||||
|
|
@ -99,7 +106,8 @@ class InspectorManager extends Plugin {
|
|||
});
|
||||
}
|
||||
|
||||
createOrUpdateVariableReference(name, data) {
|
||||
createOrUpdateVariableReference(name, data)
|
||||
{
|
||||
let index = this.variableReferences.findIndex((ref) => ref.name === name);
|
||||
if (index === -1)
|
||||
{
|
||||
|
|
@ -112,7 +120,8 @@ class InspectorManager extends Plugin {
|
|||
return index + 1;
|
||||
}
|
||||
|
||||
createScopeAndVariableReferences(frame, frameId) {
|
||||
createScopeAndVariableReferences(frame, frameId)
|
||||
{
|
||||
if (!frame || !frame.onStack || frame.terminated)
|
||||
{
|
||||
this.logger.error(`Invalid frame: ${frameId}`);
|
||||
|
|
@ -181,7 +190,8 @@ class InspectorManager extends Plugin {
|
|||
return scopes;
|
||||
}
|
||||
|
||||
describeJSObjectCallable(jsObject, varName) {
|
||||
describeJSObjectCallable(jsObject, varName)
|
||||
{
|
||||
if (!jsObject || !(jsObject instanceof Debugger.Object) || !jsObject.callable)
|
||||
{
|
||||
this.logger.error('Invalid JS Object for callable description');
|
||||
|
|
@ -221,7 +231,8 @@ class InspectorManager extends Plugin {
|
|||
return variable;
|
||||
}
|
||||
|
||||
describeJSObjectVariable(jsObject, varRefName, varReference, varName) {
|
||||
describeJSObjectVariable(jsObject, varRefName, varReference, varName)
|
||||
{
|
||||
if (!jsObject || !(jsObject instanceof Debugger.Object))
|
||||
{
|
||||
this.logger.error('Invalid JS Object for description');
|
||||
|
|
@ -307,7 +318,8 @@ class InspectorManager extends Plugin {
|
|||
return variable;
|
||||
}
|
||||
|
||||
expandVariableReference(variableReferenceIndex, frame) {
|
||||
expandVariableReference(variableReferenceIndex, frame)
|
||||
{
|
||||
if (variableReferenceIndex === 0 || this.variableReferences.length < variableReferenceIndex - 1)
|
||||
{
|
||||
this.logger.warn(`Invalid variable reference index: ${variableReferenceIndex}`);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
import { Plugin } from 'tools/dap/plugin.js';
|
||||
|
||||
class SourcesManager extends Plugin {
|
||||
constructor(jsDebugger, dapHandler) {
|
||||
class SourcesManager extends Plugin
|
||||
{
|
||||
constructor(jsDebugger, dapHandler)
|
||||
{
|
||||
super('SourcesManager', 'manager');
|
||||
this.jsDebugger = jsDebugger;
|
||||
this.logger.debug('Setting up SourcesManager');
|
||||
|
||||
jsDebugger.on('onNewScript', ({ script, global }) => {
|
||||
jsDebugger.on('onNewScript', ({ script, global }) =>
|
||||
{
|
||||
if (!jsDebugger.debuggerAttached)
|
||||
return;
|
||||
|
||||
|
|
@ -31,15 +34,18 @@ class SourcesManager extends Plugin {
|
|||
}, this.name);
|
||||
}, this.name);
|
||||
|
||||
jsDebugger.on('onDebuggerDetached', () => {
|
||||
jsDebugger.on('onDebuggerDetached', () =>
|
||||
{
|
||||
this.logger.debug('Debugger detached');
|
||||
this.jsDebugger.sourcesReferences = [];
|
||||
}, this.name);
|
||||
|
||||
jsDebugger.on('onDebuggerAttached', () => {
|
||||
jsDebugger.on('onDebuggerAttached', () =>
|
||||
{
|
||||
this.logger.debug('Debugger attached');
|
||||
this.jsDebugger.sourcesReferences = [];
|
||||
this.jsDebugger.instance.findSources().forEach((source) => {
|
||||
this.jsDebugger.instance.findSources().forEach((source) =>
|
||||
{
|
||||
const url = source.url;
|
||||
if (this.jsDebugger.sourcesReferences.some((src) => src.path === url))
|
||||
return;
|
||||
|
|
@ -50,7 +56,8 @@ class SourcesManager extends Plugin {
|
|||
});
|
||||
}, this.name);
|
||||
|
||||
dapHandler.registerCommand('loadedSources', (req) => {
|
||||
dapHandler.registerCommand('loadedSources', (req) =>
|
||||
{
|
||||
if (!jsDebugger.debuggerAttached)
|
||||
{
|
||||
this.logger.error('Debugger not attached, cannot handle loadedSources command');
|
||||
|
|
@ -66,7 +73,8 @@ class SourcesManager extends Plugin {
|
|||
return dapHandler.successResponse(req, { 'sources': sources });
|
||||
});
|
||||
|
||||
dapHandler.registerCommand('source', (req) => {
|
||||
dapHandler.registerCommand('source', (req) =>
|
||||
{
|
||||
if (!jsDebugger.debuggerAttached)
|
||||
{
|
||||
this.logger.error('Debugger not attached, cannot handle source command');
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import { logger } from 'tools/dap/logger.js';
|
||||
|
||||
export class Plugin {
|
||||
constructor(name, type) {
|
||||
export class Plugin
|
||||
{
|
||||
constructor(name, type)
|
||||
{
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.logger = logger.getLogger(name);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class AutoStartClient
|
|||
const port = +(cmdLineArgs['autostart-port'] ?? 5073);
|
||||
Engine.StartNetworkJoin(playerName, ip, port, !('autostart-disable-replay' in cmdLineArgs));
|
||||
}
|
||||
catch (e)
|
||||
catch(e)
|
||||
{
|
||||
const message = sprintf(translate("Cannot join game: %(message)s."), { "message": e.message });
|
||||
messageBox(400, 200, message, translate("Error"));
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class AutoStartHost
|
|||
// Password not implemented for autostart.
|
||||
Engine.StartNetworkHost(playerName, port, "", false, !('autostart-disable-replay' in cmdLineArgs));
|
||||
}
|
||||
catch (e)
|
||||
catch(e)
|
||||
{
|
||||
const message = sprintf(translate("Cannot host game: %(message)s."), { "message": e.message });
|
||||
messageBox(400, 200, message, translate("Error"));
|
||||
|
|
|
|||
|
|
@ -120,7 +120,8 @@ function parseCmdLineArgs(settings, cmdLineArgs)
|
|||
settings.playerCount.setNb(+cmdLineArgs['autostart-players']);
|
||||
}
|
||||
|
||||
const getPlayer = (key, i) => {
|
||||
const getPlayer = (key, i) =>
|
||||
{
|
||||
if (!(('autostart-' + key) in cmdLineArgs))
|
||||
return undefined;
|
||||
var value = cmdLineArgs['autostart-' + key];
|
||||
|
|
|
|||
|
|
@ -183,7 +183,8 @@ GameSettings.prototype.Attributes.PlayerColor = class PlayerColor extends GameSe
|
|||
|
||||
_getUnusedColor()
|
||||
{
|
||||
return this.available.find(color => {
|
||||
return this.available.find(color =>
|
||||
{
|
||||
return this.values.every(otherColor => !otherColor || !sameColor(color, otherColor));
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,8 @@ GameSettings.prototype.Attributes.PlayerName = class PlayerName extends GameSett
|
|||
const translatedCountLabel = this.settings.isNetworked ? this.CountLabel : translate(this.CountLabel);
|
||||
const translatedChosenName = this.settings.isNetworked ? chosenName : translate(chosenName);
|
||||
|
||||
const duplicateNameCount = AIPlayerNamesList.reduce((count, name) => {
|
||||
const duplicateNameCount = AIPlayerNamesList.reduce((count, name) =>
|
||||
{
|
||||
if (name == chosenName)
|
||||
count++;
|
||||
return count;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ class DamageTypesMetadata
|
|||
}
|
||||
|
||||
const hasMetadata = (a) => this.damageTypeData[a] ? -1 : 1;
|
||||
this._sort = (a, b) => {
|
||||
this._sort = (a, b) =>
|
||||
{
|
||||
if (this.damageTypeData[a] && this.damageTypeData[b])
|
||||
return this.damageTypeData[a].order - this.damageTypeData[b].order;
|
||||
return hasMetadata(a) - hasMetadata(b);
|
||||
|
|
|
|||
|
|
@ -118,41 +118,41 @@ function DeriveModificationsFromTechnologies(techsDataArray)
|
|||
* Common definition of the XML schema for in-template modifications.
|
||||
*/
|
||||
const ModificationSchema =
|
||||
"<interleave>" +
|
||||
"<element name='Paths' a:help='Space separated value paths to modify.'>" +
|
||||
"<attribute name='datatype'>" +
|
||||
"<value>tokens</value>" +
|
||||
"</attribute>" +
|
||||
"<text/>" +
|
||||
"</element>" +
|
||||
"<element name='Affects' a:help='An array of classes to affect.'>" +
|
||||
"<attribute name='datatype'>" +
|
||||
"<value>tokens</value>" +
|
||||
"</attribute>" +
|
||||
"<text/>" +
|
||||
"</element>" +
|
||||
"<choice>" +
|
||||
"<element name='Add'>" +
|
||||
"<data type='decimal' />" +
|
||||
"</element>" +
|
||||
"<element name='Multiply'>" +
|
||||
"<data type='decimal' />" +
|
||||
"</element>" +
|
||||
"<element name='Replace'>" +
|
||||
"<interleave>" +
|
||||
"<element name='Paths' a:help='Space separated value paths to modify.'>" +
|
||||
"<attribute name='datatype'>" +
|
||||
"<value>tokens</value>" +
|
||||
"</attribute>" +
|
||||
"<text/>" +
|
||||
"</element>" +
|
||||
"</choice>" +
|
||||
"</interleave>";
|
||||
"<element name='Affects' a:help='An array of classes to affect.'>" +
|
||||
"<attribute name='datatype'>" +
|
||||
"<value>tokens</value>" +
|
||||
"</attribute>" +
|
||||
"<text/>" +
|
||||
"</element>" +
|
||||
"<choice>" +
|
||||
"<element name='Add'>" +
|
||||
"<data type='decimal' />" +
|
||||
"</element>" +
|
||||
"<element name='Multiply'>" +
|
||||
"<data type='decimal' />" +
|
||||
"</element>" +
|
||||
"<element name='Replace'>" +
|
||||
"<text/>" +
|
||||
"</element>" +
|
||||
"</choice>" +
|
||||
"</interleave>";
|
||||
|
||||
const ModificationsSchema =
|
||||
"<element name='Modifiers' a:help='List of modifiers.'>" +
|
||||
"<oneOrMore>" +
|
||||
"<element>" +
|
||||
"<anyName />" +
|
||||
ModificationSchema +
|
||||
"</element>" +
|
||||
"</oneOrMore>" +
|
||||
"</element>";
|
||||
"<element name='Modifiers' a:help='List of modifiers.'>" +
|
||||
"<oneOrMore>" +
|
||||
"<element>" +
|
||||
"<anyName />" +
|
||||
ModificationSchema +
|
||||
"</element>" +
|
||||
"</oneOrMore>" +
|
||||
"</element>";
|
||||
|
||||
/**
|
||||
* Derives a single modification (to be applied to entities) from a given XML template.
|
||||
|
|
|
|||
|
|
@ -165,7 +165,8 @@ function GetTemplateDataHelper(template, player, auraTemplates, resources, modif
|
|||
// @param {string} value_path - Route to the value within the template.
|
||||
// @param {string} mod_key - Modification key, if not the same as the value_path.
|
||||
// @param {number} default_value - A value to use if one is not specified in the template.
|
||||
const getEntityValue = function(value_path, mod_key, default_value = 0) {
|
||||
const getEntityValue = function(value_path, mod_key, default_value = 0)
|
||||
{
|
||||
return GetModifiedTemplateDataValue(template, value_path, mod_key, player, modifiers, default_value);
|
||||
};
|
||||
|
||||
|
|
@ -197,7 +198,8 @@ function GetTemplateDataHelper(template, player, auraTemplates, resources, modif
|
|||
}
|
||||
}
|
||||
|
||||
const getAttackEffects = (temp, path) => {
|
||||
const getAttackEffects = (temp, path) =>
|
||||
{
|
||||
const effects = {};
|
||||
if (temp.Capture)
|
||||
effects.Capture = getEntityValue(path + "/Capture");
|
||||
|
|
@ -220,7 +222,8 @@ function GetTemplateDataHelper(template, player, auraTemplates, resources, modif
|
|||
ret.attack = {};
|
||||
for (const type in template.Attack)
|
||||
{
|
||||
const getAttackStat = function(stat) {
|
||||
const getAttackStat = function(stat)
|
||||
{
|
||||
return getEntityValue("Attack/" + type + "/" + stat);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -237,12 +237,15 @@ var g_CampaignMenu;
|
|||
function init(initData)
|
||||
{
|
||||
let run = initData?.filename || CampaignRun.getCurrentRunFilename();
|
||||
try {
|
||||
try
|
||||
{
|
||||
run = new CampaignRun(run).load();
|
||||
if (!run.isCurrent())
|
||||
run.setCurrent();
|
||||
g_CampaignMenu = new CampaignMenu(run);
|
||||
} catch (err) {
|
||||
}
|
||||
catch(err)
|
||||
{
|
||||
error(sprintf("Error loading campaign run %s: %s.", CampaignRun.getCurrentRunFilename(), err));
|
||||
Engine.SwitchGuiPage("page_pregame.xml", {});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ class LoadModal extends AutoWatcher
|
|||
|
||||
this.selectedRun = -1;
|
||||
this.runSelection = Engine.GetGUIObjectByName("runSelection");
|
||||
this.runSelection.onSelectionChange = () => {
|
||||
this.runSelection.onSelectionChange = () =>
|
||||
{
|
||||
this.selectedRun = this.runSelection.selected;
|
||||
if (this.selectedRun === -1)
|
||||
Engine.GetGUIObjectByName('runDescription').caption = "";
|
||||
|
|
@ -71,7 +72,7 @@ class LoadModal extends AutoWatcher
|
|||
{
|
||||
out.push(new CampaignRun(name).load());
|
||||
}
|
||||
catch (err)
|
||||
catch(err)
|
||||
{
|
||||
warn(err.toString());
|
||||
out.push(new BrokenRun(name));
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ class NewCampaignModal
|
|||
Engine.GetGUIObjectByName('cancelButton').onPress = closePageCallback;
|
||||
Engine.GetGUIObjectByName('startButton').onPress = () => this.createAndStartCampaign();
|
||||
Engine.GetGUIObjectByName('runDescription').caption = translateWithContext("Campaign Template", this.template.Name);
|
||||
Engine.GetGUIObjectByName('runDescription').onTextEdit = () => {
|
||||
Engine.GetGUIObjectByName('runDescription').onTextEdit = () =>
|
||||
{
|
||||
Engine.GetGUIObjectByName('startButton').enabled = Engine.GetGUIObjectByName('runDescription').caption.length > 0;
|
||||
};
|
||||
Engine.GetGUIObjectByName('runDescription').focus();
|
||||
|
|
@ -38,7 +39,8 @@ var g_NewCampaignModal;
|
|||
|
||||
function init(campaign_template_data)
|
||||
{
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
g_NewCampaignModal = new NewCampaignModal(campaign_template_data, closePageCallback);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,12 +15,14 @@ class CampaignSetupPage extends AutoWatcher
|
|||
Engine.GetGUIObjectByName("startCampButton").onPress = () => Engine.OpenChildPage("campaigns/new_modal/page.xml", this.selectedTemplate);
|
||||
|
||||
this.campaignSelection = Engine.GetGUIObjectByName("campaignSelection");
|
||||
this.campaignSelection.onMouseLeftDoubleClickItem = () => {
|
||||
this.campaignSelection.onMouseLeftDoubleClickItem = () =>
|
||||
{
|
||||
if (this.selectedIndex === -1)
|
||||
return;
|
||||
Engine.OpenChildPage("campaigns/new_modal/page.xml", this.selectedTemplate);
|
||||
};
|
||||
this.campaignSelection.onSelectionChange = () => {
|
||||
this.campaignSelection.onSelectionChange = () =>
|
||||
{
|
||||
this.selectedIndex = this.campaignSelection.selected;
|
||||
if (this.selectedIndex !== -1)
|
||||
this.selectedTemplate = this.templates[this.selectedIndex];
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ var ObservableMixin = (Parent) => class Observable extends (() => Parent || Obje
|
|||
"enumerable": false,
|
||||
});
|
||||
return new Proxy(this, {
|
||||
"set": (target, key, value) => {
|
||||
"set": (target, key, value) =>
|
||||
{
|
||||
let old;
|
||||
let hasOld = false;
|
||||
if (Reflect.has(target, key))
|
||||
|
|
|
|||
|
|
@ -14,13 +14,15 @@ var ProfilableMixin = (Parent) => class Profilable extends (() => Parent || Obje
|
|||
{
|
||||
super();
|
||||
return new Proxy(this, {
|
||||
"get": (target, prop, receiver) => {
|
||||
"get": (target, prop, receiver) =>
|
||||
{
|
||||
let ret = Reflect.get(target, prop);
|
||||
if (typeof ret !== 'function')
|
||||
return ret;
|
||||
{
|
||||
ret = ret.bind(receiver);
|
||||
return (...a) => {
|
||||
return (...a) =>
|
||||
{
|
||||
Engine.ProfileStart(target.constructor.name + ":" + prop);
|
||||
const ret2 = ret(...a);
|
||||
Engine.ProfileStop();
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@
|
|||
function _watch(object, callback)
|
||||
{
|
||||
return new Proxy(object, {
|
||||
"get": (obj, key) => {
|
||||
"get": (obj, key) =>
|
||||
{
|
||||
return obj[key];
|
||||
},
|
||||
"set": (obj, key, value) => {
|
||||
"set": (obj, key, value) =>
|
||||
{
|
||||
obj[key] = value;
|
||||
callback(key);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ function stringifiedTeamListToPlayerData(stringifiedTeamList)
|
|||
{
|
||||
teamList = JSON.parse(unescapeText(stringifiedTeamList));
|
||||
}
|
||||
catch (e)
|
||||
catch(e)
|
||||
{
|
||||
// Ignore invalid input from remote users
|
||||
return [];
|
||||
|
|
|
|||
|
|
@ -153,7 +153,8 @@ function formatPlayerInfo(playerDataArray, playerStates)
|
|||
|
||||
// If there are teams, merge "Team N:" + playerDescriptions
|
||||
else
|
||||
teamDescription = teams.map(team => {
|
||||
teamDescription = teams.map(team =>
|
||||
{
|
||||
|
||||
const teamCaption = team == -1 ?
|
||||
translate("No Team") :
|
||||
|
|
|
|||
|
|
@ -211,7 +211,8 @@ function kickObservers(ban)
|
|||
*/
|
||||
function sortGUIDsByPlayerID()
|
||||
{
|
||||
return Object.keys(g_PlayerAssignments).sort((guidA, guidB) => {
|
||||
return Object.keys(g_PlayerAssignments).sort((guidA, guidB) =>
|
||||
{
|
||||
|
||||
const playerIdA = g_PlayerAssignments[guidA].player;
|
||||
const playerIdB = g_PlayerAssignments[guidB].player;
|
||||
|
|
|
|||
|
|
@ -201,7 +201,8 @@ function loadMapTypes()
|
|||
|
||||
function loadBiomes()
|
||||
{
|
||||
return listFiles(g_BiomesDirectory, ".json", true).filter(biomeID => biomeID != "defaultbiome").map(biomeID => {
|
||||
return listFiles(g_BiomesDirectory, ".json", true).filter(biomeID => biomeID != "defaultbiome").map(biomeID =>
|
||||
{
|
||||
const description = Engine.ReadJSONFile(g_BiomesDirectory + biomeID + ".json").Description;
|
||||
return {
|
||||
"Id": biomeID,
|
||||
|
|
@ -221,7 +222,8 @@ function loadVictoryConditions()
|
|||
{
|
||||
const subdir = "victory_conditions/";
|
||||
|
||||
const victoryConditions = listFiles(g_SettingsDirectory + subdir, ".json", false).map(victoryScriptName => {
|
||||
const victoryConditions = listFiles(g_SettingsDirectory + subdir, ".json", false).map(victoryScriptName =>
|
||||
{
|
||||
const victoryCondition = loadSettingValuesFile(subdir + victoryScriptName + ".json");
|
||||
if (victoryCondition)
|
||||
victoryCondition.Name = victoryScriptName;
|
||||
|
|
|
|||
|
|
@ -90,7 +90,8 @@ function selectNextTab(direction)
|
|||
function selectPanel(category)
|
||||
{
|
||||
g_TabCategorySelected = category;
|
||||
Engine.GetGUIObjectByName("tabButtons").children.forEach((button, j) => {
|
||||
Engine.GetGUIObjectByName("tabButtons").children.forEach((button, j) =>
|
||||
{
|
||||
button.sprite = g_TabHorizontal ?
|
||||
category == j ?
|
||||
"ModernTabHorizontalForeground" :
|
||||
|
|
|
|||
|
|
@ -57,9 +57,12 @@ function updateTimers()
|
|||
if (!t)
|
||||
continue; // an earlier timer might have cancelled this one, so skip it
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
t[1]();
|
||||
} catch (e) {
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
var stack = e.stack.trimRight().replace(/^/mg, ' '); // indent the stack trace
|
||||
error(sprintf("Error in timer: %(error)s", { "error": e }) + "\n" + stack + "\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ var g_ShowSecondaryNames = Engine.ConfigDB_GetValue("user", "gui.session.howtosh
|
|||
|
||||
function initDisplayedNames()
|
||||
{
|
||||
registerConfigChangeHandler(changes => {
|
||||
registerConfigChangeHandler(changes =>
|
||||
{
|
||||
if (changes.has("gui.session.howtoshownames"))
|
||||
updateDisplayedNames();
|
||||
});
|
||||
|
|
@ -269,7 +270,8 @@ function getStatusEffectsResistanceTooltip(resistanceTypeTemplate)
|
|||
"label": headerFont(translate("Status Effects:")),
|
||||
"details":
|
||||
Object.keys(resistanceTypeTemplate).map(
|
||||
statusEffect => {
|
||||
statusEffect =>
|
||||
{
|
||||
if (resistanceTypeTemplate[statusEffect].blockChance == 1)
|
||||
return sprintf(translate("Blocks %(name)s"), {
|
||||
"name": unitFont(translateWithContext("status effect", g_StatusEffectsMetadata.getName(statusEffect)))
|
||||
|
|
|
|||
|
|
@ -56,11 +56,13 @@ function init()
|
|||
g_TabButtonHeight,
|
||||
g_TabButtonDist,
|
||||
selectPanel,
|
||||
category => {
|
||||
category =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("creditsText").caption = g_PanelData[category].content;
|
||||
});
|
||||
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("closeButton").onPress = closePageCallback;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,8 @@ class GameSettingsController
|
|||
// and particularly could fail with mods that change persistent settings, so this is
|
||||
// difficult to fully fix from the gameSettings code.
|
||||
// Also include hotloaded data because that can also fail and having to restart isn't very useful.
|
||||
try {
|
||||
try
|
||||
{
|
||||
if (hotloadData)
|
||||
this.parseSettings(hotloadData.initAttributes, false);
|
||||
else if (g_IsController && (initData?.gameSettings || this.persistentMatchSettings.enabled))
|
||||
|
|
@ -96,7 +97,9 @@ class GameSettingsController
|
|||
if (settings)
|
||||
this.parseSettings(settings, true);
|
||||
}
|
||||
} catch (err) {
|
||||
}
|
||||
catch(err)
|
||||
{
|
||||
error("There was an error loading game settings. You may need to disable persistent match settings.");
|
||||
warn(err?.toString() ?? uneval(err));
|
||||
if (err.stack)
|
||||
|
|
@ -231,7 +234,8 @@ class GameSettingsController
|
|||
{
|
||||
if (this.layoutTimer)
|
||||
return;
|
||||
this.layoutTimer = setTimeout(() => {
|
||||
this.layoutTimer = setTimeout(() =>
|
||||
{
|
||||
for (const handler of this.updateLayoutHandlers)
|
||||
handler();
|
||||
delete this.layoutTimer;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ class GameSettingControlSlider extends GameSettingControl
|
|||
onValueChangeSuper()
|
||||
{
|
||||
if (!this.isInGuiUpdate && !this.timer)
|
||||
this.timer = setTimeout(() => {
|
||||
this.timer = setTimeout(() =>
|
||||
{
|
||||
this.onValueChange(this.slider.value);
|
||||
delete this.timer;
|
||||
}, this.Timeout);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ PlayerSettingControls.AIConfigButton = class AIConfigButton extends GameSettingC
|
|||
super(...args);
|
||||
|
||||
this.aiConfigButton = Engine.GetGUIObjectByName("aiConfigButton[" + this.playerIndex + "]");
|
||||
this.aiConfigButton.onPress = () => {
|
||||
this.aiConfigButton.onPress = () =>
|
||||
{
|
||||
this.setupWindow.pages.AIConfigPage.openPage(this.playerIndex, this.enabled);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -314,8 +314,8 @@ PlayerSettingControls.PlayerAssignment.prototype.AutocompleteOrder = 100;
|
|||
};
|
||||
|
||||
PlayerAssignmentItem.Removed.prototype.Label =
|
||||
translate("Removed");
|
||||
translate("Removed");
|
||||
|
||||
PlayerAssignmentItem.Removed.prototype.Tags =
|
||||
{ "color": "255 140 140" };
|
||||
{ "color": "255 140 140" };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ PlayerSettingControls.PlayerColor = class PlayerColor extends GameSettingControl
|
|||
this.values = g_GameSettings.playerColor.available;
|
||||
this.dropdown.list = this.values.map(color => coloredText(this.ColorIcon, rgbToGuiColor(color)));
|
||||
this.dropdown.list_data = this.values.map((color, i) => i);
|
||||
this.setSelectedValue(this.values.map((color, i) => {
|
||||
this.setSelectedValue(this.values.map((color, i) =>
|
||||
{
|
||||
if (color.r === value.r && color.g === value.g && color.b === value.b)
|
||||
return i;
|
||||
return undefined;
|
||||
|
|
|
|||
|
|
@ -120,7 +120,8 @@ GameSettingControls.MapSelection = class MapSelection extends GameSettingControl
|
|||
// which takes a few ms, but this could only be done once per frame anyways.
|
||||
// NB: this technically makes it possible to start the game without the change going through
|
||||
// but it's essentially impossible to trigger accidentally.
|
||||
const call = () => {
|
||||
const call = () =>
|
||||
{
|
||||
g_GameSettings.map.selectMap(this.values.file[itemIdx]);
|
||||
this.gameSettingsController.setNetworkInitAttributes();
|
||||
delete this.reRenderTimeout;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ GameSettingControls.PopulationCap = class PopulationCap extends GameSettingContr
|
|||
{
|
||||
const popCap = g_GameSettings.population.currentData.Options.List[this.dropdown.hovered];
|
||||
const nbPlayers = g_GameSettings.playerCount.nbPlayers;
|
||||
const nbTeams = g_GameSettings.playerTeam.values.reduce((teamList, team) => {
|
||||
const nbTeams = g_GameSettings.playerTeam.values.reduce((teamList, team) =>
|
||||
{
|
||||
if (!teamList.includes(team) || team == -1)
|
||||
teamList.push(team);
|
||||
return teamList;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ const cancelTag = Symbol("cancelTag");
|
|||
*/
|
||||
function cancelOr(costumPromise)
|
||||
{
|
||||
return Promise.race([costumPromise, new Promise(resolve => {
|
||||
return Promise.race([costumPromise, new Promise(resolve =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("cancelButton").onPress = resolve.bind(undefined, cancelTag);
|
||||
})]);
|
||||
}
|
||||
|
|
@ -42,7 +43,8 @@ async function waitOnEvent(loadSavedGame, joinFromLobby)
|
|||
{
|
||||
if (!joinFromLobby)
|
||||
{
|
||||
const continueResult = await cancelOr(new Promise(resolve => {
|
||||
const continueResult = await cancelOr(new Promise(resolve =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("continueButton").onPress = resolve;
|
||||
}));
|
||||
if (continueResult === cancelTag)
|
||||
|
|
@ -55,7 +57,7 @@ async function waitOnEvent(loadSavedGame, joinFromLobby)
|
|||
{
|
||||
confirmSetup(loadSavedGame);
|
||||
}
|
||||
catch (e)
|
||||
catch(e)
|
||||
{
|
||||
if (cancelSetup())
|
||||
return;
|
||||
|
|
@ -64,7 +66,8 @@ async function waitOnEvent(loadSavedGame, joinFromLobby)
|
|||
}
|
||||
while (true)
|
||||
{
|
||||
const tickResult = await cancelOr(new Promise(resolve => {
|
||||
const tickResult = await cancelOr(new Promise(resolve =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("multiplayerPages").onTick = resolve;
|
||||
}));
|
||||
if (tickResult === cancelTag || await onTick(loadSavedGame))
|
||||
|
|
@ -92,7 +95,8 @@ async function init(attribs)
|
|||
{
|
||||
g_ServerName = attribs.name;
|
||||
switchSetupPage("pagePassword");
|
||||
const passwordResult = await cancelOr(new Promise(resolve => {
|
||||
const passwordResult = await cancelOr(new Promise(resolve =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("confirmPasswordButton").onPress = resolve;
|
||||
}));
|
||||
if (passwordResult === cancelTag)
|
||||
|
|
@ -104,7 +108,7 @@ async function init(attribs)
|
|||
attribs.hasPassword ? Engine.GetGUIObjectByName("clientPassword").caption : "");
|
||||
switchSetupPage("pageConnecting");
|
||||
}
|
||||
catch (e)
|
||||
catch(e)
|
||||
{
|
||||
if (cancelSetup())
|
||||
return;
|
||||
|
|
@ -439,7 +443,7 @@ function startHost(playername, servername, port, password, loadSavedGame)
|
|||
Engine.StartNetworkHost(playername + (g_UserRating ? " (" + g_UserRating + ")" : ""), port,
|
||||
password, loadSavedGame, true);
|
||||
}
|
||||
catch (e)
|
||||
catch(e)
|
||||
{
|
||||
messageBox(
|
||||
400, 200,
|
||||
|
|
@ -465,7 +469,7 @@ function startJoin(playername, ip, port)
|
|||
{
|
||||
Engine.StartNetworkJoin(playername, ip, port, true);
|
||||
}
|
||||
catch (e)
|
||||
catch(e)
|
||||
{
|
||||
messageBox(
|
||||
400, 200,
|
||||
|
|
@ -507,7 +511,7 @@ function startJoinFromLobby(playername, hostJID, password)
|
|||
{
|
||||
Engine.StartNetworkJoinLobby(playername + (g_UserRating ? " (" + g_UserRating + ")" : ""), hostJID, password);
|
||||
}
|
||||
catch (e)
|
||||
catch(e)
|
||||
{
|
||||
messageBox(
|
||||
400, 200,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ class HotkeyMetadata
|
|||
}
|
||||
// Sort categories (JS objects are (in this case) sorted by insertion order).
|
||||
this.categories = {};
|
||||
const keys = Object.keys(categories).sort((a, b) => {
|
||||
const keys = Object.keys(categories).sort((a, b) =>
|
||||
{
|
||||
if (a === this.DEFAULT_CATEGORY || b === this.DEFAULT_CATEGORY)
|
||||
return a === this.DEFAULT_CATEGORY ? 1 : -1;
|
||||
if (categories[a].order === undefined || categories[b].order === undefined)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ class HotkeyPicker
|
|||
this.setupCombinations();
|
||||
this.render();
|
||||
|
||||
Engine.GetGUIObjectByName("hotkeyPickerReset").onPress = () => {
|
||||
Engine.GetGUIObjectByName("hotkeyPickerReset").onPress = () =>
|
||||
{
|
||||
// This is a bit "using a bazooka to kill a fly"
|
||||
Engine.ConfigDB_RemoveValueAndSave("user", "hotkey." + this.name);
|
||||
Engine.ReloadHotkeys();
|
||||
|
|
@ -37,10 +38,12 @@ class HotkeyPicker
|
|||
this.setupCombinations();
|
||||
this.render();
|
||||
};
|
||||
Engine.GetGUIObjectByName("hotkeyPickerCancel").onPress = () => {
|
||||
Engine.GetGUIObjectByName("hotkeyPickerCancel").onPress = () =>
|
||||
{
|
||||
onClose(this, false);
|
||||
};
|
||||
Engine.GetGUIObjectByName("hotkeyPickerSave").onPress = () => {
|
||||
Engine.GetGUIObjectByName("hotkeyPickerSave").onPress = () =>
|
||||
{
|
||||
onClose(this, true);
|
||||
};
|
||||
}
|
||||
|
|
@ -61,24 +64,28 @@ class HotkeyPicker
|
|||
const input = Engine.GetGUIObjectByName("combMapping[" + i + "]");
|
||||
|
||||
const picker = Engine.GetGUIObjectByName("picker[" + i + "]");
|
||||
Engine.GetGUIObjectByName("combMappingBtn[" + i + "]").onPress = () => {
|
||||
Engine.GetGUIObjectByName("combMappingBtn[" + i + "]").onPress = () =>
|
||||
{
|
||||
this.enteringInput = i;
|
||||
picker.focus();
|
||||
this.render();
|
||||
};
|
||||
|
||||
picker.onKeyChange = keys => {
|
||||
picker.onKeyChange = keys =>
|
||||
{
|
||||
input.caption = (keys.length ?
|
||||
formatHotkeyCombination(keys) + translate(" (hold to register)") :
|
||||
translate("Enter new Hotkey, hold to register."));
|
||||
};
|
||||
|
||||
Engine.GetGUIObjectByName("deleteComb[" + i + "]").onPress = (j => () => {
|
||||
Engine.GetGUIObjectByName("deleteComb[" + i + "]").onPress = (j => () =>
|
||||
{
|
||||
this.combinations[j] = [];
|
||||
this.render();
|
||||
})(i);
|
||||
|
||||
picker.onCombination = (j => keys => {
|
||||
picker.onCombination = (j => keys =>
|
||||
{
|
||||
this.combinations[j] = keys;
|
||||
this.enteringInput = -1;
|
||||
picker.blur();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ class HotkeysPage
|
|||
{
|
||||
this.metadata = metadata;
|
||||
|
||||
Engine.GetGUIObjectByName("hotkeyList").onMouseLeftDoubleClickItem = () => {
|
||||
Engine.GetGUIObjectByName("hotkeyList").onMouseLeftDoubleClickItem = () =>
|
||||
{
|
||||
const idx = Engine.GetGUIObjectByName("hotkeyList").selected;
|
||||
const picker = new HotkeyPicker(
|
||||
this.metadata,
|
||||
|
|
@ -25,7 +26,8 @@ class HotkeysPage
|
|||
|
||||
Engine.GetGUIObjectByName("hotkeyClose").onPress = closePageCallback;
|
||||
Engine.GetGUIObjectByName("hotkeyReset").onPress = () => this.resetUserHotkeys();
|
||||
this.saveButton.onPress = () => {
|
||||
this.saveButton.onPress = () =>
|
||||
{
|
||||
this.saveUserHotkeys();
|
||||
this.saveButton.enabled = false;
|
||||
};
|
||||
|
|
@ -55,7 +57,8 @@ class HotkeysPage
|
|||
categories[this.metadata.DEFAULT_CATEGORY].hotkeys.push(hotkeyName);
|
||||
}
|
||||
for (const cat in categories)
|
||||
categories[cat].hotkeys.sort((a, b) => {
|
||||
categories[cat].hotkeys.sort((a, b) =>
|
||||
{
|
||||
if (!this.metadata.hotkeys[a] || !this.metadata.hotkeys[b])
|
||||
return !this.metadata.hotkeys[a] ? 1 : -1;
|
||||
return this.metadata.hotkeys[a].order - this.metadata.hotkeys[b].order;
|
||||
|
|
@ -89,7 +92,8 @@ class HotkeysPage
|
|||
hotkeys = this.categories[dropdown.list_data[dropdown.selected]].hotkeys;
|
||||
else
|
||||
hotkeys = Object.values(this.categories).map(x => x.hotkeys).flat();
|
||||
hotkeys = hotkeys.filter(x => {
|
||||
hotkeys = hotkeys.filter(x =>
|
||||
{
|
||||
return x.indexOf(textFilter) !== -1 ||
|
||||
translateWithContext("hotkey metadata", this.metadata.hotkeys[x]?.name || x).toLowerCase().indexOf(textFilter) !== -1;
|
||||
});
|
||||
|
|
@ -151,7 +155,8 @@ class HotkeysPage
|
|||
return;
|
||||
|
||||
for (const cat in this.categories)
|
||||
this.categories[cat].hotkeys.forEach((name) => {
|
||||
this.categories[cat].hotkeys.forEach((name) =>
|
||||
{
|
||||
Engine.ConfigDB_RemoveValue("user", "hotkey." + name);
|
||||
});
|
||||
Engine.ConfigDB_SaveChanges("user");
|
||||
|
|
@ -181,7 +186,8 @@ class HotkeysPage
|
|||
|
||||
function init()
|
||||
{
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
// FIXME: There are proposals to remove init and allowing to specify
|
||||
// controller classes in the gui xml, therefore leave it as a class and
|
||||
// suppress the warning.
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ class SavegameDeleter
|
|||
onSelectionChange(gameID, metadata, label)
|
||||
{
|
||||
this.deleteGameButton.enabled = !!metadata;
|
||||
this.deleteGameButton.onPress = () => {
|
||||
this.deleteGameButton.onPress = () =>
|
||||
{
|
||||
this.deleteGame(gameID, label);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ class SavegameList
|
|||
|
||||
this.gameSelection.onSelectionColumnChange = () => { this.updateSavegameList(); };
|
||||
this.gameSelection.onMouseLeftDoubleClickItem = () => { this.confirmButton.onPress(); };
|
||||
this.gameSelection.onSelectionChange = () => {
|
||||
this.gameSelection.onSelectionChange = () =>
|
||||
{
|
||||
const gameId = this.gameSelection.list_data[this.gameSelection.selected];
|
||||
const metadata = this.savedGamesMetadata[this.gameSelection.selected];
|
||||
const label = this.generateSavegameLabel(metadata, engineInfo);
|
||||
|
|
@ -74,7 +75,8 @@ class SavegameList
|
|||
const engineInfo = Engine.GetEngineInfo();
|
||||
|
||||
if (this.compatibilityFilter.checked)
|
||||
savedGames = savedGames.filter(game => {
|
||||
savedGames = savedGames.filter(game =>
|
||||
{
|
||||
return this.isCompatibleSavegame(game.metadata, engineInfo) &&
|
||||
this.campaignFilter(game.metadata, this.campaignRun);
|
||||
});
|
||||
|
|
@ -88,7 +90,8 @@ class SavegameList
|
|||
const selectedGameId = this.gameSelection.list_data[this.gameSelection.selected];
|
||||
|
||||
// Save metadata for the detailed view
|
||||
this.savedGamesMetadata = savedGames.map(game => {
|
||||
this.savedGamesMetadata = savedGames.map(game =>
|
||||
{
|
||||
game.metadata.id = game.id;
|
||||
return game.metadata;
|
||||
});
|
||||
|
|
@ -96,7 +99,8 @@ class SavegameList
|
|||
const sortKey = this.gameSelection.selected_column;
|
||||
const sortOrder = this.gameSelection.selected_column_order;
|
||||
|
||||
this.savedGamesMetadata = this.savedGamesMetadata.sort((a, b) => {
|
||||
this.savedGamesMetadata = this.savedGamesMetadata.sort((a, b) =>
|
||||
{
|
||||
let cmpA, cmpB;
|
||||
switch (sortKey)
|
||||
{
|
||||
|
|
@ -128,7 +132,8 @@ class SavegameList
|
|||
return 0;
|
||||
});
|
||||
|
||||
let list = this.savedGamesMetadata.map(metadata => {
|
||||
let list = this.savedGamesMetadata.map(metadata =>
|
||||
{
|
||||
const isCompatible = this.isCompatibleSavegame(metadata, engineInfo) &&
|
||||
this.campaignFilter(metadata, this.campaignRun);
|
||||
// Backwards compatibility for pre-A25 savegames
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ class SavegameLoader
|
|||
onSelectionChange(gameID, metadata, label)
|
||||
{
|
||||
this.confirmButton.enabled = !!metadata;
|
||||
this.confirmButton.onPress = () => {
|
||||
this.confirmButton.onPress = () =>
|
||||
{
|
||||
this.loadGame(gameID, metadata);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ var g_SavegamePage;
|
|||
|
||||
function init(data)
|
||||
{
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
g_SavegamePage = new SavegamePage(data, closePageCallback);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ class SavegameWriter
|
|||
this.closePageCallback = closePageCallback;
|
||||
this.savedGameData = savedGameData;
|
||||
|
||||
const saveNew = () => {
|
||||
const saveNew = () =>
|
||||
{
|
||||
this.saveGame();
|
||||
};
|
||||
|
||||
|
|
@ -21,7 +22,8 @@ class SavegameWriter
|
|||
this.saveGameDesc.hidden = false;
|
||||
this.saveGameDesc.onPress = saveNew;
|
||||
this.descriptionChanged = false;
|
||||
this.saveGameDesc.onTextEdit = () => {
|
||||
this.saveGameDesc.onTextEdit = () =>
|
||||
{
|
||||
this.descriptionChanged = true;
|
||||
};
|
||||
}
|
||||
|
|
@ -30,7 +32,8 @@ class SavegameWriter
|
|||
{
|
||||
if (!this.descriptionChanged && metadata && typeof metadata.description === "string")
|
||||
this.saveGameDesc.caption = metadata.description;
|
||||
this.confirmButton.onPress = () => {
|
||||
this.confirmButton.onPress = () =>
|
||||
{
|
||||
this.saveGame(gameID, label);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ var AccountSettingsPage = {
|
|||
pageElement.hidden = false;
|
||||
pageElement.onTick = updateTimers;
|
||||
await Promise.race([
|
||||
new Promise(resolve => {
|
||||
new Promise(resolve =>
|
||||
{
|
||||
Engine.SetGlobalHotkey("cancel", "Press", resolve);
|
||||
Engine.GetGUIObjectByName("as_Close").onPress = resolve;
|
||||
}),
|
||||
|
|
@ -31,7 +32,8 @@ var AccountSettingsPage = {
|
|||
const changePasswordButton = Engine.GetGUIObjectByName("as_ChangePasswordBtn");
|
||||
while (true)
|
||||
{
|
||||
await new Promise(resolve => {
|
||||
await new Promise(resolve =>
|
||||
{
|
||||
changePasswordButton.onPress = resolve;
|
||||
});
|
||||
try
|
||||
|
|
@ -56,9 +58,11 @@ var AccountSettingsPage = {
|
|||
requestResult.caption = translate("Changing password…");
|
||||
const encryptedPassword = AccountSettingsPage._readAndValidatePassword(SetPasswordError);
|
||||
Engine.LobbyChangePassword(encryptedPassword);
|
||||
await new Promise((resolve, reject) => {
|
||||
await new Promise((resolve, reject) =>
|
||||
{
|
||||
xmppMessages.registerXmppMessageHandler("system", "registered", resolve);
|
||||
xmppMessages.registerXmppMessageHandler("system", "error", message => {
|
||||
xmppMessages.registerXmppMessageHandler("system", "error", message =>
|
||||
{
|
||||
reject(new SetPasswordError(message.text));
|
||||
});
|
||||
timeout = setTimeout(reject.bind(null,
|
||||
|
|
@ -70,7 +74,7 @@ var AccountSettingsPage = {
|
|||
Engine["ConfigDB_" + functionSufix]("user", "lobby.password", encryptedPassword);
|
||||
Engine.ConfigDB_SaveChanges("user");
|
||||
}
|
||||
catch (e)
|
||||
catch(e)
|
||||
{
|
||||
if (e instanceof SetPasswordError)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ class LeaderboardList
|
|||
const list_rank = [];
|
||||
const list_rating = [];
|
||||
|
||||
boardList.forEach((entry, i) => {
|
||||
boardList.forEach((entry, i) =>
|
||||
{
|
||||
list_name.push(escapeText(entry.name));
|
||||
list_rating.push(entry.rating);
|
||||
list_rank.push(i + 1);
|
||||
|
|
|
|||
|
|
@ -86,21 +86,24 @@ ChatCommandHandler.prototype.ChatCommandTags = {
|
|||
ChatCommandHandler.prototype.ChatCommands = {
|
||||
"away": {
|
||||
"description": translate("Set your state to 'Away'."),
|
||||
"handler": function(args) {
|
||||
"handler": function(args)
|
||||
{
|
||||
Engine.LobbySetPlayerPresence("away");
|
||||
return true;
|
||||
}
|
||||
},
|
||||
"back": {
|
||||
"description": translate("Set your state to 'Online'."),
|
||||
"handler": function(args) {
|
||||
"handler": function(args)
|
||||
{
|
||||
Engine.LobbySetPlayerPresence("available");
|
||||
return true;
|
||||
}
|
||||
},
|
||||
"kick": {
|
||||
"description": translate("Kick a specified user from the lobby. Usage: /kick nick reason"),
|
||||
"handler": function(args) {
|
||||
"handler": function(args)
|
||||
{
|
||||
const index = args.indexOf(" ");
|
||||
if (index == -1)
|
||||
Engine.LobbyKick(args, "");
|
||||
|
|
@ -112,7 +115,8 @@ ChatCommandHandler.prototype.ChatCommands = {
|
|||
},
|
||||
"ban": {
|
||||
"description": translate("Ban a specified user from the lobby. Usage: /ban nick reason"),
|
||||
"handler": function(args) {
|
||||
"handler": function(args)
|
||||
{
|
||||
const index = args.indexOf(" ");
|
||||
if (index == -1)
|
||||
Engine.LobbyBan(args, "");
|
||||
|
|
@ -124,7 +128,8 @@ ChatCommandHandler.prototype.ChatCommands = {
|
|||
},
|
||||
"help": {
|
||||
"description": translate("Show this help."),
|
||||
"handler": function(args) {
|
||||
"handler": function(args)
|
||||
{
|
||||
const isModerator = Engine.LobbyGetPlayerRole(g_Nickname) == "moderator";
|
||||
let txt = translate("Chat commands:");
|
||||
for (const command in this.ChatCommands)
|
||||
|
|
@ -145,21 +150,24 @@ ChatCommandHandler.prototype.ChatCommands = {
|
|||
},
|
||||
"me": {
|
||||
"description": translate("Send a chat message about yourself. Example: /me goes swimming."),
|
||||
"handler": function(args) {
|
||||
"handler": function(args)
|
||||
{
|
||||
// Translation: Chat command
|
||||
return this.argumentCount(translate("/me"), args);
|
||||
}
|
||||
},
|
||||
"say": {
|
||||
"description": translate("Send text as a chat message (even if it starts with slash). Example: /say /help is a great command."),
|
||||
"handler": function(args) {
|
||||
"handler": function(args)
|
||||
{
|
||||
// Translation: Chat command
|
||||
return this.argumentCount(translate("/say"), args);
|
||||
}
|
||||
},
|
||||
"clear": {
|
||||
"description": translate("Clear all chat scrollback."),
|
||||
"handler": function(args) {
|
||||
"handler": function(args)
|
||||
{
|
||||
this.chatMessagesPanel.clearChatMessages();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,30 +104,30 @@ ChatMessageEvents.Role = class
|
|||
};
|
||||
|
||||
ChatMessageEvents.Role.prototype.RoleStrings =
|
||||
[
|
||||
{
|
||||
"newrole": "visitor",
|
||||
"you": translate("You have been muted."),
|
||||
"nick": translate("%(nick)s has been muted.")
|
||||
},
|
||||
{
|
||||
"newrole": "moderator",
|
||||
"you": translate("You are now a moderator."),
|
||||
"nick": translate("%(nick)s is now a moderator.")
|
||||
},
|
||||
{
|
||||
"newrole": "participant",
|
||||
"oldrole": "visitor",
|
||||
"you": translate("You have been unmuted."),
|
||||
"nick": translate("%(nick)s has been unmuted.")
|
||||
},
|
||||
{
|
||||
"newrole": "participant",
|
||||
"oldrole": "moderator",
|
||||
"you": translate("You are not a moderator anymore."),
|
||||
"nick": translate("%(nick)s is not a moderator anymore.")
|
||||
}
|
||||
];
|
||||
[
|
||||
{
|
||||
"newrole": "visitor",
|
||||
"you": translate("You have been muted."),
|
||||
"nick": translate("%(nick)s has been muted.")
|
||||
},
|
||||
{
|
||||
"newrole": "moderator",
|
||||
"you": translate("You are now a moderator."),
|
||||
"nick": translate("%(nick)s is now a moderator.")
|
||||
},
|
||||
{
|
||||
"newrole": "participant",
|
||||
"oldrole": "visitor",
|
||||
"you": translate("You have been unmuted."),
|
||||
"nick": translate("%(nick)s has been unmuted.")
|
||||
},
|
||||
{
|
||||
"newrole": "participant",
|
||||
"oldrole": "moderator",
|
||||
"you": translate("You are not a moderator anymore."),
|
||||
"nick": translate("%(nick)s is not a moderator anymore.")
|
||||
}
|
||||
];
|
||||
|
||||
ChatMessageEvents.Subject = class
|
||||
{
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ class Game
|
|||
{
|
||||
this.mods = JSON.parse(newStanza.mods);
|
||||
}
|
||||
catch (e)
|
||||
catch(e)
|
||||
{
|
||||
this.mods = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,7 +125,8 @@ class GameList
|
|||
{
|
||||
Engine.ProfileStart("sortGameList");
|
||||
const sortOrder = this.gamesBox.selected_column_order;
|
||||
this.gameList.sort((game1, game2) => {
|
||||
this.gameList.sort((game1, game2) =>
|
||||
{
|
||||
if (game1.sortValue < game2.sortValue) return -sortOrder;
|
||||
if (game1.sortValue > game2.sortValue) return +sortOrder;
|
||||
return 0;
|
||||
|
|
@ -148,7 +149,8 @@ class GameList
|
|||
this.list_gameRating.length = length;
|
||||
this.list.length = length;
|
||||
|
||||
this.gameList.forEach((game, i) => {
|
||||
this.gameList.forEach((game, i) =>
|
||||
{
|
||||
|
||||
const displayData = game.displayData;
|
||||
this.list_buddy[i] = displayData.buddy || "";
|
||||
|
|
|
|||
|
|
@ -145,7 +145,8 @@ class PlayerList
|
|||
this.nickList.length = length;
|
||||
this.ratingList.length = length;
|
||||
|
||||
playerList.forEach((player, i) => {
|
||||
playerList.forEach((player, i) =>
|
||||
{
|
||||
// TODO: COList.cpp columns should support horizontal center align
|
||||
const rating = player.rating ? (" " + player.rating).substr(-5) : " -";
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ var g_LobbyHandler;
|
|||
async function init(attribs)
|
||||
{
|
||||
if (g_Settings)
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
g_LobbyHandler = new LobbyHandler(closePageCallback, attribs && attribs.dialog);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ function init()
|
|||
var languageList = Engine.GetGUIObjectByName("languageList");
|
||||
const displayLanguages = Engine.GetSupportedLocaleDisplayNames();
|
||||
const displayLanguagesData = Engine.GetSupportedLocaleBaseNames();
|
||||
languageList.list = displayLanguages.map((name, index) => {
|
||||
languageList.list = displayLanguages.map((name, index) =>
|
||||
{
|
||||
return `[locale="${displayLanguagesData[index]}"]${name}[/locale]`;
|
||||
});
|
||||
languageList.list_data = displayLanguagesData;
|
||||
|
|
@ -18,7 +19,8 @@ function init()
|
|||
var localeText = Engine.GetGUIObjectByName("localeText");
|
||||
localeText.caption = currentLocale;
|
||||
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("cancelButton").onPress = closePageCallback;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,9 +47,11 @@ function init(initData)
|
|||
// fill the script
|
||||
scriptInput.caption = Engine.GetLocaleScript(initData.locale);
|
||||
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("cancelButton").onPress = closePageCallback;
|
||||
Engine.GetGUIObjectByName("acceptButton").onPress = () => {
|
||||
Engine.GetGUIObjectByName("acceptButton").onPress = () =>
|
||||
{
|
||||
closePageCallback(applySelectedLocale());
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ function init()
|
|||
// Replace anything starting with 'hotkey.' with its hotkey.
|
||||
mainText.caption = text.replace(/hotkey.([a-z0-9_.]+)/g, (_, k) => formatHotkeyCombinations(hotkeys[k]));
|
||||
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("closeButton").onPress = closePageCallback;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ class MapBrowserPageControls
|
|||
setupButtons()
|
||||
{
|
||||
this.pickRandom = Engine.GetGUIObjectByName("mapBrowserPagePickRandom");
|
||||
this.pickRandom.onPress = () => {
|
||||
this.pickRandom.onPress = () =>
|
||||
{
|
||||
const index = randIntInclusive(0, this.gridBrowser.itemCount - 1);
|
||||
this.gridBrowser.setSelectedIndex(index);
|
||||
this.gridBrowser.goToPageOfSelected();
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ MapBrowserPageControls.prototype.MapFiltering = class
|
|||
onOpenPage()
|
||||
{
|
||||
// setTimeout avoids having the hotkey key inserted into the input text.
|
||||
setTimeout(() => {
|
||||
setTimeout(() =>
|
||||
{
|
||||
this.searchBox.control.caption = "";
|
||||
this.searchBox.focus();
|
||||
}, 0);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
const MatchSort = (function() {
|
||||
const MatchSort = (function()
|
||||
{
|
||||
const Highscore = -10E7;
|
||||
|
||||
return class
|
||||
|
|
|
|||
|
|
@ -58,7 +58,8 @@ var g_OptionType = {
|
|||
"boolean":
|
||||
{
|
||||
"configToValue": config => config == "true",
|
||||
"valueToGui": (value, control) => {
|
||||
"valueToGui": (value, control) =>
|
||||
{
|
||||
control.checked = value;
|
||||
},
|
||||
"guiToValue": control => control.checked,
|
||||
|
|
@ -67,7 +68,8 @@ var g_OptionType = {
|
|||
"string":
|
||||
{
|
||||
"configToValue": value => value,
|
||||
"valueToGui": (value, control) => {
|
||||
"valueToGui": (value, control) =>
|
||||
{
|
||||
control.caption = value;
|
||||
},
|
||||
"guiToValue": control => control.caption,
|
||||
|
|
@ -76,11 +78,14 @@ var g_OptionType = {
|
|||
"color":
|
||||
{
|
||||
"configToValue": value => value,
|
||||
"valueToGui": (value, control) => {
|
||||
"valueToGui": (value, control) =>
|
||||
{
|
||||
control.caption = value;
|
||||
},
|
||||
"initGUI": (option, control) => {
|
||||
control.children[2].onPress = async() => {
|
||||
"initGUI": (option, control) =>
|
||||
{
|
||||
control.children[2].onPress = async() =>
|
||||
{
|
||||
const color = await Engine.OpenChildPage("page_colormixer.xml", control.caption);
|
||||
|
||||
if (color != control.caption)
|
||||
|
|
@ -92,7 +97,8 @@ var g_OptionType = {
|
|||
},
|
||||
"guiToValue": control => control.caption,
|
||||
"guiSetter": "onTextEdit",
|
||||
"sanitizeValue": (value, control, option) => {
|
||||
"sanitizeValue": (value, control, option) =>
|
||||
{
|
||||
const color = guiToRgbColor(value);
|
||||
const sanitized = rgbToGuiColor(color);
|
||||
if (control)
|
||||
|
|
@ -110,12 +116,14 @@ var g_OptionType = {
|
|||
"number":
|
||||
{
|
||||
"configToValue": value => value,
|
||||
"valueToGui": (value, control) => {
|
||||
"valueToGui": (value, control) =>
|
||||
{
|
||||
control.caption = value;
|
||||
},
|
||||
"guiToValue": control => control.caption,
|
||||
"guiSetter": "onTextEdit",
|
||||
"sanitizeValue": (value, control, option) => {
|
||||
"sanitizeValue": (value, control, option) =>
|
||||
{
|
||||
const sanitized =
|
||||
Math.min(option.max !== undefined ? option.max : +Infinity,
|
||||
Math.max(option.min !== undefined ? option.min : -Infinity,
|
||||
|
|
@ -143,15 +151,18 @@ var g_OptionType = {
|
|||
"dropdown":
|
||||
{
|
||||
"configToValue": value => value,
|
||||
"valueToGui": (value, control) => {
|
||||
"valueToGui": (value, control) =>
|
||||
{
|
||||
control.selected = control.list_data.indexOf(value);
|
||||
},
|
||||
"guiToValue": control => control.list_data[control.selected],
|
||||
"guiSetter": "onSelectionChange",
|
||||
"initGUI": (option, control) => {
|
||||
"initGUI": (option, control) =>
|
||||
{
|
||||
control.list = option.list.map(e => e.label);
|
||||
control.list_data = option.list.map(e => e.value);
|
||||
control.onHoverChange = () => {
|
||||
control.onHoverChange = () =>
|
||||
{
|
||||
const item = option.list[control.hovered];
|
||||
control.tooltip = item && item.tooltip || option.tooltip;
|
||||
};
|
||||
|
|
@ -160,20 +171,24 @@ var g_OptionType = {
|
|||
"dropdownNumber":
|
||||
{
|
||||
"configToValue": value => +value,
|
||||
"valueToGui": (value, control) => {
|
||||
"valueToGui": (value, control) =>
|
||||
{
|
||||
control.selected = control.list_data.indexOf("" + value);
|
||||
},
|
||||
"guiToValue": control => +control.list_data[control.selected],
|
||||
"guiSetter": "onSelectionChange",
|
||||
"initGUI": (option, control) => {
|
||||
"initGUI": (option, control) =>
|
||||
{
|
||||
control.list = option.list.map(e => e.label);
|
||||
control.list_data = option.list.map(e => e.value);
|
||||
control.onHoverChange = () => {
|
||||
control.onHoverChange = () =>
|
||||
{
|
||||
const item = option.list[control.hovered];
|
||||
control.tooltip = item && item.tooltip || option.tooltip;
|
||||
};
|
||||
},
|
||||
"timeout": async(option, oldValue, hasChanges, newValue) => {
|
||||
"timeout": async(option, oldValue, hasChanges, newValue) =>
|
||||
{
|
||||
if (!option.timeout)
|
||||
return;
|
||||
const buttonIndex = await timedConfirmation(
|
||||
|
|
@ -191,12 +206,14 @@ var g_OptionType = {
|
|||
"slider":
|
||||
{
|
||||
"configToValue": value => +value,
|
||||
"valueToGui": (value, control) => {
|
||||
"valueToGui": (value, control) =>
|
||||
{
|
||||
control.value = +value;
|
||||
},
|
||||
"guiToValue": control => control.value,
|
||||
"guiSetter": "onValueChange",
|
||||
"initGUI": (option, control) => {
|
||||
"initGUI": (option, control) =>
|
||||
{
|
||||
control.max_value = option.max;
|
||||
control.min_value = option.min;
|
||||
},
|
||||
|
|
@ -282,7 +299,8 @@ function displayOptions()
|
|||
if (optionType.sanitizeValue)
|
||||
optionType.sanitizeValue(value, control, option);
|
||||
|
||||
control[optionType.guiSetter] = function() {
|
||||
control[optionType.guiSetter] = function()
|
||||
{
|
||||
|
||||
const newValue = optionType.guiToValue(control);
|
||||
|
||||
|
|
@ -326,8 +344,10 @@ function displayOptions()
|
|||
*/
|
||||
function enableButtons()
|
||||
{
|
||||
g_Options[g_TabCategorySelected].options.forEach((option, i) => {
|
||||
const isDependencyMet = dependency => {
|
||||
g_Options[g_TabCategorySelected].options.forEach((option, i) =>
|
||||
{
|
||||
const isDependencyMet = dependency =>
|
||||
{
|
||||
if (typeof dependency === "string")
|
||||
return Engine.ConfigDB_GetValue("user", dependency) == "true";
|
||||
else if (typeof dependency === "object")
|
||||
|
|
@ -409,8 +429,10 @@ function revertChanges()
|
|||
|
||||
async function saveChanges()
|
||||
{
|
||||
const category = Object.keys(g_Options).find(key => {
|
||||
return g_Options[key].options.some(option => {
|
||||
const category = Object.keys(g_Options).find(key =>
|
||||
{
|
||||
return g_Options[key].options.some(option =>
|
||||
{
|
||||
const optionType = g_OptionType[option.type];
|
||||
if (!optionType.sanitizeValue)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ export class MainMenuItemHandler
|
|||
|
||||
setupMenuButtons(buttons, menuItems)
|
||||
{
|
||||
buttons.forEach((button, i) => {
|
||||
buttons.forEach((button, i) =>
|
||||
{
|
||||
const item = menuItems[i];
|
||||
button.hidden = !item;
|
||||
if (button.hidden)
|
||||
|
|
@ -87,7 +88,8 @@ export class MainMenuItemHandler
|
|||
{
|
||||
const item = menuItems[i];
|
||||
if (item.onPress && item.hotkey)
|
||||
Engine.SetGlobalHotkey(item.hotkey, "Press", () => {
|
||||
Engine.SetGlobalHotkey(item.hotkey, "Press", () =>
|
||||
{
|
||||
this.closeSubmenu();
|
||||
item.onPress();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,14 +6,16 @@ export const mainMenuItems = [
|
|||
{
|
||||
"caption": translate("Manual"),
|
||||
"tooltip": translate("Open the 0 A.D. Game Manual."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.OpenChildPage("page_manual.xml");
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": translate("Tutorial"),
|
||||
"tooltip": translate("Start the introductory tutorial."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.SwitchGuiPage("page_autostart.xml", {
|
||||
"attribs": {
|
||||
"mapType": "scenario",
|
||||
|
|
@ -43,7 +45,8 @@ export const mainMenuItems = [
|
|||
"caption": translate("Structure Tree"),
|
||||
"tooltip": colorizeHotkey(translate("%(hotkey)s: View the structure tree of civilizations featured in 0 A.D."), "structree"),
|
||||
"hotkey": "structree",
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
pageLoop("page_structree.xml");
|
||||
}
|
||||
},
|
||||
|
|
@ -51,21 +54,24 @@ export const mainMenuItems = [
|
|||
"caption": translate("Civilization Overview"),
|
||||
"tooltip": colorizeHotkey(translate("%(hotkey)s: Learn about the civilizations featured in 0 A.D."), "civinfo"),
|
||||
"hotkey": "civinfo",
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
pageLoop("page_civinfo.xml");
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": translate("Catafalque Overview"),
|
||||
"tooltip": translate("Compare the bonuses of catafalques featured in 0 A.D."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.OpenChildPage("page_catafalque.xml");
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": translate("Map Overview"),
|
||||
"tooltip": translate("View the different maps featured in 0 A.D."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.OpenChildPage("page_mapbrowser.xml");
|
||||
}
|
||||
}
|
||||
|
|
@ -74,12 +80,13 @@ export const mainMenuItems = [
|
|||
{
|
||||
"caption": translate("Continue Campaign"),
|
||||
"tooltip": translate("Relive history through historical military campaigns."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Engine.SwitchGuiPage(CampaignRun.getCurrentRun().getMenuPath());
|
||||
}
|
||||
catch (err)
|
||||
catch(err)
|
||||
{
|
||||
error("Error opening campaign run:");
|
||||
error(err.toString());
|
||||
|
|
@ -94,14 +101,16 @@ export const mainMenuItems = [
|
|||
{
|
||||
"caption": translate("Matches"),
|
||||
"tooltip": translate("Start a new single-player game."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.SwitchGuiPage("page_gamesetup.xml");
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": translate("Load Game"),
|
||||
"tooltip": translate("Load a saved game."),
|
||||
"onPress": async() => {
|
||||
"onPress": async() =>
|
||||
{
|
||||
const gameId = await Engine.OpenChildPage("page_loadgame.xml");
|
||||
|
||||
if (!gameId)
|
||||
|
|
@ -131,12 +140,13 @@ export const mainMenuItems = [
|
|||
{
|
||||
"caption": translate("Continue Campaign"),
|
||||
"tooltip": translate("Relive history through historical military campaigns."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Engine.SwitchGuiPage(CampaignRun.getCurrentRun().getMenuPath());
|
||||
}
|
||||
catch (err)
|
||||
catch(err)
|
||||
{
|
||||
error("Error opening campaign run:");
|
||||
error(err.toString());
|
||||
|
|
@ -147,14 +157,16 @@ export const mainMenuItems = [
|
|||
{
|
||||
"caption": translate("New Campaign"),
|
||||
"tooltip": translate("Relive history through historical military campaigns."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.SwitchGuiPage("campaigns/setup/page.xml");
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": translate("Load Campaign"),
|
||||
"tooltip": translate("Relive history through historical military campaigns."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
// Switch instead of push, otherwise the 'continue'
|
||||
// button might remain enabled.
|
||||
// TODO: find a better solution.
|
||||
|
|
@ -164,7 +176,8 @@ export const mainMenuItems = [
|
|||
{
|
||||
"caption": translate("Replays"),
|
||||
"tooltip": translate("Playback previous games."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.SwitchGuiPage("page_replaymenu.xml", {
|
||||
"replaySelectionData": {
|
||||
"filters": {
|
||||
|
|
@ -187,7 +200,8 @@ export const mainMenuItems = [
|
|||
(Engine.StartXmppClient ? "" : translate("Launch the multiplayer lobby. \\[DISABLED BY BUILD]")),
|
||||
"enabled": () => !!Engine.StartXmppClient,
|
||||
"hotkey": "lobby",
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
if (Engine.StartXmppClient)
|
||||
Engine.OpenChildPage("page_prelobby_entrance.xml");
|
||||
}
|
||||
|
|
@ -219,7 +233,8 @@ export const mainMenuItems = [
|
|||
{
|
||||
"caption": translate("Replays"),
|
||||
"tooltip": translate("Playback previous games."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.SwitchGuiPage("page_replaymenu.xml", {
|
||||
"replaySelectionData": {
|
||||
"filters": {
|
||||
|
|
@ -238,35 +253,40 @@ export const mainMenuItems = [
|
|||
{
|
||||
"caption": translate("Options"),
|
||||
"tooltip": translate("Adjust game settings."),
|
||||
"onPress": async() => {
|
||||
"onPress": async() =>
|
||||
{
|
||||
fireConfigChangeHandlers(await Engine.OpenChildPage("page_options.xml"));
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": translate("Hotkeys"),
|
||||
"tooltip": translate("Adjust hotkeys."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.OpenChildPage("hotkeys/page_hotkeys.xml");
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": translate("Language"),
|
||||
"tooltip": translate("Choose the language of the game."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.OpenChildPage("page_locale.xml");
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": translate("Mod Selection"),
|
||||
"tooltip": translate("Select and download mods for the game."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.SwitchGuiPage("page_modmod.xml");
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": translate("Welcome Screen"),
|
||||
"tooltip": translate("Show the Welcome Screen again. Useful if you hid it by mistake."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.OpenChildPage("page_splashscreen.xml");
|
||||
}
|
||||
}
|
||||
|
|
@ -275,7 +295,8 @@ export const mainMenuItems = [
|
|||
{
|
||||
"caption": translate("Scenario Editor"),
|
||||
"tooltip": translate('Open the Atlas Scenario Editor in a new window. You can run this more reliably by starting the game with the command-line argument "-editor".'),
|
||||
"onPress": async(closePageCallback) => {
|
||||
"onPress": async(closePageCallback) =>
|
||||
{
|
||||
if (!Engine.AtlasIsAvailable())
|
||||
{
|
||||
messageBox(
|
||||
|
|
@ -298,14 +319,16 @@ export const mainMenuItems = [
|
|||
{
|
||||
"caption": translate("Credits"),
|
||||
"tooltip": translate("Show the 0 A.D. credits."),
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
Engine.OpenChildPage("page_credits.xml");
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": translate("Exit"),
|
||||
"tooltip": translate("Exit the game."),
|
||||
"onPress": async(closePageCallback) => {
|
||||
"onPress": async(closePageCallback) =>
|
||||
{
|
||||
const buttonIndex = await messageBox(
|
||||
400, 200,
|
||||
translate("Are you sure you want to quit 0 A.D.?"),
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ function initCommunityButton(communityButtons)
|
|||
{
|
||||
const buttons = Engine.GetGUIObjectByName("communityButtons").children;
|
||||
|
||||
communityButtons.forEach((buttonInfo, i) => {
|
||||
communityButtons.forEach((buttonInfo, i) =>
|
||||
{
|
||||
const button = buttons[i];
|
||||
button.hidden = false;
|
||||
for (const propertyName in buttonInfo)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ export const communityButtons = [
|
|||
"caption": translate("Website"),
|
||||
"tooltip": translate("Click to open play0ad.com in your web browser."),
|
||||
"size": "8 100%-148 50%-4 100%-116",
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
openURL("https://play0ad.com/");
|
||||
}
|
||||
},
|
||||
|
|
@ -33,7 +34,8 @@ export const communityButtons = [
|
|||
"caption": translate("Chat"),
|
||||
"tooltip": translate("Click to open the 0 A.D. IRC chat in your browser (#0ad on webchat.quakenet.org). It is run by volunteers who do all sorts of tasks, it may take a while to get your question answered. Alternatively, you can use the forum (see Website)."),
|
||||
"size": "50%+4 100%-148 100%-8 100%-116",
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
openURL("https://webchat.quakenet.org/?channels=0ad");
|
||||
}
|
||||
},
|
||||
|
|
@ -41,7 +43,8 @@ export const communityButtons = [
|
|||
"caption": translate("Report a Bug"),
|
||||
"tooltip": translate("Click to visit the 0 A.D. issue tracker to report a bug, crash, or error."),
|
||||
"size": "8 100%-112 50%-4 100%-80",
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
openURL("https://gitea.wildfiregames.com/0ad/0ad/issues");
|
||||
}
|
||||
},
|
||||
|
|
@ -49,7 +52,8 @@ export const communityButtons = [
|
|||
"caption": translateWithContext("Frequently Asked Questions", "FAQ"),
|
||||
"tooltip": translate("Click to visit the Frequently Asked Questions page in your browser."),
|
||||
"size": "50%+4 100%-112 100%-8 100%-80",
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
openURL("https://gitea.wildfiregames.com/0ad/0ad/wiki/FAQ");
|
||||
}
|
||||
},
|
||||
|
|
@ -57,7 +61,8 @@ export const communityButtons = [
|
|||
"caption": translate("Translate the Game"),
|
||||
"tooltip": translate("Click to open the 0 A.D. translate page in your browser."),
|
||||
"size": "8 100%-76 100%-8 100%-44",
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
openURL("https://gitea.wildfiregames.com/0ad/0ad/wiki/Localization");
|
||||
}
|
||||
},
|
||||
|
|
@ -65,7 +70,8 @@ export const communityButtons = [
|
|||
"caption": translate("Donate"),
|
||||
"tooltip": translate("Help with the project expenses by donating."),
|
||||
"size": "8 100%-40 100%-8 100%-8",
|
||||
"onPress": () => {
|
||||
"onPress": () =>
|
||||
{
|
||||
openURL("https://play0ad.com/community/donate/");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ export function init(data, hotloadData)
|
|||
initUserReport();
|
||||
Engine.GetGUIObjectByName("userReport").onTick = updateUserReportStatus;
|
||||
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
const mainMenuPage = new MainMenuPage(
|
||||
closePageCallback,
|
||||
data,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ var g_TermsUserReport = {
|
|||
"configPath": setStringTags(escapeText(Engine.GetUserReportConfigPath()), { "font": "sans-bold-12" })
|
||||
},
|
||||
"config": "userreport.terms",
|
||||
"callback": data => {
|
||||
"callback": data =>
|
||||
{
|
||||
setUserReportEnabled(data.accepted);
|
||||
},
|
||||
"accepted": false,
|
||||
|
|
@ -61,13 +62,15 @@ function updateUserReportButtons()
|
|||
userReportEnableButton.caption = Engine.IsUserReportEnabled() ? translate("Disable Feedback") : translate("Enable Feedback");
|
||||
userReportEnableButton.enabled = !termsFeedback;
|
||||
userReportEnableButton.tooltip = termsFeedback;
|
||||
userReportEnableButton.onPress = () => {
|
||||
userReportEnableButton.onPress = () =>
|
||||
{
|
||||
setUserReportEnabled(!Engine.IsUserReportEnabled());
|
||||
};
|
||||
|
||||
const userReportTermsButton = Engine.GetGUIObjectByName("userReportTermsButton");
|
||||
userReportTermsButton.caption = g_TermsUserReport.TermsAndConditions.title;
|
||||
userReportTermsButton.onPress = () => {
|
||||
userReportTermsButton.onPress = () =>
|
||||
{
|
||||
openTerms("TermsAndConditions");
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
var g_LobbyMessages = {
|
||||
"error": message => {
|
||||
"error": message =>
|
||||
{
|
||||
setFeedback(message.text ||
|
||||
translate("Unknown error. This usually occurs because the same IP address is not allowed to register more than one account within one hour."));
|
||||
Engine.StopXmppClient();
|
||||
},
|
||||
"disconnected": message => {
|
||||
"disconnected": message =>
|
||||
{
|
||||
setFeedback(message.reason + message.certificate_status);
|
||||
Engine.StopXmppClient();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,13 +37,15 @@ function initLobbyTerms()
|
|||
}
|
||||
};
|
||||
|
||||
Object.keys(terms).forEach((page, i) => {
|
||||
Object.keys(terms).forEach((page, i) =>
|
||||
{
|
||||
|
||||
const button = Engine.GetGUIObjectByName("termsButton[" + i + "]");
|
||||
|
||||
button.caption = terms[page].title;
|
||||
|
||||
button.onPress = () => {
|
||||
button.onPress = () =>
|
||||
{
|
||||
openTerms(page);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ function init()
|
|||
if (Engine.ConfigDB_GetValue("user", "lobby.login"))
|
||||
loginButton();
|
||||
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
Engine.GetGUIObjectByName("cancel").onPress = closePageCallback;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,7 +155,8 @@ class TemplateLoader
|
|||
production.units.push(templateName);
|
||||
}
|
||||
|
||||
const appendTechnology = (technologyName) => {
|
||||
const appendTechnology = (technologyName) =>
|
||||
{
|
||||
const technology = this.loadTechnologyTemplate(technologyName, civCode);
|
||||
if (DeriveTechnologyRequirements(technology, civCode))
|
||||
production.techs.push(technologyName);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ class TipDisplay
|
|||
else
|
||||
this.tipFilesData =
|
||||
hotloadData?.tipFilesData ||
|
||||
shuffleArray(Engine.ReadJSONFile(this.TipFilesDataFile).map(category => category.files).flat().map(tip => {
|
||||
shuffleArray(Engine.ReadJSONFile(this.TipFilesDataFile).map(category => category.files).flat().map(tip =>
|
||||
{
|
||||
tip.imageFiles = shuffleArray(tip.imageFiles);
|
||||
return tip;
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ var g_TipsPage;
|
|||
|
||||
function init(initData, hotloadData)
|
||||
{
|
||||
return new Promise(closePageCallback => {
|
||||
return new Promise(closePageCallback =>
|
||||
{
|
||||
g_TipsPage = new TipsPage(initData, hotloadData, closePageCallback);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue