From c3a1b420eacace9b1dcff1e241c48dcaf286982b Mon Sep 17 00:00:00 2001 From: bbassie Date: Thu, 4 Nov 2021 01:36:56 +0100 Subject: [PATCH 01/13] Added InstanceStatusTag react component - Modified InstanceList & InstanceViewPage to use it --- .../web_ui/src/components/InstanceList.jsx | 2 ++ .../src/components/InstanceStatusTag.jsx | 21 +++++++++++++++++++ .../src/components/InstanceViewPage.jsx | 3 ++- 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 packages/web_ui/src/components/InstanceStatusTag.jsx diff --git a/packages/web_ui/src/components/InstanceList.jsx b/packages/web_ui/src/components/InstanceList.jsx index 4a010ffa..39f77156 100644 --- a/packages/web_ui/src/components/InstanceList.jsx +++ b/packages/web_ui/src/components/InstanceList.jsx @@ -3,6 +3,7 @@ import { useHistory } from "react-router-dom"; import { Table } from "antd"; import { useSlaveList } from "../model/slave"; +import InstanceStatusTag from "./InstanceStatusTag"; const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "base" }).compare; @@ -35,6 +36,7 @@ export default function InstanceList(props) { { title: "Status", dataIndex: "status", + render: status => , sorter: (a, b) => strcmp(a["status"], b["status"]), }, ]; diff --git a/packages/web_ui/src/components/InstanceStatusTag.jsx b/packages/web_ui/src/components/InstanceStatusTag.jsx new file mode 100644 index 00000000..d3418fcf --- /dev/null +++ b/packages/web_ui/src/components/InstanceStatusTag.jsx @@ -0,0 +1,21 @@ +import { Tag } from "antd"; +import React from "react"; + +const statusColors = { + unknown: "#d46b08", + unassigned: "#d4380d", + stopped: "#cf1322", + starting: "#7cb305", + running: "#389e0d", + stopping: "#d48806", + creating_save: "#096dd9", + exporting_data: "#08979c", + deleted: "#cf1322", +}; + + +export default function InstanceStatusTag(props) { + return + {props.status} + ; +} diff --git a/packages/web_ui/src/components/InstanceViewPage.jsx b/packages/web_ui/src/components/InstanceViewPage.jsx index c5a27cb5..58384ab4 100644 --- a/packages/web_ui/src/components/InstanceViewPage.jsx +++ b/packages/web_ui/src/components/InstanceViewPage.jsx @@ -18,6 +18,7 @@ import SavesList from "./SavesList"; import { notifyErrorHandler } from "../util/notify"; import { useInstance } from "../model/instance"; import { useSlave } from "../model/slave"; +import InstanceStatusTag from "./InstanceStatusTag"; const { Title, Paragraph } = Typography; @@ -116,7 +117,7 @@ export default function InstanceViewPage(props) { buttonContent={assigned ? "Reassign" : "Assign"} />} - {instance["status"]} + { From 83b720eade77f6737f1bb9616304e035f815ba4a Mon Sep 17 00:00:00 2001 From: bbassie Date: Thu, 4 Nov 2021 01:39:28 +0100 Subject: [PATCH 02/13] Added public_address field to lists - InstanceList - SlavesPage Added public_address field to messages - slaveProperties - instanceProperties --- packages/lib/link/messages.js | 2 ++ packages/lib/schema.js | 1 + packages/master/src/ControlConnection.js | 4 ++++ packages/master/src/Master.js | 1 + packages/master/src/SlaveConnection.js | 1 + packages/slave/slave.js | 1 + packages/web_ui/src/components/InstanceList.jsx | 17 ++++++++++++++++- packages/web_ui/src/components/SlavesPage.jsx | 13 +++++++++++-- 8 files changed, 37 insertions(+), 3 deletions(-) diff --git a/packages/lib/link/messages.js b/packages/lib/link/messages.js index 5a13f6dd..b09e3134 100644 --- a/packages/lib/link/messages.js +++ b/packages/lib/link/messages.js @@ -337,6 +337,7 @@ let slaveProperties = { "name": { type: "string" }, "id": { type: "integer" }, "connected": { type: "boolean" }, + "public_address": { type: ["null", "string"] }, }; messages.listSlaves = new Request({ @@ -372,6 +373,7 @@ let instanceProperties = { "name": { type: "string" }, "id": { type: "integer" }, "assigned_slave": { type: ["null", "integer"] }, + "game_port": { type: ["null", "integer"] }, "status": { enum: [ "unknown", "unassigned", "stopped", "starting", "running", "stopping", "creating_save", "exporting_data", "deleted", diff --git a/packages/lib/schema.js b/packages/lib/schema.js index da43a843..17157876 100644 --- a/packages/lib/schema.js +++ b/packages/lib/schema.js @@ -178,6 +178,7 @@ const clientHandshake = ajv.compile({ "version": { type: "string" }, "name": { type: "string" }, "id": { type: "integer" }, + "public_address": { type: "string" }, "plugins": { type: "object", additionalProperties: { type: "string" }, diff --git a/packages/master/src/ControlConnection.js b/packages/master/src/ControlConnection.js index 69e1f5e9..dfc07981 100644 --- a/packages/master/src/ControlConnection.js +++ b/packages/master/src/ControlConnection.js @@ -106,6 +106,7 @@ class ControlConnection extends BaseConnection { version: slave.version, id: slave.id, name: slave.name, + public_address: slave.public_address, connected: this._master.wsServer.slaveConnections.has(slave.id), }); } @@ -169,6 +170,7 @@ class ControlConnection extends BaseConnection { id, name: instance.config.get("instance.name"), assigned_slave: instance.config.get("instance.assigned_slave"), + game_port: instance.config.get("factorio.game_port"), status: instance.status, }; } @@ -180,6 +182,7 @@ class ControlConnection extends BaseConnection { id: instance.config.get("instance.id"), name: instance.config.get("instance.name"), assigned_slave: instance.config.get("instance.assigned_slave"), + game_port: instance.config.get("factorio.game_port"), status: instance.status, }); } @@ -199,6 +202,7 @@ class ControlConnection extends BaseConnection { id: instance.config.get("instance.id"), name: instance.config.get("instance.name"), assigned_slave: instance.config.get("instance.assigned_slave"), + game_port: instance.config.get("factorio.game_port"), status: instance.status, }); } diff --git a/packages/master/src/Master.js b/packages/master/src/Master.js index c4f2ee6e..72b525a7 100644 --- a/packages/master/src/Master.js +++ b/packages/master/src/Master.js @@ -368,6 +368,7 @@ class Master { version: slave.version, id: slave.id, name: slave.name, + public_address: slave.public_address, connected: this.wsServer.slaveConnections.has(slave.id), }; diff --git a/packages/master/src/SlaveConnection.js b/packages/master/src/SlaveConnection.js index 6c2319dd..dde922d1 100644 --- a/packages/master/src/SlaveConnection.js +++ b/packages/master/src/SlaveConnection.js @@ -28,6 +28,7 @@ class SlaveConnection extends BaseConnection { id: this._id, name: this._name, version: this._version, + public_address: registerData.public_address, plugins: registerData.plugins, }); diff --git a/packages/slave/slave.js b/packages/slave/slave.js index ddf0cd32..222c6687 100755 --- a/packages/slave/slave.js +++ b/packages/slave/slave.js @@ -1004,6 +1004,7 @@ class SlaveConnector extends libLink.WebSocketClientConnector { version, id: this.slaveConfig.get("slave.id"), name: this.slaveConfig.get("slave.name"), + public_address: this.slaveConfig.get("slave.public_address"), plugins, }); } diff --git a/packages/web_ui/src/components/InstanceList.jsx b/packages/web_ui/src/components/InstanceList.jsx index 39f77156..c5eb002a 100644 --- a/packages/web_ui/src/components/InstanceList.jsx +++ b/packages/web_ui/src/components/InstanceList.jsx @@ -19,7 +19,13 @@ export default function InstanceList(props) { } return String(slaveId); } - + function slavePublicAddress(slaveId) { + let slave = slaveList.find(s => s.id === slaveId); + if (slave) { + return slave.public_address; + } + return null; + } let columns = [ { title: "Name", @@ -33,6 +39,15 @@ export default function InstanceList(props) { render: instance => slaveName(instance["assigned_slave"]), sorter: (a, b) => strcmp(slaveName(a["assigned_slave"]), slaveName(b["assigned_slave"])), }, + { + title: "Public address", + key: "public_address", + render: instance => { + let address = slavePublicAddress(instance["assigned_slave"]); + return address ? `${address}:${instance["game_port"] || "unknown"}` : ""; + }, + sorter: (a, b) => strcmp(slavePublicAddress(a["assigned_slave"]), slavePublicAddress(b["assigned_slave"])), + }, { title: "Status", dataIndex: "status", diff --git a/packages/web_ui/src/components/SlavesPage.jsx b/packages/web_ui/src/components/SlavesPage.jsx index 9333752a..24cb17ed 100644 --- a/packages/web_ui/src/components/SlavesPage.jsx +++ b/packages/web_ui/src/components/SlavesPage.jsx @@ -1,6 +1,6 @@ import React, { useContext, useRef, useState } from "react"; import { useHistory } from "react-router-dom"; -import { Button, Form, Input, Modal, PageHeader, Table } from "antd"; +import { Button, Form, Input, Modal, PageHeader, Table, Tag } from "antd"; import { libLink } from "@clusterio/lib"; @@ -104,10 +104,19 @@ export default function SlavesPage() { dataIndex: "version", sorter: (a, b) => strcmp(a["version"], b["version"]), }, + { + title: "Public address", + dataIndex: "public_address", + sorter: (a, b) => strcmp(a["public_address"], b["public_address"]), + }, { title: "Connected", key: "connected", - render: slave => slave["connected"] && "Yes", + render: slave => + {slave["connected"] ? "Connected" : "Disconnected"} + , sorter: (a, b) => a["connected"] - b["connected"], }, ]} From f930ed36a0f611fe291301781e467bc447a92cce Mon Sep 17 00:00:00 2001 From: bbassie Date: Thu, 4 Nov 2021 21:29:53 +0100 Subject: [PATCH 03/13] Changed to using the real factorio port --- packages/lib/link/messages.js | 1 + packages/master/src/ControlConnection.js | 6 +++--- packages/master/src/SlaveConnection.js | 1 + packages/slave/slave.js | 5 ++++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/lib/link/messages.js b/packages/lib/link/messages.js index b09e3134..5aa971e8 100644 --- a/packages/lib/link/messages.js +++ b/packages/lib/link/messages.js @@ -1152,6 +1152,7 @@ messages.instanceStatusChanged = new Event({ "status": { enum: [ "stopped", "starting", "running", "stopping", "creating_save", "exporting_data", ]}, + "game_port": { type: ["null", "integer"] }, }, }); diff --git a/packages/master/src/ControlConnection.js b/packages/master/src/ControlConnection.js index dfc07981..d00a1e2d 100644 --- a/packages/master/src/ControlConnection.js +++ b/packages/master/src/ControlConnection.js @@ -170,7 +170,7 @@ class ControlConnection extends BaseConnection { id, name: instance.config.get("instance.name"), assigned_slave: instance.config.get("instance.assigned_slave"), - game_port: instance.config.get("factorio.game_port"), + game_port: instance.game_port, status: instance.status, }; } @@ -182,7 +182,7 @@ class ControlConnection extends BaseConnection { id: instance.config.get("instance.id"), name: instance.config.get("instance.name"), assigned_slave: instance.config.get("instance.assigned_slave"), - game_port: instance.config.get("factorio.game_port"), + game_port: instance.game_port, status: instance.status, }); } @@ -202,7 +202,7 @@ class ControlConnection extends BaseConnection { id: instance.config.get("instance.id"), name: instance.config.get("instance.name"), assigned_slave: instance.config.get("instance.assigned_slave"), - game_port: instance.config.get("factorio.game_port"), + game_port: instance.game_port, status: instance.status, }); } diff --git a/packages/master/src/SlaveConnection.js b/packages/master/src/SlaveConnection.js index dde922d1..a8e1e456 100644 --- a/packages/master/src/SlaveConnection.js +++ b/packages/master/src/SlaveConnection.js @@ -88,6 +88,7 @@ class SlaveConnection extends BaseConnection { let prev = instance.status; instance.status = message.data.status; + instance.game_port = message.data.game_port; logger.verbose(`Instance ${instance.config.get("instance.name")} State: ${instance.status}`); this._master.instanceUpdated(instance); await libPlugin.invokeHook(this._master.plugins, "onInstanceStatusChanged", instance, prev); diff --git a/packages/slave/slave.js b/packages/slave/slave.js index 222c6687..99c9988c 100755 --- a/packages/slave/slave.js +++ b/packages/slave/slave.js @@ -260,7 +260,9 @@ class Instance extends libLink.Link { notifyStatus(status) { this._status = status; libLink.messages.instanceStatusChanged.send(this, { - instance_id: this.id, status, + instance_id: this.id, + status, + game_port: this.server ? this.server.gamePort : this.config.get("factorio.game_port") || null, }); } @@ -1297,6 +1299,7 @@ class Slave extends libLink.Link { libLink.messages.instanceStatusChanged.send(this, { instance_id, status: instanceConnection ? instanceConnection.status : "stopped", + game_port: null, }); // save a copy of the instance config From 2e5617c4b52a7938ad2bdc0060671749042f8885 Mon Sep 17 00:00:00 2001 From: bbassie Date: Thu, 4 Nov 2021 22:25:36 +0100 Subject: [PATCH 04/13] Fix instance port and status update Master was not recieving instance status after restart. Instead only a status from the slave but the slave doesn't store the full instance status. --- packages/master/src/ControlConnection.js | 6 +++--- packages/slave/slave.js | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/master/src/ControlConnection.js b/packages/master/src/ControlConnection.js index d00a1e2d..5ac4990f 100644 --- a/packages/master/src/ControlConnection.js +++ b/packages/master/src/ControlConnection.js @@ -170,7 +170,7 @@ class ControlConnection extends BaseConnection { id, name: instance.config.get("instance.name"), assigned_slave: instance.config.get("instance.assigned_slave"), - game_port: instance.game_port, + game_port: instance.game_port || null, status: instance.status, }; } @@ -182,7 +182,7 @@ class ControlConnection extends BaseConnection { id: instance.config.get("instance.id"), name: instance.config.get("instance.name"), assigned_slave: instance.config.get("instance.assigned_slave"), - game_port: instance.game_port, + game_port: instance.game_port || null, status: instance.status, }); } @@ -202,7 +202,7 @@ class ControlConnection extends BaseConnection { id: instance.config.get("instance.id"), name: instance.config.get("instance.name"), assigned_slave: instance.config.get("instance.assigned_slave"), - game_port: instance.game_port, + game_port: instance.game_port || null, status: instance.status, }); } diff --git a/packages/slave/slave.js b/packages/slave/slave.js index 99c9988c..b6f49f40 100755 --- a/packages/slave/slave.js +++ b/packages/slave/slave.js @@ -694,6 +694,8 @@ class Instance extends libLink.Link { } async masterConnectionEventEventHandler(message) { + this.notifyStatus(this._status); + await libPlugin.invokeHook(this.plugins, "onMasterConnectionEvent", message.data.event); } From 69d4a883ad63dbf8cd955dc5e331598560cd703f Mon Sep 17 00:00:00 2001 From: bbassie Date: Thu, 4 Nov 2021 22:25:53 +0100 Subject: [PATCH 05/13] Add copy public address button --- .../web_ui/src/components/InstanceList.jsx | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/web_ui/src/components/InstanceList.jsx b/packages/web_ui/src/components/InstanceList.jsx index c5eb002a..2a3e33fd 100644 --- a/packages/web_ui/src/components/InstanceList.jsx +++ b/packages/web_ui/src/components/InstanceList.jsx @@ -1,13 +1,13 @@ import React from "react"; import { useHistory } from "react-router-dom"; -import { Table } from "antd"; +import { notification, Button, Table } from "antd"; +import { CopyOutlined } from "@ant-design/icons"; import { useSlaveList } from "../model/slave"; import InstanceStatusTag from "./InstanceStatusTag"; const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "base" }).compare; - export default function InstanceList(props) { let history = useHistory(); let [slaveList] = useSlaveList(); @@ -44,7 +44,22 @@ export default function InstanceList(props) { key: "public_address", render: instance => { let address = slavePublicAddress(instance["assigned_slave"]); - return address ? `${address}:${instance["game_port"] || "unknown"}` : ""; + let full_address = address + (instance["game_port"] !== null ? `:${instance["game_port"]}` : ""); + return <> + {full_address} + + } + /> ; } From 15381ac260e5d2425bb02b9bce315bd98fbcfd58 Mon Sep 17 00:00:00 2001 From: bbassie Date: Tue, 16 Nov 2021 23:50:13 +0100 Subject: [PATCH 13/13] Final running status color update --- packages/web_ui/src/components/InstanceStatusTag.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web_ui/src/components/InstanceStatusTag.jsx b/packages/web_ui/src/components/InstanceStatusTag.jsx index e7ee06ad..cd37ca1b 100644 --- a/packages/web_ui/src/components/InstanceStatusTag.jsx +++ b/packages/web_ui/src/components/InstanceStatusTag.jsx @@ -6,7 +6,7 @@ const statusColors = { unassigned: "#eb2f96", stopped: "#cf1322", starting: "#ad8b00", - running: "#52c41a", + running: "#389e0d", stopping: "#d48806", creating_save: "#096dd9", exporting_data: "#08979c",