From ebf65363740788fcb1449441489ded1f74b0e3bd Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Mon, 26 Feb 2024 22:03:47 -0600 Subject: [PATCH 01/43] Change style of mod upload button on drag and drop --- packages/web_ui/src/components/ModsPage.tsx | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/web_ui/src/components/ModsPage.tsx b/packages/web_ui/src/components/ModsPage.tsx index 0e5541ae..e380bcb5 100644 --- a/packages/web_ui/src/components/ModsPage.tsx +++ b/packages/web_ui/src/components/ModsPage.tsx @@ -17,6 +17,7 @@ import PageLayout from "./PageLayout"; import PluginExtra from "./PluginExtra"; import SectionHeader from "./SectionHeader"; import ModDetails from "./ModDetails"; +import { InboxOutlined } from "@ant-design/icons"; const strcmp = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }).compare; @@ -131,6 +132,7 @@ export default function ModsPage() { let navigate = useNavigate(); let [mods] = useMods(); let [modPacks] = useModPacks(); + const [isDroppingFile, setIsDroppingFile] = useState(false); function actions(mod: lib.ModInfo) { return @@ -173,11 +175,26 @@ export default function ModsPage() { accept=".zip" multiple headers={{ - "X-Access-Token": control.connector.token||"", + "X-Access-Token": control.connector.token || "", }} action={`${webRoot}api/upload-mod`} > - + ; } From b70feb37f26efb6955cd066deb6fcf0c232a1050 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Mon, 26 Feb 2024 22:04:37 -0600 Subject: [PATCH 02/43] Show table overlay when dragging and dropping saves/mods --- packages/web_ui/src/components/ModsPage.tsx | 170 +++++++++++++------ packages/web_ui/src/components/SavesList.tsx | 69 +++++++- packages/web_ui/src/style.css | 2 + 3 files changed, 183 insertions(+), 58 deletions(-) diff --git a/packages/web_ui/src/components/ModsPage.tsx b/packages/web_ui/src/components/ModsPage.tsx index e380bcb5..7b2e85ed 100644 --- a/packages/web_ui/src/components/ModsPage.tsx +++ b/packages/web_ui/src/components/ModsPage.tsx @@ -56,11 +56,13 @@ function ImportModPackButton() { name="string" rules={[ { required: true }, - { async validator(rule, value) { - if (value) { - lib.ModPack.fromModPackString(value); - } - }}, + { + async validator(rule, value) { + if (value) { + lib.ModPack.fromModPackString(value); + } + }, + }, ]} > @@ -236,54 +238,118 @@ export default function ModsPage() { })} /> - ( - strcmp(a.name, b.name) || a.integerVersion - b.integerVersion - ), - }, - { - title: "Version", - key: "version", - align: "right", - render: (_, mod) => <> - {`${mod.version} `} - {`/ ${mod.factorioVersion}`} - , - }, - { - title: "Filename", - dataIndex: "filename", - responsive: ["xl"], - sorter: (a, b) => strcmp(a.filename, b.filename), - }, - { - title: "Size", - key: "size", - responsive: ["lg"], - render: (_, mod) => lib.formatBytes(mod.size), - align: "right", - sorter: (a, b) => a.size - b.size, - }, - { - title: "Action", - key: "action", - responsive: ["lg"], - render: (_, mod) => actions(mod), - }, - ]} - expandable={{ - expandedRowRender: (mod: lib.ModInfo) => , - expandedRowClassName: () => "no-expanded-padding", + + mod.id} - /> + action={`${webRoot}api/upload-mod`} + showUploadList={false} + > +
{ + setIsDroppingFile(true); + }} + onDragLeave={e => { + if ((e.currentTarget as Node).contains(e.relatedTarget as Node)) { + return; + } + setIsDroppingFile(false); + }} + onDrop={e => setIsDroppingFile(false)} + > +
+
+ +

+ Drop to upload +

