mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 15:24:52 +09:00
Coerce mod settings types during data export
Use the settings prototypes to coerce any incorrectly typed mod settings to the correct type either by casting or by replacing the value with the default value from the prototype. This will fix cases where an update to a mod changes the type of ono of its defined settings.
This commit is contained in:
1 parent
c37fe0f438
commit
3cf9f96233
3 files changed
+99
-9
No files matched your search
@@ -37,6 +37,7 @@ Many thanks to the following for contributing to this release:
|
||||
- Fixed plugin events being invoked while a host connection was in an invalid state.
|
||||
- Suppresed bogus warning about event listener leak in the browser's console [#600](https://github.com/clusterio/clusterio/pull/600).
|
||||
- Fixed installer breaking on Windows after Node.js released a security fix [#614](https://github.com/clusterio/clusterio/pull/614).
|
||||
- During a data export the mod settings in mod packs will now be corrected to the type of the settings prototype if the type is incorrect.
|
||||
|
||||
Many thanks to the following for contributing to this release:
|
||||
[@Cooldude2606](https://github.com/Cooldude2606)
|
||||
|
||||
@@ -334,10 +334,11 @@ export default class ModPack {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in missing settings with their default values
|
||||
* Fill in missing and incorrect settings with their default values
|
||||
*
|
||||
* Uses the provided setting prototypes to add any missing mod settings
|
||||
* in the mod pack with the default value from the prototype.
|
||||
* Uses the provided setting prototypes to correct any missing and or
|
||||
* incorrect mod settings in the mod pack with the default value from
|
||||
* the prototype.
|
||||
*
|
||||
* @param settingPrototypes -
|
||||
* Setting prototypes exported from the game.
|
||||
@@ -360,13 +361,23 @@ export default class ModPack {
|
||||
logger.warn(`Ignoring ${prototype.name} with missing default_value`);
|
||||
continue;
|
||||
}
|
||||
if (this.settings[settingType].get(prototype.name)) {
|
||||
continue;
|
||||
let value = this.settings[settingType].get(prototype.name)?.value ?? prototype.default_value;
|
||||
const type = prototype.type;
|
||||
if (
|
||||
type === "bool-setting" && typeof value !== "boolean"
|
||||
|| type === "color-setting" && typeof value !== "object"
|
||||
|| (type === "int-setting" || type === "double-setting") && typeof value !== "number"
|
||||
) {
|
||||
value = prototype.default_value;
|
||||
}
|
||||
|
||||
let value = prototype.default_value;
|
||||
if (prototype.type === "color-setting") {
|
||||
value = libLuaTools.normalizeColor(value);
|
||||
if (type === "string-setting" && typeof value !== "string") {
|
||||
value = typeof value === "object" ? prototype.default_value : String(value ?? "");
|
||||
}
|
||||
if (type === "color-setting") {
|
||||
if (typeof value !== "object") {
|
||||
value = prototype.default_value;
|
||||
}
|
||||
value = libLuaTools.normalizeColor(value as object);
|
||||
}
|
||||
this.settings[settingType].set(prototype.name, { value });
|
||||
}
|
||||
|
||||
@@ -179,6 +179,84 @@ describe("lib/data/ModPack", function() {
|
||||
"runtime-per-user": {},
|
||||
});
|
||||
});
|
||||
it("should coerce values of the incorrect type into the correct type", function() {
|
||||
const boolDefault = true;
|
||||
const intDefault = 123;
|
||||
const doubleDefault = 1234.5;
|
||||
const stringDefault = "default";
|
||||
const colorDefault = { r: 1, g: 0, b: 1, a: 1};
|
||||
const settingDefaultValues = {
|
||||
"bool-setting": boolDefault,
|
||||
"int-setting": intDefault,
|
||||
"double-setting": doubleDefault,
|
||||
"string-setting": stringDefault,
|
||||
"color-setting": colorDefault,
|
||||
};
|
||||
const possibleValues = ["bool", "int", "double", "string", "color"];
|
||||
const settingPrototypes = {
|
||||
"bool-setting": {},
|
||||
"int-setting": {},
|
||||
"double-setting": {},
|
||||
"string-setting": {},
|
||||
"color-setting": {},
|
||||
};
|
||||
for (const [type, default_value] of Object.entries(settingDefaultValues)) {
|
||||
for (const value of possibleValues) {
|
||||
const settingName = `${type}-with-${value}-value`;
|
||||
settingPrototypes[type][settingName] = {
|
||||
type,
|
||||
name: settingName,
|
||||
setting_type: "startup",
|
||||
default_value,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const pack = new ModPack();
|
||||
const settingValues = {
|
||||
"bool": false,
|
||||
"int": 1,
|
||||
"double": 2.5,
|
||||
"string": "str",
|
||||
"color": { r: 0, g: 1, b: 0, a: 1 },
|
||||
};
|
||||
for (const type of Object.keys(settingDefaultValues)) {
|
||||
for (const [valueType, value] of Object.entries(settingValues)) {
|
||||
pack.settings.startup.set(`${type}-with-${valueType}-value`, { value });
|
||||
}
|
||||
}
|
||||
pack.fillDefaultSettings(settingPrototypes);
|
||||
assert.deepEqual(
|
||||
pack.settings["startup"],
|
||||
new Map([
|
||||
["bool-setting-with-bool-value", false],
|
||||
["bool-setting-with-int-value", boolDefault],
|
||||
["bool-setting-with-double-value", boolDefault],
|
||||
["bool-setting-with-string-value", boolDefault],
|
||||
["bool-setting-with-color-value", boolDefault],
|
||||
["int-setting-with-bool-value", intDefault],
|
||||
["int-setting-with-int-value", 1],
|
||||
["int-setting-with-double-value", 2.5],
|
||||
["int-setting-with-string-value", intDefault],
|
||||
["int-setting-with-color-value", intDefault],
|
||||
["double-setting-with-bool-value", doubleDefault],
|
||||
["double-setting-with-int-value", 1],
|
||||
["double-setting-with-double-value", 2.5],
|
||||
["double-setting-with-string-value", doubleDefault],
|
||||
["double-setting-with-color-value", doubleDefault],
|
||||
["string-setting-with-bool-value", "false"],
|
||||
["string-setting-with-int-value", "1"],
|
||||
["string-setting-with-double-value", "2.5"],
|
||||
["string-setting-with-string-value", "str"],
|
||||
["string-setting-with-color-value", stringDefault],
|
||||
["color-setting-with-bool-value", colorDefault],
|
||||
["color-setting-with-int-value", colorDefault],
|
||||
["color-setting-with-double-value", colorDefault],
|
||||
["color-setting-with-string-value", colorDefault],
|
||||
["color-setting-with-color-value", { r: 0, g: 1, b: 0, a: 1}],
|
||||
].map(([k, v]) => [k, { value: v }])),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe(".fromModPackString()", function() {
|
||||
|
||||
Reference in new issue
Block a user