+
+
+
( + strcmp(a.name, b.name) || a.integerVersion - b.integerVersion + ), + }, + { + title: "Version", + key: "version", + align: "right", + render: (_, mod) => <> + {`${mod.version} `} + {`/ ${mod.factorioVersion}`} + , + }, + { + title: "Filename", + dataIndex: "filename", + responsive: ["xl"], + sorter: (a, b) => strcmp(a.filename, b.filename), + }, + { + title: "Size", + key: "size", + responsive: ["lg"], + render: (_, mod) => lib.formatBytes(mod.size), + align: "right", + sorter: (a, b) => a.size - b.size, + }, + { + title: "Action", + key: "action", + responsive: ["lg"], + render: (_, mod) => actions(mod), + }, + ]} + expandable={{ + expandedRowRender: (mod: lib.ModInfo) => , + expandedRowClassName: () => "no-expanded-padding", + }} + dataSource={[...mods.values()]} + pagination={false} + rowKey={mod => mod.id} + /> + + ; } diff --git a/packages/web_ui/src/components/SavesList.tsx b/packages/web_ui/src/components/SavesList.tsx index 92ce287c..66f4f78d 100644 --- a/packages/web_ui/src/components/SavesList.tsx +++ b/packages/web_ui/src/components/SavesList.tsx @@ -15,6 +15,7 @@ import SectionHeader from "./SectionHeader"; import { useInstances } from "../model/instance"; import { useSavesOfInstance } from "../model/saves"; import { notifyErrorHandler } from "../util/notify"; +import { InboxOutlined } from "@ant-design/icons"; type ModalProps = { @@ -150,7 +151,7 @@ function TransferModal(props: ModalProps) { autoFocus showSearch filterOption={(input, option) => ( - (option?.title.toLowerCase().indexOf(input.toLowerCase())??-1) >= 0 + (option?.title.toLowerCase().indexOf(input.toLowerCase()) ?? -1) >= 0 )} > {[...instances.values()].filter( @@ -204,6 +205,7 @@ export default function SavesList(props: { instance: lib.InstanceDetails }) { let [saves] = useSavesOfInstance(props.instance.id); let [starting, setStarting] = useState(false); let [uploadingFiles, setUploadingFiles] = useState([]); + const [isDroppingFile, setIsDroppingFile] = useState(false); let hostOffline = ["unassigned", "unknown"].includes(props.instance.status!); const saveTable =
<> {save.name} - {save.loaded && } - {save.loadByDefault && } + {save.loaded && } + {save.loadByDefault && } , sorter: (a, b) => a.name.localeCompare(b.name), }, @@ -240,7 +242,7 @@ export default function SavesList(props: { instance: lib.InstanceDetails }) { expandable={{ columnWidth: 33, expandRowByClick: true, - expandedRowRender: save => + expandedRowRender: save => {account.hasPermission("core.instance.start") && + ; } @@ -256,50 +241,8 @@ export default function ModsPage() { position: "relative", zIndex: "1010", }} - onDragEnter={e => { - setIsDroppingFile(true); - }} - onDragLeave={e => { - if ((e.currentTarget as Node).contains(e.relatedTarget as Node)) { - return; - } - setIsDroppingFile(false); - }} - onDrop={e => setIsDroppingFile(false)} > -
-
- -

- Drop to upload -

-
-
+
([]); - const [isDroppingFile, setIsDroppingFile] = useState(false); let hostOffline = ["unassigned", "unknown"].includes(props.instance.status!); const saveTable =
{account.hasPermission("core.instance.save.upload") && - + + Upload save + } {account.hasPermission("core.instance.save.create") && } } /> @@ -360,55 +362,8 @@ export default function SavesList(props: { instance: lib.InstanceDetails }) { position: "relative", zIndex: "1010", }} - onDragEnter={e => { - setIsDroppingFile(true); - }} - onDragLeave={e => { - if ((e.currentTarget as Node).contains(e.relatedTarget as Node)) { - return; - } - setIsDroppingFile(false); - }} - onDrop={e => setIsDroppingFile(false)} > -
-
- -

- Drop to upload -

-
-
+ {saveTable} diff --git a/packages/web_ui/src/components/SiteLayout.tsx b/packages/web_ui/src/components/SiteLayout.tsx index 07a995d1..31b0374f 100644 --- a/packages/web_ui/src/components/SiteLayout.tsx +++ b/packages/web_ui/src/components/SiteLayout.tsx @@ -9,16 +9,18 @@ import ErrorBoundary from "./ErrorBoundary"; import ErrorPage from "./ErrorPage"; import ControlContext from "./ControlContext"; import { pages } from "../pages"; +import { DraggingContext } from "../model/is_dragging"; const { Header, Sider } = Layout; export default function SiteLayout() { let navigate = useNavigate(); - let [currentSidebarPath, setCurrentSidebarPath] = useState(null); + let [currentSidebarPath, setCurrentSidebarPath] = useState(null); let account = useAccount(); let plugins = useContext(ControlContext).plugins; + const [dragging, setDragging] = useState(0); - function SetSidebar(props: { path: string|null }) { + function SetSidebar(props: { path: string | null }) { useEffect(() => { setCurrentSidebarPath(props.path); }); @@ -26,7 +28,7 @@ export default function SiteLayout() { } let accountMenuProps: MenuProps = { - onClick: ({ key }: {key:string}) => { + onClick: ({ key }: { key: string }) => { if (key === "user") { navigate(`/users/${account.name}/view`); } else if (key === "logOut") { @@ -72,59 +74,76 @@ export default function SiteLayout() { menuItems.push({ type: "group", label: name, children: group, key: name }); } - return -
-
- Clusterio - { webUiPackage.version } - - - - -
- - + // Prevent issues with event ordering + let dragChange = 0; + function setDraggingProxy(value: number) { + dragChange += value; + setDragging(dragging + dragChange); + } + + return setDraggingProxy(1)} + onDragLeave={() => setDraggingProxy(-1)} + // Reset dragging state when dropped + onDrop={() => setDragging(0)} + // Allow entire document to be a drag target + onDragOver={(e) => e.preventDefault()} + > + 0}> +
+
+ Clusterio + {webUiPackage.version} navigate(key)} - items={menuItems} + theme="dark" + mode="horizontal" + defaultSelectedKeys={["1"]} + items={[{ label: "Dashboard", key: "1" }]} /> - - - - {combinedPages.map(({path, sidebarPath, content}) => - - - {content} - - } - />)} - } /> - + + + +
+ + + navigate(key)} + items={menuItems} + /> + + + + {combinedPages.map(({ path, sidebarPath, content }) => + + + {content} + + } + />)} + } /> + + - + ; } diff --git a/packages/web_ui/src/components/UploadButton.tsx b/packages/web_ui/src/components/UploadButton.tsx new file mode 100644 index 00000000..c6c324a9 --- /dev/null +++ b/packages/web_ui/src/components/UploadButton.tsx @@ -0,0 +1,20 @@ +import { useContext } from "react"; +import { Button } from "antd"; +import { InboxOutlined, UploadOutlined } from "@ant-design/icons"; + +import { DraggingContext } from "../model/is_dragging"; + +export default function UploadButton(props: React.ComponentProps) { + const isDroppingFile = useContext(DraggingContext); + return ; +} diff --git a/packages/web_ui/src/model/is_dragging.ts b/packages/web_ui/src/model/is_dragging.ts new file mode 100644 index 00000000..652878e2 --- /dev/null +++ b/packages/web_ui/src/model/is_dragging.ts @@ -0,0 +1,3 @@ +import { createContext } from "react"; + +export const DraggingContext = createContext(false); From 78a9f73de8b94e0ce4bf5858b5f54fa7fddb1ace Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Sun, 5 May 2024 00:18:36 +0200 Subject: [PATCH 04/43] Installer promt for http port Resolves #564 --- packages/create/create.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/create/create.js b/packages/create/create.js index 3126f0dc..c6c0d094 100755 --- a/packages/create/create.js +++ b/packages/create/create.js @@ -551,6 +551,25 @@ async function inquirerMissingArgs(args) { }, }, ], answers); + + if (args.httpPort) { answers.httpPort = args.httpPort; } + answers = await inquirer.prompt([ + { + type: "input", + name: "httpPort", + message: "HTTP port to listen on", + default: 8080, + validate: input => { + if (!input) { + return "May not be empty"; + } + if (!Number.isInteger(Number(input))) { + return "Must be a number"; + } + return true; + }, + }, + ], answers); } if (answers.mode === "host") { @@ -775,6 +794,9 @@ async function main() { .option("admin", { nargs: 1, describe: "Admin account name [standalone/controller]", type: "string", }) + .option("http-port", { + nargs: 1, describe: "HTTP port to listen on [standalone/controller]", type: "number", + }) .option("host-name", { nargs: 1, describe: "Host name [host]", type: "string", }) @@ -854,6 +876,7 @@ async function main() { if (["standalone", "controller"].includes(answers.mode)) { logger.info("Setting up controller"); await execController(["bootstrap", "create-admin", answers.admin]); + await execController(["config", "set", "controller.http_port", answers.httpPort]); let result = await execController(["bootstrap", "generate-user-token", answers.admin]); adminToken = result.stdout.split("\n").slice(-2)[0]; } @@ -868,6 +891,8 @@ async function main() { result = await execController(["bootstrap", "generate-host-token", hostId]); let hostToken = result.stdout.split("\n").slice(-2)[0]; + // Default to localhost on correct port for host in standalone mode + await execHost(["config", "set", "host.controller_url", `http://localhost:${answers.httpPort}`]); await execHost(["config", "set", "host.controller_token", hostToken]); await execHost(["config", "set", "host.public_address", answers.publicAddress]); await execHost(["config", "set", "host.factorio_directory", answers.factorioDir]); From e405f09f3319119ee8de99674fe6008b682d43a5 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Sun, 5 May 2024 01:44:37 +0200 Subject: [PATCH 05/43] Add integration tests for create --- test/integration/create.js | 65 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 test/integration/create.js diff --git a/test/integration/create.js b/test/integration/create.js new file mode 100644 index 00000000..850b644b --- /dev/null +++ b/test/integration/create.js @@ -0,0 +1,65 @@ +"use strict"; +const assert = require("assert").strict; +const fs = require("fs-extra"); +const jwt = require("jsonwebtoken"); +const path = require("path"); +const events = require("events"); +const phin = require("phin"); +const child_process = require("child_process"); +const util = require("util"); + +const cwd = path.join("temp", "test_integration"); + +async function exec(command, options = {}) { + // Uncomment to show commands run in tests + // console.log(command); + options = { cwd, ...options }; + return await util.promisify(child_process.exec)(command, options); +} + +describe("Integration of create tool", function () { + before(async function () { + await fs.ensureDir(cwd); + }); + it("should create a new standalone installation", async function () { + await exec([ + "node ../../packages/create", + "--mode standalone", + "--admin Danielv123", + "--http-port 8099", + "--host-name localhost", + "--public-address localhost", + "--factorio-dir test/factorio", + "--plugins --", + ].join(" ")); + + // Check that the generated config is correct + const controllerConfig = await fs.readJson(path.join(cwd, "config-controller.json")); + assert.equal(controllerConfig["controller.http_port"], 8099); + + const hostConfig = await fs.readJson(path.join(cwd, "config-host.json")); + assert.equal(hostConfig["host.name"], "local"); + assert.equal(hostConfig["host.public_address"], "localhost"); + assert.equal(hostConfig["host.factorio_directory"], "test/factorio"); + assert.equal(hostConfig["host.controller_url"], "http://localhost:8099"); + }).timeout(60000); + it("should create a new controller installation", async function () { + await exec([ + "node ../../packages/create", + "--mode controller", + "--admin Danielv123", + "--http-port 8099", + "--public-address localhost", + "--plugins --", + ].join(" ")); + + // Check that the generated config is correct + const controllerConfig = await fs.readJson(path.join(cwd, "config-controller.json")); + assert.equal(controllerConfig["controller.http_port"], 8099); + + await assert.rejects(fs.readJson(path.join(cwd, "config-host.json"))); + }).timeout(60000); + after(async function () { + await fs.remove(path.join(cwd, "temp/test_integration")); + }); +}); From b27256421dff433bfbec2a96fc29d1051dec8dc9 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Sun, 5 May 2024 02:00:16 +0200 Subject: [PATCH 06/43] Fixed tests --- test/integration/create.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/integration/create.js b/test/integration/create.js index 850b644b..62503dae 100644 --- a/test/integration/create.js +++ b/test/integration/create.js @@ -18,9 +18,12 @@ async function exec(command, options = {}) { } describe("Integration of create tool", function () { - before(async function () { + beforeEach(async function () { await fs.ensureDir(cwd); }); + afterEach(async function () { + await fs.remove(cwd); + }); it("should create a new standalone installation", async function () { await exec([ "node ../../packages/create", @@ -42,7 +45,7 @@ describe("Integration of create tool", function () { assert.equal(hostConfig["host.public_address"], "localhost"); assert.equal(hostConfig["host.factorio_directory"], "test/factorio"); assert.equal(hostConfig["host.controller_url"], "http://localhost:8099"); - }).timeout(60000); + }).timeout(1200000); it("should create a new controller installation", async function () { await exec([ "node ../../packages/create", @@ -59,7 +62,4 @@ describe("Integration of create tool", function () { await assert.rejects(fs.readJson(path.join(cwd, "config-host.json"))); }).timeout(60000); - after(async function () { - await fs.remove(path.join(cwd, "temp/test_integration")); - }); }); From 131e45e10a235c6dc738a0d3cae62422c5ea70af Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Sun, 5 May 2024 02:24:57 +0200 Subject: [PATCH 07/43] Skip create integration tests Tests are skipped because they are really slow and fail in CI --- test/integration/create.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/integration/create.js b/test/integration/create.js index 62503dae..164e8d48 100644 --- a/test/integration/create.js +++ b/test/integration/create.js @@ -25,6 +25,7 @@ describe("Integration of create tool", function () { await fs.remove(cwd); }); it("should create a new standalone installation", async function () { + this.skip(); await exec([ "node ../../packages/create", "--mode standalone", @@ -47,6 +48,7 @@ describe("Integration of create tool", function () { assert.equal(hostConfig["host.controller_url"], "http://localhost:8099"); }).timeout(1200000); it("should create a new controller installation", async function () { + this.skip(); await exec([ "node ../../packages/create", "--mode controller", From b9e9a754b83852a88f42d29a06d35ea500807523 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Wed, 8 May 2024 20:38:05 +0100 Subject: [PATCH 08/43] Change all workspace versions to workspace:* (#621) --- package.json | 1 + packages/controller/package.json | 4 ++-- packages/create/templates/common/package.json | 6 +++--- packages/ctl/package.json | 2 +- packages/host/package.json | 2 +- packages/web_ui/package.json | 2 +- plugins/global_chat/package.json | 6 +++--- plugins/inventory_sync/package.json | 6 +++--- plugins/player_auth/package.json | 6 +++--- plugins/research_sync/package.json | 6 +++--- plugins/statistics_exporter/package.json | 6 +++--- plugins/subspace_storage/package.json | 6 +++--- 12 files changed, 27 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index e62b1c7f..7078aa49 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@clusterio/controller": "workspace:*", "@clusterio/ctl": "workspace:*", "@clusterio/host": "workspace:*", + "@clusterio/web_ui": "workspace:*", "@clusterio/lib": "workspace:*", "@swc/core": "^1.4.0", "@typescript-eslint/eslint-plugin": "^6.4.1", diff --git a/packages/controller/package.json b/packages/controller/package.json index 70238955..98251fd8 100644 --- a/packages/controller/package.json +++ b/packages/controller/package.json @@ -19,7 +19,7 @@ "node": ">=18" }, "dependencies": { - "@clusterio/lib": "^2.0.0-alpha.18", + "@clusterio/lib": "workspace:*", "@sinclair/typebox": "^0.30.4", "busboy": "^1.6.0", "compression": "^1.7.4", @@ -36,7 +36,7 @@ "yargs": "^17.7.2" }, "devDependencies": { - "@clusterio/web_ui": "^2.0.0-alpha.18", + "@clusterio/web_ui": "workspace:*", "@swc/core": "^1.4.0", "@types/busboy": "^1.5.0", "@types/compression": "^1.7.2", diff --git a/packages/create/templates/common/package.json b/packages/create/templates/common/package.json index 66b20070..346cce77 100644 --- a/packages/create/templates/common/package.json +++ b/packages/create/templates/common/package.json @@ -15,7 +15,7 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "^2.0.0-alpha.17" + "@clusterio/lib": "workspace:*" }, "devDependencies": { //%// Typescript and type declarations @@ -36,9 +36,9 @@ "webpack": "^5.88.2", "webpack-cli": "^5.1.4", "webpack-merge": "^5.9.0", - "@clusterio/web_ui": "^2.0.0-alpha.17", + "@clusterio/web_ui": "workspace:*", //%endif - "@clusterio/lib": "^2.0.0-alpha.17" + "@clusterio/lib": "workspace:*" }, "dependencies": { "@sinclair/typebox": "^0.30.4" diff --git a/packages/ctl/package.json b/packages/ctl/package.json index 4cfa6b84..de6a89da 100644 --- a/packages/ctl/package.json +++ b/packages/ctl/package.json @@ -19,7 +19,7 @@ "node": ">=18" }, "dependencies": { - "@clusterio/lib": "^2.0.0-alpha.18", + "@clusterio/lib": "workspace:*", "as-table": "^1.0.55", "fs-extra": "^11.1.1", "phin": "^3.7.0", diff --git a/packages/host/package.json b/packages/host/package.json index 613d40fd..73384900 100644 --- a/packages/host/package.json +++ b/packages/host/package.json @@ -19,7 +19,7 @@ "node": ">=18" }, "dependencies": { - "@clusterio/lib": "^2.0.0-alpha.18", + "@clusterio/lib": "workspace:*", "@sinclair/typebox": "^0.30.4", "fs-extra": "^11.1.1", "jimp": "^0.22.8", diff --git a/packages/web_ui/package.json b/packages/web_ui/package.json index 97c6aab5..568acf8e 100644 --- a/packages/web_ui/package.json +++ b/packages/web_ui/package.json @@ -17,7 +17,7 @@ }, "dependencies": { "@ant-design/icons": "^5.1.4", - "@clusterio/lib": "^2.0.0-alpha.18", + "@clusterio/lib": "workspace:*", "@swc/core": "^1.4.0", "antd": "^5.13.0", "assert": "^2.0.0", diff --git a/plugins/global_chat/package.json b/plugins/global_chat/package.json index 2d1226a6..5b644083 100644 --- a/plugins/global_chat/package.json +++ b/plugins/global_chat/package.json @@ -18,11 +18,11 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "^2.0.0-alpha.0" + "@clusterio/lib": "workspace:*" }, "devDependencies": { - "@clusterio/lib": "^2.0.0-alpha.18", - "@clusterio/web_ui": "^2.0.0-alpha.18", + "@clusterio/lib": "workspace:*", + "@clusterio/web_ui": "workspace:*", "@types/node": "^20.4.5", "@types/react": "^18.2.21", "typescript": "^5.1.6", diff --git a/plugins/inventory_sync/package.json b/plugins/inventory_sync/package.json index d98b9ea7..ea3cc927 100644 --- a/plugins/inventory_sync/package.json +++ b/plugins/inventory_sync/package.json @@ -18,15 +18,15 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "^2.0.0-alpha.0" + "@clusterio/lib": "workspace:*" }, "dependencies": { "@sinclair/typebox": "^0.30.4", "fs-extra": "^8.1.0" }, "devDependencies": { - "@clusterio/lib": "^2.0.0-alpha.18", - "@clusterio/web_ui": "^2.0.0-alpha.18", + "@clusterio/lib": "workspace:*", + "@clusterio/web_ui": "workspace:*", "@types/fs-extra": "^11.0.1", "@types/node": "^20.4.5", "@types/react": "^18.2.21", diff --git a/plugins/player_auth/package.json b/plugins/player_auth/package.json index c2e35762..17cbe97c 100644 --- a/plugins/player_auth/package.json +++ b/plugins/player_auth/package.json @@ -18,7 +18,7 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "^2.0.0-alpha.0" + "@clusterio/lib": "workspace:*" }, "dependencies": { "@sinclair/typebox": "^0.30.4", @@ -26,8 +26,8 @@ "jsonwebtoken": "^9.0.1" }, "devDependencies": { - "@clusterio/lib": "^2.0.0-alpha.18", - "@clusterio/web_ui": "^2.0.0-alpha.18", + "@clusterio/lib": "workspace:*", + "@clusterio/web_ui": "workspace:*", "@types/express": "^4.17.17", "@types/jsonwebtoken": "^9.0.2", "@types/node": "^20.4.5", diff --git a/plugins/research_sync/package.json b/plugins/research_sync/package.json index d1bf14fa..5cf31dc2 100644 --- a/plugins/research_sync/package.json +++ b/plugins/research_sync/package.json @@ -18,15 +18,15 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "^2.0.0-alpha.0" + "@clusterio/lib": "workspace:*" }, "dependencies": { "@sinclair/typebox": "^0.30.4", "fs-extra": "^8.1.0" }, "devDependencies": { - "@clusterio/lib": "^2.0.0-alpha.18", - "@clusterio/web_ui": "^2.0.0-alpha.18", + "@clusterio/lib": "workspace:*", + "@clusterio/web_ui": "workspace:*", "@types/fs-extra": "^11.0.1", "@types/node": "^20.4.5", "@types/react": "^18.2.21", diff --git a/plugins/statistics_exporter/package.json b/plugins/statistics_exporter/package.json index 68a4d8f1..09d09f0a 100644 --- a/plugins/statistics_exporter/package.json +++ b/plugins/statistics_exporter/package.json @@ -18,11 +18,11 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "^2.0.0-alpha.0" + "@clusterio/lib": "workspace:*" }, "devDependencies": { - "@clusterio/lib": "^2.0.0-alpha.18", - "@clusterio/web_ui": "^2.0.0-alpha.18", + "@clusterio/lib": "workspace:*", + "@clusterio/web_ui": "workspace:*", "@types/node": "^20.4.5", "@types/react": "^18.2.21", "typescript": "^5.1.6", diff --git a/plugins/subspace_storage/package.json b/plugins/subspace_storage/package.json index 288b4743..26fa03e8 100644 --- a/plugins/subspace_storage/package.json +++ b/plugins/subspace_storage/package.json @@ -18,15 +18,15 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "^2.0.0-alpha.0" + "@clusterio/lib": "workspace:*" }, "dependencies": { "@sinclair/typebox": "^0.30.4", "fs-extra": "^8.1.0" }, "devDependencies": { - "@clusterio/lib": "^2.0.0-alpha.18", - "@clusterio/web_ui": "^2.0.0-alpha.18", + "@clusterio/lib": "workspace:*", + "@clusterio/web_ui": "workspace:*", "@types/express": "^4.17.17", "@types/fs-extra": "^11.0.1", "@types/node": "^20.4.5", From d7c2e7eed72d6e33e9f592a443dce6d6e1d67aea Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 15 May 2024 18:41:24 +0200 Subject: [PATCH 09/43] Update mod management section of readme (#618) * Update mod management section of readme Resolves #617 * Update section after review --- README.md | 13 +++++++++---- docs/assets/config_select_mod_pack.png | Bin 0 -> 55234 bytes docs/assets/export_mod_config_data.png | Bin 0 -> 26078 bytes docs/assets/mod_settings_configuration.png | Bin 0 -> 130825 bytes 4 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 docs/assets/config_select_mod_pack.png create mode 100644 docs/assets/export_mod_config_data.png create mode 100644 docs/assets/mod_settings_configuration.png diff --git a/README.md b/README.md index c00b5ab5..092e55b4 100644 --- a/README.md +++ b/README.md @@ -209,12 +209,17 @@ See the [readme for @clusterio/controller](/packages/controller/README.md) for m ## Managing Factorio mods -Clusterio currently only provides a manual method for running mods on servers by copying them either to each instance's individual `mods` folder, or by copying them into a host installation's `sharedMods` folder which will link/copy them to the `mods` folder of each instance on that host if the file doesn't already exist in the `mods` folder for that instance. -Mods are copied from `sharedMods` on Windows and symlinked on Linux, this means that when mods are removed from `sharedMods` the mods will also be removed from the instance's `mods` folder on Linux if it got there by being linked by Clusterio, but not on Windows. +Mods in clusterio are managed as parts of modpacks. There is currently no mod portal integration, so you first need to navigate to the mods section of the web UI and upload your mods. You can then create a modpack from the uploaded mods by navigating to the mods page, hitting `create`. Once you have a modpack, you can assign it to an instance under Instance config -> Factorio -> Mod pack. You can also set a default modpack for new instances in the controller settings. -For managing the mod settings, the `mod-settings.dat` and `mod-list.json` files will also be linked/copied over if present in `sharedMods`, but since Factorio creates these files automatically it might be necessary to delete them from each instance's `mods` folder for changes to them in `sharedMods` to take effect. +![Select mod pack for instance](docs/assets/config_select_mod_pack.png) -Better remote management of mods is a planned feature. +Mod settings can be managed under the modpack configuration page in the web UI. For mod settings to show, you first need to run an export. This is done by creating an instance with the modpack assigned, opening the instance page and pressing More -> Export data. + +![Export mod configuration data](docs/assets/export_mod_config_data.png) + +Once this is done, the mod settings will show up under the modpack configuration page. + +![Mod settings configuration in web interface](docs/assets/mod_settings_configuration.png) ## Setting up shared storage diff --git a/docs/assets/config_select_mod_pack.png b/docs/assets/config_select_mod_pack.png new file mode 100644 index 0000000000000000000000000000000000000000..c801a13eea44878efd6dc682e35d492f0f34d3af GIT binary patch literal 55234 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 literal 0 HcmV?d00001 diff --git a/docs/assets/export_mod_config_data.png b/docs/assets/export_mod_config_data.png new file mode 100644 index 0000000000000000000000000000000000000000..c8ba29d8d9138bb5989e22e79c997b58c7505dcb GIT binary patch literal 26078 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
6)kv%&3PhopK6ABFTI{j z-bt$A(vn7P6x*qCDb-T*1!(R|SFB*hDqh+BB#3c2N**LrH^m`~y9B812O2nAEkMwb z&K^h)K?<$hbSNk7Qz|~_3Mjw6T$3EfdGSyfQLoi}$uzIVYUoXAYp0ueocC7dFr|y^ zM?sk*k+?H2tE~b~?V1>&1C+1U_@T!rH_v>*+|bUj+9IoD zROIv>Ag^{{Ze{1;j?i}QRN@L8qgq%fVrNiTmQ=HZMY=~pn@X_j=lOxCSb@LdCQPR4 zUOP^Xw-EqeEnsrq~*xaF+ZZi)aX*7&CCW<^Yvx+zM#AUer5#*IYQp~hDIBSc8 zR&ij|?GL6^!~Io@P8L9DgB4qR(~E3=95n)UCwdqz+I-bH6|PVa1r;Q?D5_8L)K((} z(=!%?hh!vGenl;kOOer`60h43G`^?S>?!DEY^&-u6tGlXWTKwA{`H#e_?m zf1pvLIlEf&U3^MPg@%SkzJ%_Ixl0_BU!3n-2C90~w_Rud*?I%Z&}1FRJupg12FaPn zK8k&2y)rLoI}CGt_%+UV4?z3`pJd^)8f#BR1>p|d#nJ5;b=`8?Rno$3 zHh*x?m=1Mix?05{uBH+i=F|DD`(@b#9u%D_uqb5#i((l8%cR7 z&tGTbUzcYertsVwSNHT*fHKuAFuO19iU{X@_m2LVunjj$t$dzwU~c>as&OXe{leY1 zh8gOPqqg^%{^NUy$YCH&b2Z8j6%Lo^N-9*Q?zncpw2gtnC){OwC`_VPKQn|~E@{x# zDAK^lX}WV{tgBXA$+YeH;uv9BJRr)f4S8K}7YCqzdJ3LTutKj)*is+;fv;l)fc51j zB{MI7OWUqo!-Kw`Lm|`eEg)N~0Oh$lHMH%}zfPCMaC4ythzDsLJaFo_P`QZ^N}c{# zX!CjTSMNvDbEPaERYUl^c9TE2TfhJaM+}!d`X9$F(tr3>L@b=>xNvpR66{~A@4q+J z^T~g2?EkYX_Ew`i_up9nusHv_djGpE?EZhlek)`xw63$|$IcAOLBL~qIFI}D0U;#_ zrEJU&!PjDo=Ma_Iufl<}3{7uA9qX+fhb~J_#yWTS7P&nLw|xwXzS^SulFUCHJT!hG z#A_&Q)=lVM;Okz%qIo5_NKrz;owI)}e(FTbG5RoV(>``<>&cN_t3OIJyTJsvN?>wk zW@VQvOh>=L{J47DzJP#o$Y3@^8Jx&sgKK@lw)l_TDg^r6hcYPi8!%zl>BD@&udbXF zUH{|LbEkHP%6rRCe`T`oTlAERSnE0a*VU=0i}MHGG^?IS$aoQR=bwW|##g3tjd=lU zsJx_!+oESw*^6@oWF$;mN?S_ZdC-zQh_##FRmUAK$TH!&XWA zbBMAzsQ-)jOixd~fKsMjo9Dz<@WX1f=PwQb{ZtAqWyrV(1y0KK;f5c-=~w@kX9-N! z=u<9mlxrP*9wJ|Soj&@bF-?& zjlag5UtNYvv0~ubVsP;&GOtl#)K=X
rB^kHbNFifWs)ZVUxhYHW5K81=bKe0fA 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%0AepLQAMxr6eI`p?@?xc{bQ$o!ZE_-{#pK?S-99 z%QenmceJ8BS9*13j7_ZJ*kjmFuk4oBmVceic=ybDV=F5W-^?Q(w?28Uuj_%=1l)wYmkt@- zTyNxYJJ{gPHE6DMm^@S#*$jAeP2Uwu=eb$=hv=6%9A`{n`K>6*gL$CM34=T+)fT>lF{qA*FiYw_{x`O_Sgr2&UY zhXQiJd}=vGv@$DDny}vVb@`!0rEkb#zE*%fT<$KX%%H5MGpKu?t7`rVc9yq~AN*SN zWNt^9)#lLh#>VP9g%@(?`7Z{tGe@um$WWS|GhwpQIL|~)-5hfvRC9Pbi|>*2^Q1j- zG2YmtyJ`mcm{s@0akGT6H}%i0#YRHILFx%tsxB`iuqtP+)fjg2WgfG95XRMKa;PHy6VFwN4 z@D0J5{hs9VwWiUhqoUTC3zR+xQONZBkvZ3{+P#Q3KhwS!ufr5`*06io)(Vd+O?Y}| zBGoT zTwQj{S!`Ibp4&QX;9X2_(8uHx3S)l7Vl!6@+xG4jx+ayF} z#XiDQ$FcKCE46g&1e}%E7eCSJCpTB>$3UoYWU?<>)P4fonN;lA_9YRFW=*@6UpG@t z3Hl0*-D1Q)?dX%OapS#Z1Y>5iIRB&7!gQpm>vFSkN6Bogls4y1ioKYutE($K>}OnR?}phQmtx(^ z9wz;eoDXdNk7?D=9ApaRAnavYueOGuqqMU8I$ zP4~;jdtUdE4wb1DXT7WDd7yw|YF|VllZ`!7H~G>;!?UmK_Ff`4g%q6lb;))xUA(Z9 zPVGa$fh`s9_Igm7Fc58PY-G$}6jhy|@EjK3FqOE({$*4oo&vXve11NfTshF)S1D!h z5gFeay}A8Yt$adB%y*CC($mN&85hSX<`ejE>}<75;tGXB4`p`XMvY6&G{U{J=&Ni- zs&{y;5xMr4+M1LfDm&y`Y1ppj^Hr1dH`3DE8aX@Ee6ti@M-O7Ip357uBX-80(i|NJ zp-0OddUw*Ta=t9fTd(aMJ)^yn^|rvQrM8$GYd5pco~Vlsw@>6tf-||vONlu9G^-sZ zH)(iA>3c@1SIEnrvw7<^CuLkHZ>^)7Xo_E(Dz@%v=TBFR2xq9Wbh$XTvuk%3ttX9V zyIC*Ez`muOqeo;b3>hPrZng@xQq&stGLYT0ks1=Mp<@|b<_jU4B-pr*Y&N;>?GtQe zUCf=(rhAtDtEKkm0(|-zvwr!iPu!+Ln9i{E9GvfNpABVX4~N(kia<%AMK1J}NAmVC z&Q^7BSM;_%#>@>H1;zrYd)L7_@b**Bk_yGF@Mcy`C7cuy6UG(^ZiQxKSk9?vSb3=J2*6&()Q5gPZPjUs3%rR(pn%>egl8==d zhK^@)lgsXn-%5sKq>Q0t@mG8}R(<^`5f;zVIoFRBW;`TY;d%DvN|4u6z6QG6m!k}~ z*-%Og+??B;$Avj2OGAm|c^^DV&jQJLLM)9~A!6&@+)Bf@K2O0il|uHu)(vUV{ZmrD zL^g7M!0sjSB$~3uJc#qO9TPK=3{Upi#j8jh%xbN9%-q-=Z|wMm{_b0tILGCyv0j`l z80~9v8BLU)V8%Fd2_g>5Kwyu zcj>2FkKtu706PT-lk>;M_33yJ~5fpRz5gjSgd7-wc_>g2C#jb)ziBn&DbZ| z+7nx6-n(C+U5nF`SezHT-gb?S*A4nPTT%ZE`#RIDY@STp8g7Xzbj>UPMdaj(ZzIK`=ild4$g(J@=V@1_* ze|S}dpbWdG_U>wPT(7(WZfuZ)hJy9cheS8=^}S<6bb1KyA3k}*WGgRs1kV619jB67 zy#2wVAs>aEKD6YzFb@8FtUx z+h0s5gt~*YgQJ@8f+D=v)l2wuY9MCExxS}t3h~IMtSK&)Zp-CUV}6BqZ|<*gmVF4;u%>;b$IFi0m}_piZ9faOcW_1z$!HA46&B_DDO9^#N{~ zS=xr}#FQ)_ENjVacUGJWdF7pUbt1Xuz%0wNH5SLz_i?O>7x7erMEjJA7%8i_-e~7d za$B_!BldG5uN*k~(0OU9<+x9Pa^*RZ@(-`tC?V<3fZXrHU;&sH>CpO4E*~W2aLHuZ z6HFnZex&Mbz!paQt}k+DJ>GtR;fZl{Up1dB8Q#G6$k`h=#=(A7;^NSWtA(x0Oj=Lh z`Fu)E(Jj23r6xA2qrvQ|lU*&b zZ;_%~)wD+D;lxw(6y10VX=dzJ@~zOBIphZjgs6S8TY-( z>@KU3px8>+h08lm%**3DkEjg}hpTU5GWXVc-A?)BD7(T??@um3=Vg-QGW#MG#r>Un zgdrddxUEik#GFiFhP(N_N@=lWlJaR+{i|oI{(EtOUS#j5MvGhcMRlsY7)i?j<*rxk zVR!eSxgq?PgUbfOd3h}7!F^BBGsH$hZ*gegFjCmA;>iWUN~xkoNosKg8i{RRLYB4Px-8EyF7UNfiui0>P;nacj?m4;sy@-9G5;mOF2M{ZDEL@ zP9~XOZ0hur?KHJY+f0L^D!01R6k3s$9(R}vXwg|p-({l2-j%JPI zcXzM%0l{qEwOy*^_FRB;nzx?E1+Fk``Z=4=H$-I|Qx17h>@b7`>_mm#bLVY+Z(Kt0 zloeRUBhw0l>O0As1Eolh5_ffj@%e3KqOlX@>M9ol`eko8z?A2jwNvdh>N#=DG z;+I^ep(uLE^if8k?val8@F&dMAOXE}YalF#FM`+JVj3X!Ps-x(?khpEe5i)WMQ@DM!oySx0zler4u=# z|M;r4o#@jEmU!0d&Iz?RR(+6s-mLu;se4Azx^t1ux_2hz{1=F`k0RcUaa?95WBs6q zrE`Zz#8P>;HG+-_>u>qn5I%)wEJ(6?F+%373Yk%8?J&QeIe8L{>Wz{{ovfApc8oIY zaO*3S|6C(By2m*A=)_C9G$R&+As&~OB)9OabZ;#di^pP~uROg)FEKnges*SKsXx=P zv+%GX*+Frz7_~Ssx@}Fc4n(;^<)CnBa1C0iDP{@h(B5j&l3<^)dyh3!^Sfee1MS;G zSLVYC#`cozADyVFk^LxT?}ZofNH%>L-b9QeH&pK)gkg-zMq0$4kyx9a?4a%$6Bn{G z5*za!%)#F!OU0Iv zVW+xM={mZ5jqgl^^p0yx#7w=;rH6;Buc*BXhbmrR>0DFqfLj+;?_OIyTsfWQp&~)9 zQB~J*e%;dkA^qBo0U&SC2>U#r0Fs+h|Kq7xOxGa^^-_kL6qtr*oj1oQmvSj9268cHQmu zL028uHo=flfmO!XJ!++LWi_K!wdWzPQOFS{JcCGpjms$aj;?l9)_T(D+amjd4_qFY ze*d^6`+)p?FZzbG&$U31ltb>BJF0-eat=p(P<@2#kcXuwTa~s zALQZa1PRf$+9S>MM0{lFS&i&t>QkN%?Z;Z|=IW_cB2a! z(*=FGu$whYaHgen-_^Z&P^k~nb*mZ?0lU%+i*R8JAyZVK* zQRH~qIV~a1Lwc&PUJmvi_koM5ALcK8HaUnn@NgE7i`W!P%Zd*VHZ7^SzEdIVz)a?e z9y1@D`F>Qf`K?EVlFv(F4k?chu9vpu#{X)PXlT){&lRjaxOU-M-&;x>{o_wBiO#LR z)px$?o`d^}h7Aqo=ae-(58eK~XJcGfa)Hl-KLVUSLLDyArrt-4EQ%FeW|S)AE!c7) zfKR~pue;5G7~sZM?MoXi;-6Kl753CEzLO=O5O|B@`|NEGq+ZOLpZi-$%i)Hjk&QTu zLAc;q1%{KYzPWEV$T9L$a$bS&r!((=-#ODSJRjKFm^`oWjP1MJpMMo^l@lJ*uxWhy zHLNZF|BCG=ZeRTKl~*XpLcfIdr1q(`KEkO?Ti5dbauV9Bo%PEpI``1@TmO7su{TN1 zaTI6^=wcTaKP5W{xJ)|J{Eql3hckw{hc~VL(U*MG%QalHf8p=e2g}peJv;t3sZX0- zNd(wN`K{jRlCeFl?%DD4_QvwFpFP=C`ub8@;5F6z%ik8yc374Bd)Zgh$Kl!!W=!M0 z{z%|@a$TLu8_CO{3Bu0q9b(z8N?R_QrhiKQxbvITo8omAu?l$ybvrA7t9CCHb=24X zGCcC}l-aVm+NsvDpmCqv>nY*4efM9to31wZzZb{9S?7+H;u+lmCB_H$of58cyZ+N< zHr0RL8GI7BV%Bs~4C|u_0v!|P(*GOR`&Yx;k*AUmID#(wQOuq*Dn>p`33!gx ze7@b;*Vj$8_+$TWMu(1B?yV{3x`RT2r!_z5n)le`vv~SUflh_Et|EW!DkZrXLUp?X z(|-e|)%(7jvCpvyyZSQV5VN_U*F&GG=$g>ESLT#V3zF@ym^H_u?ZqQtRaG=QA|@tg zV-Y`aAze(7$<6Kg_XU=JS)borgyj*Yu~q4?@m5y?LuE)g+h97&KkMmxHw6<2dz5Z& zvv7chkwuX76zoL Date: Wed, 15 May 2024 19:43:40 +0100 Subject: [PATCH 10/43] Prevent dropping files outside of dropzones --- packages/web_ui/src/components/Dropzone.tsx | 3 +- packages/web_ui/src/components/SiteLayout.tsx | 35 +++++++++++++++++-- .../web_ui/src/components/UploadButton.tsx | 1 + 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/packages/web_ui/src/components/Dropzone.tsx b/packages/web_ui/src/components/Dropzone.tsx index 0af48ff4..cef95cd6 100644 --- a/packages/web_ui/src/components/Dropzone.tsx +++ b/packages/web_ui/src/components/Dropzone.tsx @@ -7,6 +7,7 @@ export function Dropzone() { const isDroppingFile = useContext(DraggingContext); return
(null); @@ -86,9 +102,24 @@ export default function SiteLayout() { onDragEnter={() => setDraggingProxy(1)} onDragLeave={() => setDraggingProxy(-1)} // Reset dragging state when dropped - onDrop={() => setDragging(0)} + onDrop={(e) => { + setDragging(0); + // Prevent dropping outside of dropzone + if (!isDropzone(e.target as HTMLElement)) { + e.preventDefault(); + e.stopPropagation(); + } + }} // Allow entire document to be a drag target - onDragOver={(e) => e.preventDefault()} + onDragOver={(e) => { + e.preventDefault(); + // Change cursor + if (isDropzone(e.target as HTMLElement)) { + e.dataTransfer.dropEffect = "copy"; + } else { + e.dataTransfer.dropEffect = "none"; + } + }} > 0}>
diff --git a/packages/web_ui/src/components/UploadButton.tsx b/packages/web_ui/src/components/UploadButton.tsx index c6c324a9..652ce9a4 100644 --- a/packages/web_ui/src/components/UploadButton.tsx +++ b/packages/web_ui/src/components/UploadButton.tsx @@ -7,6 +7,7 @@ import { DraggingContext } from "../model/is_dragging"; export default function UploadButton(props: React.ComponentProps) { const isDroppingFile = useContext(DraggingContext); return
; diff --git a/packages/web_ui/src/components/SavesList.tsx b/packages/web_ui/src/components/SavesList.tsx index d5eb6ef8..9a962a87 100644 --- a/packages/web_ui/src/components/SavesList.tsx +++ b/packages/web_ui/src/components/SavesList.tsx @@ -363,7 +363,7 @@ export default function SavesList(props: { instance: lib.InstanceDetails }) { zIndex: "1010", }} > - + {saveTable}
diff --git a/packages/web_ui/src/components/SiteLayout.tsx b/packages/web_ui/src/components/SiteLayout.tsx index 856ac492..5baece76 100644 --- a/packages/web_ui/src/components/SiteLayout.tsx +++ b/packages/web_ui/src/components/SiteLayout.tsx @@ -13,7 +13,7 @@ import { DraggingContext } from "../model/is_dragging"; const { Header, Sider } = Layout; -function isDropzone(element: HTMLElement | null): boolean { +function isActiveDropzone(element: HTMLElement | null): boolean { if (!element) { return false; } @@ -21,7 +21,7 @@ function isDropzone(element: HTMLElement | null): boolean { let depth = 0; while (element && depth < checkDepth) { if (element.classList.contains("dropzone")) { - return true; + return element.classList.contains("enabled"); } element = element.parentElement; depth += 1; @@ -105,7 +105,7 @@ export default function SiteLayout() { onDrop={(e) => { setDragging(0); // Prevent dropping outside of dropzone - if (!isDropzone(e.target as HTMLElement)) { + if (!isActiveDropzone(e.target as HTMLElement)) { e.preventDefault(); e.stopPropagation(); } @@ -114,7 +114,7 @@ export default function SiteLayout() { onDragOver={(e) => { e.preventDefault(); // Change cursor - if (isDropzone(e.target as HTMLElement)) { + if (isActiveDropzone(e.target as HTMLElement)) { e.dataTransfer.dropEffect = "copy"; } else { e.dataTransfer.dropEffect = "none"; diff --git a/packages/web_ui/src/components/UploadButton.tsx b/packages/web_ui/src/components/UploadButton.tsx index 652ce9a4..cc3dd6b7 100644 --- a/packages/web_ui/src/components/UploadButton.tsx +++ b/packages/web_ui/src/components/UploadButton.tsx @@ -6,13 +6,14 @@ import { DraggingContext } from "../model/is_dragging"; export default function UploadButton(props: React.ComponentProps) { const isDroppingFile = useContext(DraggingContext); + const borderColor = props.disabled ? "gray" : "rgb(22, 119, 255)"; return
-

Inventory sync

+ {statsData && <>

Database size: {Math.round(statsData.databaseSize / 1000)}kB

Database entries: {statsData.databaseEntries}

diff --git a/plugins/subspace_storage/web/index.tsx b/plugins/subspace_storage/web/index.tsx index 345795f2..2d1b458a 100644 --- a/plugins/subspace_storage/web/index.tsx +++ b/plugins/subspace_storage/web/index.tsx @@ -3,7 +3,7 @@ import { Input, Table, Typography } from "antd"; import * as lib from "@clusterio/lib"; import { - BaseWebPlugin, PageLayout, Control, ControlContext, + BaseWebPlugin, PageLayout, PageHeader, Control, ControlContext, notifyErrorHandler, useItemMetadata, useLocale, } from "@clusterio/web_ui"; import { GetStorageRequest, Item, SetStorageSubscriptionRequest, UpdateStorageEvent } from "../messages"; @@ -60,7 +60,7 @@ function StoragePage() { let numberFormat = new Intl.NumberFormat("en-US"); return -

Storage

+ Date: Sat, 6 Jul 2024 17:48:14 +0100 Subject: [PATCH 33/43] Fix missing codecov upload token --- .github/workflows/node.js.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 632e46f9..69a7fa1f 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -34,9 +34,10 @@ jobs: run: pnpm run ci-cover - name : Upload coverage to Codecov if: ${{ matrix.node-version == '18.x' }} - uses: codecov/codecov-action@v2 + uses: codecov/codecov-action@v4 with: files: ./coverage/lcov.info + token: ${{ secrets.CODECOV_TOKEN }} lint: runs-on: ubuntu-latest From 02df956f6cc4f7e5a48fedf80ac8a6120da913a6 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Fri, 5 Jul 2024 23:44:53 +0100 Subject: [PATCH 34/43] Fix breaking change introduced in v5.5 https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/#simplified-reference-directive-declaration-emit --- packages/web_ui/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web_ui/src/index.ts b/packages/web_ui/src/index.ts index 601e092c..2053560a 100644 --- a/packages/web_ui/src/index.ts +++ b/packages/web_ui/src/index.ts @@ -1,4 +1,4 @@ -/// +/// export { default as bootstrap } from "./bootstrap"; export { default as notify, notifyErrorHandler } from "./util/notify"; export { default as BaseWebPlugin } from "./BaseWebPlugin"; From 08c522429bc57b63f4ae22d56ae1b957ccbbb232 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Sat, 6 Jul 2024 00:25:54 +0100 Subject: [PATCH 35/43] Implemented configDir for outDir --- CHANGELOG.md | 1 + package.json | 6 +++--- packages/controller/package.json | 2 +- packages/controller/tsconfig.browser.json | 1 - packages/controller/tsconfig.node.json | 3 --- packages/create/templates/plugin-ts/tsconfig.browser.json | 3 --- packages/create/templates/plugin-ts/tsconfig.node.json | 3 --- packages/ctl/package.json | 2 +- packages/ctl/tsconfig.node.json | 3 --- packages/host/package.json | 2 +- packages/host/tsconfig.node.json | 3 --- packages/lib/package.json | 2 +- packages/lib/tsconfig.browser.json | 1 - packages/lib/tsconfig.node.json | 1 - packages/web_ui/package.json | 2 +- packages/web_ui/tsconfig.browser.json | 3 --- plugins/global_chat/package.json | 2 +- plugins/global_chat/tsconfig.browser.json | 3 --- plugins/global_chat/tsconfig.node.json | 3 --- plugins/inventory_sync/package.json | 2 +- plugins/inventory_sync/tsconfig.browser.json | 3 --- plugins/inventory_sync/tsconfig.node.json | 3 --- plugins/player_auth/package.json | 2 +- plugins/player_auth/tsconfig.browser.json | 3 --- plugins/player_auth/tsconfig.node.json | 3 --- plugins/research_sync/package.json | 2 +- plugins/research_sync/tsconfig.browser.json | 3 --- plugins/research_sync/tsconfig.node.json | 3 --- plugins/statistics_exporter/package.json | 2 +- plugins/statistics_exporter/tsconfig.browser.json | 3 --- plugins/statistics_exporter/tsconfig.node.json | 3 --- plugins/subspace_storage/package.json | 2 +- plugins/subspace_storage/tsconfig.browser.json | 3 --- plugins/subspace_storage/tsconfig.node.json | 3 --- tsconfig.browser.json | 1 + tsconfig.node.json | 1 + 36 files changed, 17 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 099eb639..66319a98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ Many thanks to the following for contributing to this release: - Fixed IPC errors reporting undefined when no stack trace was present [#624](https://github.com/clusterio/clusterio/pull/624). - Fixed loopback routing for instances reporting the wrong error message [#625](https://github.com/clusterio/clusterio/pull/625). +- Bumped Typescript version to 5.5 and implemented `${configDir}` in base configs for "outDir" [#648](https://github.com/clusterio/clusterio/pull/648). ### Breaking Changes diff --git a/package.json b/package.json index 280d5e3c..985bbc79 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,8 @@ "@clusterio/controller": "workspace:*", "@clusterio/ctl": "workspace:*", "@clusterio/host": "workspace:*", - "@clusterio/web_ui": "workspace:*", "@clusterio/lib": "workspace:*", + "@clusterio/web_ui": "workspace:*", "@swc/core": "^1.4.0", "@typescript-eslint/eslint-plugin": "^6.4.1", "@typescript-eslint/parser": "^6.4.1", @@ -51,8 +51,8 @@ "mocha": "^10.2.0", "nyc": "^15.1.0", "phin": "^3.7.0", - "typedoc": "^0.24.8", - "typescript": "^5.1.6", + "typedoc": "^0.26.3", + "typescript": "^5.5.3", "yargs": "^17.7.2" } } diff --git a/packages/controller/package.json b/packages/controller/package.json index 98251fd8..d83a87b8 100644 --- a/packages/controller/package.json +++ b/packages/controller/package.json @@ -51,7 +51,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.4.14", - "typescript": "^5.1.6", + "typescript": "^5.5.3", "webpack": "^5.88.2", "webpack-dev-middleware": "^6.1.1", "webpack-merge": "^5.9.0" diff --git a/packages/controller/tsconfig.browser.json b/packages/controller/tsconfig.browser.json index 154bd176..01b8e68f 100644 --- a/packages/controller/tsconfig.browser.json +++ b/packages/controller/tsconfig.browser.json @@ -7,6 +7,5 @@ "include": [ "web/**/*.tsx", "web/**/*.ts", "package.json" ], "compilerOptions": { "rootDir": "..", - "outDir": "dist/browser", } } diff --git a/packages/controller/tsconfig.node.json b/packages/controller/tsconfig.node.json index 9dcc91db..52b0c217 100644 --- a/packages/controller/tsconfig.node.json +++ b/packages/controller/tsconfig.node.json @@ -4,7 +4,4 @@ { "path": "../lib/tsconfig.node.json" }, ], "include": ["index.ts", "controller.ts", "package.json", "src/**/*.ts"], - "compilerOptions": { - "outDir": "dist/node", - }, } diff --git a/packages/create/templates/plugin-ts/tsconfig.browser.json b/packages/create/templates/plugin-ts/tsconfig.browser.json index e1b39d0f..325fd71d 100644 --- a/packages/create/templates/plugin-ts/tsconfig.browser.json +++ b/packages/create/templates/plugin-ts/tsconfig.browser.json @@ -5,7 +5,4 @@ { "path": "../../packages/web_ui/tsconfig.browser.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], - "compilerOptions": { - "outDir": "dist/browser", - } } diff --git a/packages/create/templates/plugin-ts/tsconfig.node.json b/packages/create/templates/plugin-ts/tsconfig.node.json index b6197500..ce0e013f 100644 --- a/packages/create/templates/plugin-ts/tsconfig.node.json +++ b/packages/create/templates/plugin-ts/tsconfig.node.json @@ -5,7 +5,4 @@ ], "include": ["./**/*.ts"], "exclude": ["test/*", "./dist/*"], - "compilerOptions": { - "outDir": "dist/node", - }, } diff --git a/packages/ctl/package.json b/packages/ctl/package.json index de6a89da..385d4eae 100644 --- a/packages/ctl/package.json +++ b/packages/ctl/package.json @@ -35,6 +35,6 @@ "@types/node": "^20.4.5", "@types/set-blocking": "^2.0.0", "@types/yargs": "^17.0.24", - "typescript": "^5.1.6" + "typescript": "^5.5.3" } } diff --git a/packages/ctl/tsconfig.node.json b/packages/ctl/tsconfig.node.json index 3a0fb105..40446ef9 100644 --- a/packages/ctl/tsconfig.node.json +++ b/packages/ctl/tsconfig.node.json @@ -4,7 +4,4 @@ { "path": "../lib/tsconfig.node.json" }, ], "include": ["index.ts", "package.json", "ctl.ts", "src/**/*.ts"], - "compilerOptions": { - "outDir": "dist/node", - }, } diff --git a/packages/host/package.json b/packages/host/package.json index 73384900..22fc8306 100644 --- a/packages/host/package.json +++ b/packages/host/package.json @@ -43,6 +43,6 @@ "@types/semver": "^7.5.0", "@types/set-blocking": "^2.0.0", "@types/yargs": "^17.0.24", - "typescript": "^5.1.6" + "typescript": "^5.5.3" } } diff --git a/packages/host/tsconfig.node.json b/packages/host/tsconfig.node.json index e7a488be..689d80e5 100644 --- a/packages/host/tsconfig.node.json +++ b/packages/host/tsconfig.node.json @@ -4,7 +4,4 @@ { "path": "../lib/tsconfig.node.json" }, ], "include": ["index.ts", "host.ts", "package.json", "src/**/*.ts", "src/**/*.js"], - "compilerOptions": { - "outDir": "dist/node", - }, } diff --git a/packages/lib/package.json b/packages/lib/package.json index bf27858b..f45d13d8 100644 --- a/packages/lib/package.json +++ b/packages/lib/package.json @@ -41,6 +41,6 @@ "@types/triple-beam": "^1.3.2", "@types/ws": "^8.5.5", "@types/yargs": "^17.0.24", - "typescript": "^5.1.6" + "typescript": "^5.5.3" } } diff --git a/packages/lib/tsconfig.browser.json b/packages/lib/tsconfig.browser.json index e3c20c4e..0eeb49e4 100644 --- a/packages/lib/tsconfig.browser.json +++ b/packages/lib/tsconfig.browser.json @@ -26,6 +26,5 @@ ], "compilerOptions": { "rootDir": ".", - "outDir": "dist/browser", } } diff --git a/packages/lib/tsconfig.node.json b/packages/lib/tsconfig.node.json index d3dab4e1..a963c8a0 100644 --- a/packages/lib/tsconfig.node.json +++ b/packages/lib/tsconfig.node.json @@ -2,7 +2,6 @@ "extends": "../../tsconfig.node.json", "include": ["index.ts", "browser.ts", "build_mod.js", "src/**/*.ts", "src/**/*.js"], "compilerOptions": { - "outDir": "dist/node", "allowJs": true, }, } diff --git a/packages/web_ui/package.json b/packages/web_ui/package.json index 658e4611..f61a632f 100644 --- a/packages/web_ui/package.json +++ b/packages/web_ui/package.json @@ -40,7 +40,7 @@ "style-loader": "^3.3.3", "swc-loader": "^0.2.6", "terser-webpack-plugin": "^5.3.9", - "typescript": "^5.1.6", + "typescript": "^5.5.3", "util": "^0.12.5", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", diff --git a/packages/web_ui/tsconfig.browser.json b/packages/web_ui/tsconfig.browser.json index 62dbe09d..4c6a3729 100644 --- a/packages/web_ui/tsconfig.browser.json +++ b/packages/web_ui/tsconfig.browser.json @@ -4,7 +4,4 @@ { "path": "../lib/tsconfig.browser.json" }, ], "include": [ "src/**/*.tsx", "src/**/*.ts", "package.json", "global.d.ts" ], - "compilerOptions": { - "outDir": "dist/browser", - } } diff --git a/plugins/global_chat/package.json b/plugins/global_chat/package.json index 5b644083..b8d97aa2 100644 --- a/plugins/global_chat/package.json +++ b/plugins/global_chat/package.json @@ -25,7 +25,7 @@ "@clusterio/web_ui": "workspace:*", "@types/node": "^20.4.5", "@types/react": "^18.2.21", - "typescript": "^5.1.6", + "typescript": "^5.5.3", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", "webpack-merge": "^5.9.0" diff --git a/plugins/global_chat/tsconfig.browser.json b/plugins/global_chat/tsconfig.browser.json index e1b39d0f..325fd71d 100644 --- a/plugins/global_chat/tsconfig.browser.json +++ b/plugins/global_chat/tsconfig.browser.json @@ -5,7 +5,4 @@ { "path": "../../packages/web_ui/tsconfig.browser.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], - "compilerOptions": { - "outDir": "dist/browser", - } } diff --git a/plugins/global_chat/tsconfig.node.json b/plugins/global_chat/tsconfig.node.json index b6197500..ce0e013f 100644 --- a/plugins/global_chat/tsconfig.node.json +++ b/plugins/global_chat/tsconfig.node.json @@ -5,7 +5,4 @@ ], "include": ["./**/*.ts"], "exclude": ["test/*", "./dist/*"], - "compilerOptions": { - "outDir": "dist/node", - }, } diff --git a/plugins/inventory_sync/package.json b/plugins/inventory_sync/package.json index ea3cc927..e184e734 100644 --- a/plugins/inventory_sync/package.json +++ b/plugins/inventory_sync/package.json @@ -33,7 +33,7 @@ "antd": "^5.13.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "typescript": "^5.1.6", + "typescript": "^5.5.3", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", "webpack-merge": "^5.9.0" diff --git a/plugins/inventory_sync/tsconfig.browser.json b/plugins/inventory_sync/tsconfig.browser.json index e1b39d0f..325fd71d 100644 --- a/plugins/inventory_sync/tsconfig.browser.json +++ b/plugins/inventory_sync/tsconfig.browser.json @@ -5,7 +5,4 @@ { "path": "../../packages/web_ui/tsconfig.browser.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], - "compilerOptions": { - "outDir": "dist/browser", - } } diff --git a/plugins/inventory_sync/tsconfig.node.json b/plugins/inventory_sync/tsconfig.node.json index b6197500..ce0e013f 100644 --- a/plugins/inventory_sync/tsconfig.node.json +++ b/plugins/inventory_sync/tsconfig.node.json @@ -5,7 +5,4 @@ ], "include": ["./**/*.ts"], "exclude": ["test/*", "./dist/*"], - "compilerOptions": { - "outDir": "dist/node", - }, } diff --git a/plugins/player_auth/package.json b/plugins/player_auth/package.json index 17cbe97c..a7c40a5b 100644 --- a/plugins/player_auth/package.json +++ b/plugins/player_auth/package.json @@ -36,7 +36,7 @@ "phin": "^3.7.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "typescript": "^5.1.6", + "typescript": "^5.5.3", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", "webpack-merge": "^5.9.0" diff --git a/plugins/player_auth/tsconfig.browser.json b/plugins/player_auth/tsconfig.browser.json index e1b39d0f..325fd71d 100644 --- a/plugins/player_auth/tsconfig.browser.json +++ b/plugins/player_auth/tsconfig.browser.json @@ -5,7 +5,4 @@ { "path": "../../packages/web_ui/tsconfig.browser.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], - "compilerOptions": { - "outDir": "dist/browser", - } } diff --git a/plugins/player_auth/tsconfig.node.json b/plugins/player_auth/tsconfig.node.json index b6197500..ce0e013f 100644 --- a/plugins/player_auth/tsconfig.node.json +++ b/plugins/player_auth/tsconfig.node.json @@ -5,7 +5,4 @@ ], "include": ["./**/*.ts"], "exclude": ["test/*", "./dist/*"], - "compilerOptions": { - "outDir": "dist/node", - }, } diff --git a/plugins/research_sync/package.json b/plugins/research_sync/package.json index 5cf31dc2..955874ae 100644 --- a/plugins/research_sync/package.json +++ b/plugins/research_sync/package.json @@ -30,7 +30,7 @@ "@types/fs-extra": "^11.0.1", "@types/node": "^20.4.5", "@types/react": "^18.2.21", - "typescript": "^5.1.6", + "typescript": "^5.5.3", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", "webpack-merge": "^5.9.0" diff --git a/plugins/research_sync/tsconfig.browser.json b/plugins/research_sync/tsconfig.browser.json index e1b39d0f..325fd71d 100644 --- a/plugins/research_sync/tsconfig.browser.json +++ b/plugins/research_sync/tsconfig.browser.json @@ -5,7 +5,4 @@ { "path": "../../packages/web_ui/tsconfig.browser.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], - "compilerOptions": { - "outDir": "dist/browser", - } } diff --git a/plugins/research_sync/tsconfig.node.json b/plugins/research_sync/tsconfig.node.json index b6197500..ce0e013f 100644 --- a/plugins/research_sync/tsconfig.node.json +++ b/plugins/research_sync/tsconfig.node.json @@ -5,7 +5,4 @@ ], "include": ["./**/*.ts"], "exclude": ["test/*", "./dist/*"], - "compilerOptions": { - "outDir": "dist/node", - }, } diff --git a/plugins/statistics_exporter/package.json b/plugins/statistics_exporter/package.json index 09d09f0a..cb4e9d0c 100644 --- a/plugins/statistics_exporter/package.json +++ b/plugins/statistics_exporter/package.json @@ -25,7 +25,7 @@ "@clusterio/web_ui": "workspace:*", "@types/node": "^20.4.5", "@types/react": "^18.2.21", - "typescript": "^5.1.6", + "typescript": "^5.5.3", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", "webpack-merge": "^5.9.0" diff --git a/plugins/statistics_exporter/tsconfig.browser.json b/plugins/statistics_exporter/tsconfig.browser.json index f2dc36da..ff89a801 100644 --- a/plugins/statistics_exporter/tsconfig.browser.json +++ b/plugins/statistics_exporter/tsconfig.browser.json @@ -5,7 +5,4 @@ { "path": "../../packages/web_ui/tsconfig.browser.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "package.json" ], - "compilerOptions": { - "outDir": "dist/browser", - } } diff --git a/plugins/statistics_exporter/tsconfig.node.json b/plugins/statistics_exporter/tsconfig.node.json index b6197500..ce0e013f 100644 --- a/plugins/statistics_exporter/tsconfig.node.json +++ b/plugins/statistics_exporter/tsconfig.node.json @@ -5,7 +5,4 @@ ], "include": ["./**/*.ts"], "exclude": ["test/*", "./dist/*"], - "compilerOptions": { - "outDir": "dist/node", - }, } diff --git a/plugins/subspace_storage/package.json b/plugins/subspace_storage/package.json index 26fa03e8..e6de5b57 100644 --- a/plugins/subspace_storage/package.json +++ b/plugins/subspace_storage/package.json @@ -34,7 +34,7 @@ "antd": "^5.13.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "typescript": "^5.1.6", + "typescript": "^5.5.3", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", "webpack-merge": "^5.9.0" diff --git a/plugins/subspace_storage/tsconfig.browser.json b/plugins/subspace_storage/tsconfig.browser.json index e1b39d0f..325fd71d 100644 --- a/plugins/subspace_storage/tsconfig.browser.json +++ b/plugins/subspace_storage/tsconfig.browser.json @@ -5,7 +5,4 @@ { "path": "../../packages/web_ui/tsconfig.browser.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], - "compilerOptions": { - "outDir": "dist/browser", - } } diff --git a/plugins/subspace_storage/tsconfig.node.json b/plugins/subspace_storage/tsconfig.node.json index b6197500..ce0e013f 100644 --- a/plugins/subspace_storage/tsconfig.node.json +++ b/plugins/subspace_storage/tsconfig.node.json @@ -5,7 +5,4 @@ ], "include": ["./**/*.ts"], "exclude": ["test/*", "./dist/*"], - "compilerOptions": { - "outDir": "dist/node", - }, } diff --git a/tsconfig.browser.json b/tsconfig.browser.json index 605c2c61..b5d82db1 100644 --- a/tsconfig.browser.json +++ b/tsconfig.browser.json @@ -7,5 +7,6 @@ "target": "es2022", "jsx": "react-jsx", "noEmitOnError": true, + "outDir": "${configDir}/dist/browser", }, } diff --git a/tsconfig.node.json b/tsconfig.node.json index 700d02da..dd436f25 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -6,5 +6,6 @@ "moduleResolution": "node16", "target": "es2022", "forceConsistentCasingInFileNames": true, + "outDir": "${configDir}/dist/node", }, } From 660af756e6beba8f856a489f6d3d9c71a320e74e Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:03:09 +0100 Subject: [PATCH 36/43] Minor Corrections --- packages/controller/package.json | 4 ++-- packages/controller/src/Controller.ts | 2 +- packages/create/templates/common/package.json | 2 +- packages/lib/src/link/link.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/controller/package.json b/packages/controller/package.json index d83a87b8..2256e2a9 100644 --- a/packages/controller/package.json +++ b/packages/controller/package.json @@ -29,7 +29,6 @@ "jsonwebtoken": "^9.0.1", "jszip": "^3.10.1", "set-blocking": "^2.0.0", - "webpack-cli": "^5.1.4", "winston": "^3.10.0", "winston-daily-rotate-file": "^4.7.1", "ws": "^8.13.0", @@ -54,7 +53,8 @@ "typescript": "^5.5.3", "webpack": "^5.88.2", "webpack-dev-middleware": "^6.1.1", - "webpack-merge": "^5.9.0" + "webpack-merge": "^5.9.0", + "webpack-cli": "^5.1.4" }, "publishConfig": { "access": "public" diff --git a/packages/controller/src/Controller.ts b/packages/controller/src/Controller.ts index f256da32..8ae227bc 100644 --- a/packages/controller/src/Controller.ts +++ b/packages/controller/src/Controller.ts @@ -95,7 +95,7 @@ export default class Controller { public shouldRestart: boolean = false; _fallbackedRequests: Map, lib.RequestHandler> = new Map(); _registeredRequests: Map, lib.RequestHandler> = new Map(); - _registeredEvents = new Map(); + _registeredEvents = new Map, lib.EventHandler>(); _snoopedEvents = new Map(); devMiddleware: any | null = null; diff --git a/packages/create/templates/common/package.json b/packages/create/templates/common/package.json index 346cce77..b05122b3 100644 --- a/packages/create/templates/common/package.json +++ b/packages/create/templates/common/package.json @@ -20,7 +20,7 @@ "devDependencies": { //%// Typescript and type declarations //%if typescript - "typescript": "^5.1.6", + "typescript": "^5.5.3", "@types/node": "^20.4.5", //%endif //%if typescript & web diff --git a/packages/lib/src/link/link.ts b/packages/lib/src/link/link.ts index ae91a4c8..236b5340 100644 --- a/packages/lib/src/link/link.ts +++ b/packages/lib/src/link/link.ts @@ -538,7 +538,7 @@ export class Link { if (!entry) { throw new Error(`Attempt to send unregistered Request ${request.constructor.name}`); } - if (this.connector.src.equals(dst)) { + if (this.connector.src.addressedTo(dst)) { throw new Error(`Message would return back to sender ${dst}.`); } if (this.validateSent) { @@ -575,7 +575,7 @@ export class Link { if (!entry) { throw new Error(`Attempt to send unregistered Event ${event.constructor.name}`); } - if (this.connector.src.equals(dst)) { + if (this.connector.src.addressedTo(dst)) { throw new Error(`Message would return back to sender ${dst}.`); } if (this.validateSent) { From 70cf680eddff8f3ca628a573ba098abb51d5f39d Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Thu, 29 Aug 2024 21:04:34 +0200 Subject: [PATCH 37/43] Escape arguments when installer invokes commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The usage of shell: true means that no escaping is done on the arguments passed to the commands invoked by the installer. This leads to the installation failing if the user for example puts a space in the username for the admin account. Fix by escaping the arguments passed on command lines. This is unreasonably complicated on Windows 😡. --- packages/create/create.js | 25 ++++++++---- packages/create/escape_arg.js | 62 ++++++++++++++++++++++++++++++ test/create/echo_args.js | 4 ++ test/create/escape_arg.js | 71 +++++++++++++++++++++++++++++++++++ test/create/forward_args.cmd | 3 ++ test/create/forward_args.sh | 3 ++ 6 files changed, 161 insertions(+), 7 deletions(-) create mode 100644 packages/create/escape_arg.js create mode 100644 test/create/echo_args.js create mode 100644 test/create/escape_arg.js create mode 100644 test/create/forward_args.cmd create mode 100755 test/create/forward_args.sh diff --git a/packages/create/create.js b/packages/create/create.js index eda9364e..037c31c8 100755 --- a/packages/create/create.js +++ b/packages/create/create.js @@ -16,6 +16,7 @@ const { copyPluginTemplates } = require("./template"); let dev = false; const scriptExt = process.platform === "win32" ? ".cmd" : ""; const finished = util.promisify(stream.finished); +const { escapeArg } = require("./escape_arg"); // I hate this, there is a bug with rl.close on windows that was meant to have been fixed in Node14.4 // See nodejs/node#21771 and nodejs/node#30701 for the apparent fix that was applied @@ -106,15 +107,25 @@ async function safeOutputFile(file, data, options={}) { } async function execFile(cmd, args) { - logger.verbose(`executing ${cmd} ${args.join(" ")}`); + const escaped = args.map(escapeArg); + logger.verbose(`executing ${cmd} ${escaped.join(" ")}`); return new Promise((resolve, reject) => { - let child = child_process.execFile(cmd, args, { shell: true }, (err, stdout, stderr) => { - if (err) { - reject(err); - } else { - resolve({ stdout, stderr }); + let child = child_process.execFile( + cmd, + escaped, + { + shell: true, + // eslint-disable-next-line node/no-process-env + env: process.platform === "win32" ? { ...process.env, pct: "%" } : undefined, + }, + (err, stdout, stderr) => { + if (err) { + reject(err); + } else { + resolve({ stdout, stderr }); + } } - }); + ); let stdout = new LineSplitter({ readableObjectMode: true }); stdout.on("data", line => { logger.verbose(line.toString()); }); child.stdout.pipe(stdout); diff --git a/packages/create/escape_arg.js b/packages/create/escape_arg.js new file mode 100644 index 00000000..143257d2 --- /dev/null +++ b/packages/create/escape_arg.js @@ -0,0 +1,62 @@ +"use strict"; + +function escapeArg(arg) { + // When shell: true is used execFile does not escaping of arguments, they are + // simply joined by space and then passed to the shell. + + // For Windows the command is cmd.exe /d /s /c "command arg arg ..." + // The parsing and escaping on windows is cursed. The following references are not for mortals: + // https://daviddeley.com/autohotkey/parameters/parameters.htm#WIN + // https://stackoverflow.com/a/4095133 + // https://ss64.com/nt/syntax-esc.html + if (process.platform === "win32") { + if (!/[\t "%&<>\\^|]/.test(arg)) { + return arg; + } + + const escaped = []; + let pos = 0; + while (pos < arg.length) { + if (arg[pos] === "\\") { + // If a backslash is followed by a quote or the end of the string, then + // double the number of backslashes because why not! + let peek = pos + 1; + while (peek !== arg.length && arg[peek] === "\\") { + peek += 1; + } + if (peek === arg.length || arg[peek] === '"') { + const count = peek - pos; + escaped.push("\\".repeat(count * 2)); + pos = peek; + continue; + } else { + escaped.push("\\"); + } + } else if (arg[pos] === '"') { + escaped.push('""'); + } else if (arg[pos] === "%") { + // Expect a pct environment variable to contain %, because cmd does variable substitutions + // before parsing string quotes, and there's no mechanism for escaping % symbols, and this + // is a half sane workaround. The less sane workaround is to replace % with %%cd:~,%. + escaped.push("%pct%"); + } else { + escaped.push(arg[pos]); + } + pos += 1; + } + return `"${escaped.join("")}"`; + } + + // For all other platforms the command is /bin/sh -c + // The command and its arguments are passed as a single argument to the shell. + // See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02 + // eslint-disable-next-line no-lonely-if + if (!/[|&;<>()$`\\"' \t*?\[#~=%]/.test(arg)) { + return arg; + } + return `"${arg.replace(/[$`"\\]/g, "\\$&")}"`; +} + +module.exports = { + escapeArg, +}; diff --git a/test/create/echo_args.js b/test/create/echo_args.js new file mode 100644 index 00000000..1319b1cf --- /dev/null +++ b/test/create/echo_args.js @@ -0,0 +1,4 @@ +"use strict"; +if (module === require.main) { + process.stdout.write(JSON.stringify(process.argv.slice(2))); +} diff --git a/test/create/escape_arg.js b/test/create/escape_arg.js new file mode 100644 index 00000000..808036c5 --- /dev/null +++ b/test/create/escape_arg.js @@ -0,0 +1,71 @@ +"use strict"; +const child_process = require("child_process"); +const util = require("util"); +const assert = require("assert").strict; +const path = require("path"); + +const { escapeArg } = require("../../packages/create/escape_arg"); +const execFile = util.promisify(child_process.execFile); + +async function exec(file, args) { + const { stdout, stderr } = await execFile( + file, + args.map(escapeArg), + // eslint-disable-next-line node/no-process-env + { shell: true, cwd: __dirname, env: { ...process.env, pct: "%"} } + ); + return { stdout: JSON.parse(stdout), stderr }; +} + +const strings = [ + '"a"', + "a sentence of text.", + " irregular \tspaces ", + '"C:\\path\\"', + "C:\\path\\", + '\\ "\\" \\\\ "\\\\" \\\\\\ "\\\\\\" \\\\\\\\ "\\\\\\\\" \\\\\\\\\\ "\\\\\\\\\\" \\\\\\\\\\\ "\\\\\\\\\\\\"', + '"C:\\path"', + "C:\\path", + "%OS%", + "!OS!", + "😮", +]; +for (let i=1; i < 128; i++) { + const char = String.fromCodePoint(i); + // Skip newline and carriage return because those are difficult to escape + // Skip most alphanumeric characters as they don't behave differently to each other. + if (/[\n\r1-9B-Zb-z]/.test(char)) { + continue; + } + strings.push(char, `${char}${char}`, `${char}"`); +} + +// Test 100 strings at a time. +const tests = [[]]; +for (const string of strings) { + if (tests[tests.length - 1].length >= 100) { + tests.push([]); + } + tests[tests.length - 1].push(string); +} + + +describe("create/escape_arg", function() { + it("should correctly escape strings when args are forwarded", async function() { + const ext = process.platform === "win32" ? ".cmd" : ".sh"; + for (const args of tests) { + assert.deepEqual( + await exec(`.${path.sep}forward_args${ext}`, ["echo_args.js", ...args]), + { stdout: args, stderr: "" } + ); + } + }); + it("should correctly escape strings when invoking node directly", async function() { + for (const args of tests) { + assert.deepEqual( + await exec("node", ["echo_args.js", ...args]), + { stdout: args, stderr: "" } + ); + } + }); +}); diff --git a/test/create/forward_args.cmd b/test/create/forward_args.cmd new file mode 100644 index 00000000..fc77d29c --- /dev/null +++ b/test/create/forward_args.cmd @@ -0,0 +1,3 @@ +@ECHO off +REM this is how npm and package.json bin entries forwards arguments on Windows +node.exe %* diff --git a/test/create/forward_args.sh b/test/create/forward_args.sh new file mode 100755 index 00000000..f7044d7f --- /dev/null +++ b/test/create/forward_args.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# this is how package.json bin entries forwards arguments on Linux +exec node "$@" From 0cd24d120cea49965b38fab7caca4c447cd625f6 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Fri, 30 Aug 2024 00:58:34 +0200 Subject: [PATCH 38/43] Install optional dependencies on CI The @swc/core module depends on optional dependencies being installed in order to get the correct native binding's package installed. Remove --no-optional flag passed to pnpm to install these. --- .github/workflows/node.js.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 69a7fa1f..189c0dec 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -24,7 +24,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - - run: pnpm i --no-optional --no-frozen-lockfile + - run: pnpm i --no-frozen-lockfile - run: wget -q -O factorio.tar.gz https://www.factorio.com/get-download/latest/headless/linux64 && tar -xf factorio.tar.gz && rm factorio.tar.gz - name: Run tests if: ${{ matrix.node-version != '18.x' }} @@ -49,5 +49,5 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 18.x - - run: pnpm i --no-optional --no-frozen-lockfile + - run: pnpm i --no-frozen-lockfile - run: pnpm run lint From 0b50a6a29e50e9c6c149969b59907aaefd28ddf3 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Mon, 2 Sep 2024 22:43:53 +0200 Subject: [PATCH 39/43] Add changelog entry for #652 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66319a98..7ab5d832 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ Many thanks to the following for contributing to this release: - Fixed IPC errors reporting undefined when no stack trace was present [#624](https://github.com/clusterio/clusterio/pull/624). - Fixed loopback routing for instances reporting the wrong error message [#625](https://github.com/clusterio/clusterio/pull/625). - Bumped Typescript version to 5.5 and implemented `${configDir}` in base configs for "outDir" [#648](https://github.com/clusterio/clusterio/pull/648). +- Fixed spaces passed in arguments to the installer causing it to break [#620](https://github.com/clusterio/clusterio/issues/620) ### Breaking Changes @@ -37,6 +38,7 @@ Many thanks to the following for contributing to this release: Many thanks to the following for contributing to this release: [@Cooldude2606](https://github.com/Cooldude2606) +[@Hornwitser](https://github.com/Hornwitser) ## Version 2.0.0-alpha.18 From 5215ee8eefe3a896c44b1ef3652425bc8cc7f040 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Tue, 30 Jul 2024 23:09:33 +0100 Subject: [PATCH 40/43] Include mono repo plugins in build --- clean.js | 4 +++- package.json | 3 ++- pnpm-workspace.yaml | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/clean.js b/clean.js index f7d0a0e5..1a94d74d 100644 --- a/clean.js +++ b/clean.js @@ -12,7 +12,9 @@ const fs = require("fs-extra"); const yargs = require("yargs"); const npmPackage = require("./package.json"); -const workspaces = npmPackage.workspaces.map(p => p.slice(0, -2)); +const workspaces = npmPackage.workspaces + .map(p => p.slice(0, -2)) + .filter(p => !p.includes("external_plugins")); let DRY = false; diff --git a/package.json b/package.json index 985bbc79..34397619 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,8 @@ "workspaces": [ "packages/*", "plugins/*", - "external_plugins/*" + "external_plugins/*", + "external_plugins/*/*" ], "devDependencies": { "@clusterio/controller": "workspace:*", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a74adfca..fd9fdcd3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,4 +2,5 @@ packages: - "packages/*" - "plugins/*" - "external_plugins/*" + - "external_plugins/*/*" - "test/" From 7db582196764395f35a52d0e3a811b075dc21a2f Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Mon, 2 Sep 2024 22:06:40 +0100 Subject: [PATCH 41/43] Update change log and publish steps (#646) --- CHANGELOG.md | 14 ++++++++++++++ docs/contributing.md | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ab5d832..9650040b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,10 +25,22 @@ Many thanks to the following for contributing to this release: ## Version 2.0.0-alpha.19 +### Features + +- Added clean script to speed up publishing and debugging of build steps [#640](https://github.com/clusterio/clusterio/pull/640). +- Added sub-tile option on plugin page headers [#642](https://github.com/clusterio/clusterio/pull/642). +- Greatly improved plugin and module template generation [#641](https://github.com/clusterio/clusterio/pull/641). + ### Changes +- Added tests for sendEvent and sendRequest throwing the correct error messages [#638](https://github.com/clusterio/clusterio/pull/638). +- Updated all web ui pages to use correct page header component [#643](https://github.com/clusterio/clusterio/pull/643). - Fixed IPC errors reporting undefined when no stack trace was present [#624](https://github.com/clusterio/clusterio/pull/624). - Fixed loopback routing for instances reporting the wrong error message [#625](https://github.com/clusterio/clusterio/pull/625). +- Fixed docs linking to non-existing js files after ts migration [#633](https://github.com/clusterio/clusterio/pull/633). +- Fixed CI workflows using deprecated version of nodejs [#637](https://github.com/clusterio/clusterio/pull/637). +- Fixed test running on windows that should be linux only [#628](https://github.com/clusterio/clusterio/pull/628). +- Fixed log events being sent from a host over an invalid websocket [#639](https://github.com/clusterio/clusterio/pull/639). - Bumped Typescript version to 5.5 and implemented `${configDir}` in base configs for "outDir" [#648](https://github.com/clusterio/clusterio/pull/648). - Fixed spaces passed in arguments to the installer causing it to break [#620](https://github.com/clusterio/clusterio/issues/620) @@ -38,7 +50,9 @@ Many thanks to the following for contributing to this release: Many thanks to the following for contributing to this release: [@Cooldude2606](https://github.com/Cooldude2606) +[@Danielv123](https://github.com/Danielv123) [@Hornwitser](https://github.com/Hornwitser) +[@Laar](https://github.com/Laar) ## Version 2.0.0-alpha.18 diff --git a/docs/contributing.md b/docs/contributing.md index 9a4ef6a9..e7cabcf4 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -319,6 +319,6 @@ You will need commit access to the repository as well publish access to the @clu 4. Publish the packages. ```sh - rm -r ./{plugins,packages}/*/dist + pnpm clean pnpm -r --filter='./{plugins,packages}/*' publish ``` From 55fcd90ed23d148c81d9c10966286115e15d925f Mon Sep 17 00:00:00 2001 From: Arvids Godjuks Date: Tue, 3 Sep 2024 01:13:49 +0300 Subject: [PATCH 42/43] Fix bootstrap command missing type declaration for admin name Lack of typing was resulting in admin name being serialized to storage as a number and breaking websocket communications protocol due to type mismatch: expected string, got number. Fixes #536 --- CHANGELOG.md | 2 ++ packages/controller/controller.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9650040b..b46d098a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ Many thanks to the following for contributing to this release: - Fixed log events being sent from a host over an invalid websocket [#639](https://github.com/clusterio/clusterio/pull/639). - Bumped Typescript version to 5.5 and implemented `${configDir}` in base configs for "outDir" [#648](https://github.com/clusterio/clusterio/pull/648). - Fixed spaces passed in arguments to the installer causing it to break [#620](https://github.com/clusterio/clusterio/issues/620) +- Fixed numeric admin name breaking login [#536](https://github.com/clusterio/clusterio/issues/536) ### Breaking Changes @@ -53,6 +54,7 @@ Many thanks to the following for contributing to this release: [@Danielv123](https://github.com/Danielv123) [@Hornwitser](https://github.com/Hornwitser) [@Laar](https://github.com/Laar) +[@psihius](https://github.com/psihius) ## Version 2.0.0-alpha.18 diff --git a/packages/controller/controller.ts b/packages/controller/controller.ts index b4161f65..4b59b18c 100644 --- a/packages/controller/controller.ts +++ b/packages/controller/controller.ts @@ -248,8 +248,12 @@ async function initialize(): Promise { .command("config", "Manage Controller config", lib.configCommand) .command("bootstrap", "Bootstrap access to cluster", yargs => { yargs - .command("create-admin ", "Create a cluster admin") - .command("generate-user-token ", "Generate authentication token for the given user") + .command("create-admin ", "Create a cluster admin", yargs => { + yargs.positional("name", { describe: "Name of the admin user", type: "string" }); + }) + .command("generate-user-token ", "Generate authentication token for the given user", yargs => { + yargs.positional("name", { describe: "Name of the user", type: "string" }); + }) .command("generate-host-token ", "Generate authentication token for the given host", yargs => { yargs.positional("id", { describe: "ID of the host", type: "number" }); }) From 47896247fea392943d88b13dc1717978c777bb42 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Tue, 3 Sep 2024 01:04:50 +0200 Subject: [PATCH 43/43] Add option to set path to server executable (#657) Allow overriding the logic selecting the path to the Factorio executable. This is mainly useful when working with development versions of the game. --- CHANGELOG.md | 1 + packages/host/src/Instance.ts | 1 + packages/host/src/server.ts | 11 ++++++++++- packages/lib/src/config/definitions.ts | 9 +++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b46d098a..4a0c6669 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ Many thanks to the following for contributing to this release: - Bumped Typescript version to 5.5 and implemented `${configDir}` in base configs for "outDir" [#648](https://github.com/clusterio/clusterio/pull/648). - Fixed spaces passed in arguments to the installer causing it to break [#620](https://github.com/clusterio/clusterio/issues/620) - Fixed numeric admin name breaking login [#536](https://github.com/clusterio/clusterio/issues/536) +- Added factorio.executable_path option which allows overriding the default path to the Factorio executable run. ### Breaking Changes diff --git a/packages/host/src/Instance.ts b/packages/host/src/Instance.ts index f6163611..7452ece5 100644 --- a/packages/host/src/Instance.ts +++ b/packages/host/src/Instance.ts @@ -169,6 +169,7 @@ export default class Instance extends lib.Link { let serverOptions = { logger: this.logger, version: this.config.get("factorio.version"), + executablePath: this.config.get("factorio.executable_path") ?? undefined, gamePort: this.config.get("factorio.game_port") ?? host.assignGamePort(this.id), rconPort: this.config.get("factorio.rcon_port") ?? undefined, rconPassword: this.config.get("factorio.rcon_password") ?? undefined, diff --git a/packages/host/src/server.ts b/packages/host/src/server.ts index 48c401b2..aa438c8f 100644 --- a/packages/host/src/server.ts +++ b/packages/host/src/server.ts @@ -407,6 +407,8 @@ export interface FactorioServerOptions { * the latest version found in `factorioDir`. */ version?: string, + /** Path to executable to invoke when starting the server */ + executablePath?: string; /** UDP port to host game on. */ gamePort?: number, /** TCP port to use for RCON. */ @@ -450,6 +452,8 @@ export interface FactorioServerOptions { * @extends events.EventEmitter */ export class FactorioServer extends events.EventEmitter { + /** Path to executable to invoke when starting the server */ + executablePath?: string; /** UDP port used for hosting the Factorio game server on */ gamePort: number; /** TCP port used for RCON on the Factorio game server */ @@ -504,6 +508,7 @@ export class FactorioServer extends events.EventEmitter { this._logger = options.logger || lib.logger; this._targetVersion = options.version || "latest"; + this.executablePath = options.executablePath; /** UDP port used for hosting the Factorio game server on */ this.gamePort = options.gamePort || randomDynamicPort(); /** TCP port used for RCON on the Factorio game server */ @@ -1155,11 +1160,15 @@ export class FactorioServer extends events.EventEmitter { /** * Get Factorio binary path * - * Get the path to the factorio binary depending on the platform (MacOS support) + * Get the path to the factorio binary depending on the configuration + * and or the platform (MacOS support) * * @returns Path to factorio binary */ binaryPath() { + if (this.executablePath) { + return this.dataPath("..", this.executablePath); + } if (process.platform === "darwin") { return this.dataPath("..", "MacOS", "factorio"); } diff --git a/packages/lib/src/config/definitions.ts b/packages/lib/src/config/definitions.ts index 445a66ad..3079e5a7 100644 --- a/packages/lib/src/config/definitions.ts +++ b/packages/lib/src/config/definitions.ts @@ -261,6 +261,7 @@ export interface InstanceConfigFields { "instance.auto_start": boolean; "factorio.version": string; + "factorio.executable_path": string | null; "factorio.game_port": number | null; "factorio.host_assigned_game_port": number | null; "factorio.rcon_port": number | null; @@ -311,6 +312,14 @@ export class InstanceConfig extends classes.Config { type: "string", initialValue: "latest", }, + "factorio.executable_path": { + description: + "Relative path from the Factorio installation directory to the executable to run. " + + "Defaults to auto detect the path, only needed in special setups.", + restartRequired: true, + type: "string", + optional: true, + }, "factorio.game_port": { description: "UDP port to run game on, uses a port in host.factorio_port_range if null", restartRequired: true,