diff --git a/README.md b/README.md
index fba2754..33bf969 100644
--- a/README.md
+++ b/README.md
@@ -24,15 +24,22 @@ Substitute clusteriocontroller with clusteriohost or clusterioctl if this a dedi
Clone the repository in clusterio/external_plugins/
- cd clusterio
+ git clone https://github.com/clusterio/clusterio
+ cd clusterio/external_plugins
+ git clone https://github.com/Danielv123/gridworld
+ git clone https://github.com/clusterio/edge_transports
+ cd ..
pnpm install
- node packages/create --dev # Interactive
+
+Interactive:
+
+ node packages/create --dev
+
node packages/ctl plugin add ./external_plugins/gridworld
- pnpm install @clusterio/plugin-edge_transports -w
+ node packages/ctl plugin add ./external_plugins/edge_transports
pnpm install @hornwitser/server_select -w
- node packages/controller bootstrap create-ctl-config Danielv123
node packages/controller bootstrap create-admin Danielv123
- node packages/controller plugin add @clusterio/plugin-edge_transports
+ node packages/controller bootstrap create-ctl-config Danielv123
node packages/controller plugin add @hornwitser/server_select
node packages/controller plugin add ./plugins/global_chat
node packages/controller plugin add ./plugins/inventory_sync
@@ -51,8 +58,6 @@ Log into the webui with the token in token.txt and create a new host token with
node packages/host config set host.name "Host 1"
node packages/host config set host.public_address "localhost"
-Luacheck can be downloaded from https://github.com/mpeterv/luacheck/releases/download/0.23.0/luacheck.exe or `sudo apt install lua-check`
+Luacheck can be downloaded from https://github.com/mpeterv/luacheck/releases/download/0.23.0/luacheck.exe or `sudo apt install lua-check` or `brew install luacheck`
Put it in your `%path%` and run `luacheck ./module`
-
-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ1c2VyIiwidXNlciI6IkRhbmllbHYxMjMiLCJpYXQiOjE3MDcwNjYwNDR9.g9iiIDvhX8GrEWGQQYig_smOdf212dmst6HKg9LKU3g
\ No newline at end of file
diff --git a/gridworld.code-workspace b/gridworld.code-workspace
index d1a7542..7d96576 100644
--- a/gridworld.code-workspace
+++ b/gridworld.code-workspace
@@ -1,21 +1,24 @@
{
"folders": [
{
- "path": "."
+ "path": "." // Gridworld
},
{
- "path": "../.."
- }
+ "path": "../edge_transports" // Edge transports
+ },
+ {
+ "path": "../.." // Clusterio
+ },
],
"settings": {
- "prettier.useTabs": true,
"editor.insertSpaces": false
},
"extensions": {
"recommendations": [
"yzhang.markdown-all-in-one",
"github.copilot",
- "yinfei.luahelper"
+ "yinfei.luahelper",
+ "dbaeumer.vscode-eslint"
]
}
}
\ No newline at end of file
diff --git a/index.js b/index.js
index 1710c98..bd54ac8 100644
--- a/index.js
+++ b/index.js
@@ -61,44 +61,44 @@ module.exports = {
type: "number",
title: "Server position on X axis",
description: "Server position index along the X axis in the gridworld",
- initial_value: 1000,
+ initialValue: 1000,
},
"gridworld.grid_y_position": {
type: "number",
title: "Server position on Y axis",
description: "Server position index along the Y axis in the gridworld",
- initial_value: 1000,
+ initialValue: 1000,
},
"gridworld.grid_x_size": {
type: "number",
title: "Server size on X axis",
description: "Server size along the X axis",
- initial_value: 512,
+ initialValue: 512,
},
"gridworld.grid_y_size": {
type: "number",
title: "Server size on Y axis",
description: "Server size along the Y axis",
- initial_value: 512,
+ initialValue: 512,
},
"gridworld.is_lobby_server": {
type: "boolean",
title: "Server is a lobby server",
description: "Make this instance act as a lobby server for a gridworld",
- initial_value: false,
+ initialValue: false,
},
"gridworld.grid_id": {
type: "number",
title: "Grid ID",
description:
"Grid identifier - used to run multiple gridworlds on the same cluster",
- initial_value: 0,
+ initialValue: 0,
},
"gridworld.claimed_by_faction": {
type: "string",
title: "Claimed by faction",
description: "Faction that has claimed this server",
- initial_value: "",
+ initialValue: "",
},
},
@@ -108,20 +108,20 @@ module.exports = {
type: "number",
title: "Autosave Interval",
description: "Interval the gridworld data is autosaved at in seconds.",
- initial_value: 600, // 10 minutes
+ initialValue: 600, // 10 minutes
},
"gridworld.gridworld_seed": {
type: "number",
title: "Gridworld seed",
description: "Seed for servers created using gridworld generator",
- initial_value: 999,
+ initialValue: 999,
},
"gridworld.gridworld_map_exchange_string": {
type: "string",
title: "Gridworld map exchange string",
description:
"Map exchange string for servers created using gridworld generator",
- initial_value:
+ initialValue:
// eslint-disable-next-line max-len
">>>eNpjZGBk0GIAgwZ7EOZgSc5PzIHwDjiAMFdyfkFBapFuflEqsjBnclFpSqpufiaq4tS81NxK3aTEYqhiiMkcmUX5eegmsBaX5OehipQUpaYWw5wCwtylRYl5maW5EL0H7OGqGb+qrnZoaJFjAOH/9QwK//+DMJD1AGgjCDMwNoBVMwLFYIA1OSczLY2BQcERiJ1A0owMjNUi69wfVk0BMsFAzwHK+AAVOZAEE/GEMfwccEqpwBgmSOYYg8FnJAbE0hKQ/RBVHA4IBkSyBSTJyNj7duuC78cu2DH+Wfnxkm9Sgj2joavIuw9G6+yAkuwgfzLBiVkzQWAnzCsMMDMf2EOlbtoznj0DAm/sGVlBOkRAhIMFkDjgzczAKMAHZC3oARIKMgwwp9nBjBFxYEwDg28wnzyGMS7bo/sDGBA2IMPlQMQJEAG2EO4yRgjTod+B0UEeJiuJUALUb8SA7IYUhA9Pwqw9jGQ/mkMwIwLZH2giKg5YooELZGEKnHjBDHcNMDwvsMN4DvMdGJlBDJCqL0AxCA8kAzMKQgs4gIObmQEBPtgzuMX47gAAJhSjWw==<<<",
},
@@ -129,7 +129,7 @@ module.exports = {
type: "string",
title: "Tiles directory",
description: "Folder to store map tiles relative to database",
- initial_value: "tiles",
+ initialValue: "tiles",
},
},
diff --git a/messages.js b/messages.js
index a8213cc..49771ca 100644
--- a/messages.js
+++ b/messages.js
@@ -1,4 +1,5 @@
"use strict";
+const { plainJson } = require("@clusterio/lib");
const factionProperties = require("./src/factions/faction_message_properties");
const pluginName = "gridworld";
@@ -10,9 +11,6 @@ module.exports = {
static dst = "controller";
static plugin = pluginName;
static permission = "gridworld.create";
- constructor(data) {
- this.data = data;
- }
static jsonSchema = {
type: "object",
properties: {
@@ -23,6 +21,16 @@ module.exports = {
host: { type: "integer" }, // hostID to use for instance creation
},
};
+ constructor(json) {
+ this.name_prefix = json.name_prefix;
+ this.use_edge_transports = json.use_edge_transports;
+ this.x_size = json.x_size;
+ this.y_size = json.y_size;
+ this.host = json.host;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
},
GetMapData: class GetMapData {
static type = "request";
@@ -30,41 +38,39 @@ module.exports = {
static dst = "controller";
static plugin = pluginName;
static permission = "gridworld.overview.view";
- static Response = {
- jsonSchema: {
- type: "object",
- properties: {
- map_data: {
- type: "array",
- items: {
- type: "object",
- additionalProperties: false,
- properties: {
- instance_id: { type: "integer" },
- center: { type: "array", items: { type: "number" } },
- bounds: {
+ static Response = plainJson({
+ type: "object",
+ properties: {
+ map_data: {
+ type: "array",
+ items: {
+ type: "object",
+ additionalProperties: false,
+ properties: {
+ instance_id: { type: "integer" },
+ center: { type: "array", items: { type: "number" } },
+ bounds: {
+ type: "array",
+ items: {
type: "array",
- items: {
- type: "array",
- items: { type: "number" },
- },
+ items: { type: "number" },
},
- edges: {
- type: "array",
- items: {
- type: "object",
- properties: {
- id: { type: "integer" },
- origin: {
- type: "array",
- items: { type: "integer" },
- },
- surface: { type: "integer" },
- direction: { type: "integer" },
- length: { type: "integer" },
- target_instance: { type: "integer" },
- target_edge: { type: "integer" },
+ },
+ edges: {
+ type: "array",
+ items: {
+ type: "object",
+ properties: {
+ id: { type: "integer" },
+ origin: {
+ type: "array",
+ items: { type: "integer" },
},
+ surface: { type: "integer" },
+ direction: { type: "integer" },
+ length: { type: "integer" },
+ target_instance: { type: "integer" },
+ target_edge: { type: "integer" },
},
},
},
@@ -72,10 +78,7 @@ module.exports = {
},
},
},
- fromJson(data) {
- return data;
- },
- };
+ });
},
PopulateNeighborData: class PopulateNeighborData {
static type = "request";
@@ -91,6 +94,15 @@ module.exports = {
west: { type: ["integer", "null"] },
},
};
+ constructor(json) {
+ this.north = json.north;
+ this.south = json.south;
+ this.east = json.east;
+ this.west = json.west;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
},
UpdateEdgeTransportEdges: class UpdateEdgeTransportEdges {
static type = "request";
@@ -103,6 +115,12 @@ module.exports = {
instance_id: { type: "integer" },
},
};
+ constructor(json) {
+ this.instance_id = json.instance_id;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
},
TeleportPlayer: class TeleportPlayer {
static type = "request";
@@ -117,6 +135,14 @@ module.exports = {
y: { type: "number" },
},
};
+ constructor(json) {
+ this.player_name = json.player_name;
+ this.x = json.x;
+ this.y = json.y;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
},
PlayerPosition: class PlayerPosition {
static type = "event";
@@ -132,6 +158,15 @@ module.exports = {
y: { type: "number" },
},
};
+ constructor(json) {
+ this.player_name = json.player_name;
+ this.instance_id = json.instance_id;
+ this.x = json.x;
+ this.y = json.y;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
},
SetWebSubscription: class SetWebSubscription {
static type = "request";
@@ -146,6 +181,15 @@ module.exports = {
faction_list: { type: "boolean" },
},
};
+ constructor(json) {
+ this.data = json;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
+ toJSON() {
+ return this.data;
+ }
},
CreateFaction: class CreateFaction {
static type = "request";
@@ -156,18 +200,25 @@ module.exports = {
type: "object",
properties: factionProperties,
};
- static Response = {
- jsonSchema: {
- type: "object",
- properties: {
- ok: { type: "boolean" },
- faction: {
- type: "object",
- properties: factionProperties,
- },
+ constructor(json) {
+ // eslint-disable-next-line guard-for-in
+ for (let key in factionProperties) {
+ this[key] = json[key];
+ }
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
+ static Response = plainJson({
+ type: "object",
+ properties: {
+ ok: { type: "boolean" },
+ faction: {
+ type: "object",
+ properties: factionProperties,
},
},
- };
+ });
},
// Send updated faction data to controller for propagation. Used to edit factions
UpdateFaction: class UpdateFaction {
@@ -191,20 +242,27 @@ module.exports = {
},
},
};
- static Response = {
- jsonSchema: {
- type: "object",
- required: ["ok", "message"],
- properties: {
- ok: { type: "boolean" },
- message: { type: "string" },
- faction: {
- type: "object",
- properties: factionProperties,
- },
+ constructor(json) {
+ this.faction_id = json.faction_id;
+ this.name = json.name;
+ this.open = json.open;
+ this.about = json.about;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
+ static Response = plainJson({
+ type: "object",
+ required: ["ok", "message"],
+ properties: {
+ ok: { type: "boolean" },
+ message: { type: "string" },
+ faction: {
+ type: "object",
+ properties: factionProperties,
},
},
- };
+ });
},
// Event notifying an instance of changes to a faction
FactionUpdate: class FactionUpdate {
@@ -221,6 +279,12 @@ module.exports = {
},
},
};
+ constructor(json) {
+ this.faction = json.faction;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
},
// Get changed factions
RefreshFactionData: class RefreshFactionData {
@@ -228,22 +292,20 @@ module.exports = {
static src = "instance";
static dst = "controller";
static plugin = pluginName;
- static Response = {
- jsonSchema: {
- type: "object",
- properties: {
- ok: { type: "boolean" },
- message: { type: "string" },
- factions: {
- type: "array",
- items: {
- type: "object",
- properties: factionProperties,
- },
+ static Response = plainJson({
+ type: "object",
+ properties: {
+ ok: { type: "boolean" },
+ message: { type: "string" },
+ factions: {
+ type: "array",
+ items: {
+ type: "object",
+ properties: factionProperties,
},
},
},
- };
+ });
},
FactionInvitePlayer: class FactionInvitePlayer {
static type = "request";
@@ -258,15 +320,21 @@ module.exports = {
role: { type: "string" },
},
};
- static Response = {
- jsonSchema: {
- type: "object",
- properties: {
- ok: { type: "boolean" },
- message: { type: "string" },
- },
+ constructor(json) {
+ this.faction_id = json.faction_id;
+ this.player_name = json.player_name;
+ this.role = json.role;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
+ static Response = plainJson({
+ type: "object",
+ properties: {
+ ok: { type: "boolean" },
+ message: { type: "string" },
},
- };
+ });
},
JoinFaction: class JoinFaction {
static type = "request";
@@ -280,15 +348,20 @@ module.exports = {
player_name: { type: "string" },
},
};
- static Response = {
- jsonSchema: {
- type: "object",
- properties: {
- ok: { type: "boolean" },
- message: { type: "string" },
- },
+ constructor(json) {
+ this.faction_id = json.faction_id;
+ this.player_name = json.player_name;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
+ static Response = plainJson({
+ type: "object",
+ properties: {
+ ok: { type: "boolean" },
+ message: { type: "string" },
},
- };
+ });
},
LeaveFaction: class LeaveFaction {
static type = "request";
@@ -302,15 +375,20 @@ module.exports = {
player_name: { type: "string" },
},
};
- static Response = {
- jsonSchema: {
- type: "object",
- properties: {
- ok: { type: "boolean" },
- message: { type: "string" },
- },
+ constructor(json) {
+ this.faction_id = json.faction_id;
+ this.player_name = json.player_name;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
+ static Response = plainJson({
+ type: "object",
+ properties: {
+ ok: { type: "boolean" },
+ message: { type: "string" },
},
- };
+ });
},
FactionChangeMemberRole: class FactionChangeMemberRole {
static type = "request";
@@ -325,15 +403,21 @@ module.exports = {
role: factionProperties.members.items.properties.role,
},
};
- static Response = {
- jsonSchema: {
- type: "object",
- properties: {
- ok: { type: "boolean" },
- message: { type: "string" },
- },
+ constructor(json) {
+ this.faction_id = json.faction_id;
+ this.player_name = json.player_name;
+ this.role = json.role;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
+ static Response = plainJson({
+ type: "object",
+ properties: {
+ ok: { type: "boolean" },
+ message: { type: "string" },
},
- };
+ });
},
ClaimServer: class ClaimServer {
static type = "request";
@@ -348,15 +432,21 @@ module.exports = {
faction_id: { type: "string" },
},
};
- static Response = {
- jsonSchema: {
- type: "object",
- properties: {
- ok: { type: "boolean" },
- message: { type: "string" },
- },
+ constructor(json) {
+ this.instance_id = json.instance_id;
+ this.player_name = json.player_name;
+ this.faction_id = json.faction_id;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
+ static Response = plainJson({
+ type: "object",
+ properties: {
+ ok: { type: "boolean" },
+ message: { type: "string" },
},
- };
+ });
},
UnclaimServer: class UnclaimServer {
static type = "request";
@@ -370,15 +460,20 @@ module.exports = {
player_name: { type: "string" },
},
};
- static Response = {
- jsonSchema: {
- type: "object",
- properties: {
- ok: { type: "boolean" },
- message: { type: "string" },
- },
+ constructor(json) {
+ this.instance_id = json.instance_id;
+ this.player_name = json.player_name;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
+ static Response = plainJson({
+ type: "object",
+ properties: {
+ ok: { type: "boolean" },
+ message: { type: "string" },
},
- };
+ });
},
JoinGridworld: class JoinGridworld {
static type = "request";
@@ -392,18 +487,23 @@ module.exports = {
grid_id: { type: "integer" },
},
};
- static Response = {
- jsonSchema: {
- type: "object",
- properties: {
- ok: { type: "boolean" },
- message: { type: "string" },
- connection_address: { type: "string" },
- server_name: { type: "string" },
- server_description: { type: "string" },
- },
+ constructor(json) {
+ this.player_name = json.player_name;
+ this.grid_id = json.grid_id;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
+ static Response = plainJson({
+ type: "object",
+ properties: {
+ ok: { type: "boolean" },
+ message: { type: "string" },
+ connection_address: { type: "string" },
+ server_name: { type: "string" },
+ server_description: { type: "string" },
},
- };
+ });
},
PerformEdgeTeleport: class PerformEdgeTeleport {
static type = "request";
@@ -419,19 +519,26 @@ module.exports = {
grid_id: { type: "integer" },
},
};
- static Response = {
- jsonSchema: {
- type: "object",
- properties: {
- ok: { type: "boolean" },
- message: { type: "string" },
- connection_address: { type: "string" },
- server_name: { type: "string" },
- server_description: { type: "string" },
- instance_id: { type: "integer" },
- },
+ constructor(json) {
+ this.player_name = json.player_name;
+ this.player_x_position = json.player_x_position;
+ this.player_y_position = json.player_y_position;
+ this.grid_id = json.grid_id;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
+ static Response = plainJson({
+ type: "object",
+ properties: {
+ ok: { type: "boolean" },
+ message: { type: "string" },
+ connection_address: { type: "string" },
+ server_name: { type: "string" },
+ server_description: { type: "string" },
+ instance_id: { type: "integer" },
},
- };
+ });
},
GetTileData: class GetTileData {
static type = "request";
@@ -446,6 +553,14 @@ module.exports = {
position_b: { type: "array", items: { type: "number" } },
},
};
+ constructor(json) {
+ this.instance_id = json.instance_id;
+ this.position_a = json.position_a;
+ this.position_b = json.position_b;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
},
RefreshTileData: class RefreshTileData {
static type = "request";
@@ -459,6 +574,12 @@ module.exports = {
instance_id: { type: "integer" },
},
};
+ constructor(json) {
+ this.instance_id = json.instance_id;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
},
SetLoadFactor: class SetLoadFactor {
static type = "event";
@@ -472,5 +593,12 @@ module.exports = {
load_factor: { type: "number" },
},
};
+ constructor(json) {
+ this.instance_id = json.instance_id;
+ this.load_factor = json.load_factor;
+ }
+ static fromJSON(json) {
+ return new this(json);
+ }
},
};
diff --git a/module/gridworld.lua b/module/gridworld.lua
index 8a1873f..88b074d 100644
--- a/module/gridworld.lua
+++ b/module/gridworld.lua
@@ -29,12 +29,6 @@ local set_player_permission_group = require("faction/building_restrictions/set_p
local worldgen = require("worldgen/index")
local load_balancing = require("load_balancing/load_balancing")
--- Declare globals to make linter happy
-game = game
-global = global
--- defines = defines
-log = log
-
gridworld.events = {}
gridworld.events[clusterio_api.events.on_server_startup] = function()
-- Set up global table
diff --git a/src/instance_migration/info/MigrateInstanceRequest.js b/src/instance_migration/info/MigrateInstanceRequest.js
index 933d7b8..a1b4300 100644
--- a/src/instance_migration/info/MigrateInstanceRequest.js
+++ b/src/instance_migration/info/MigrateInstanceRequest.js
@@ -1,11 +1,17 @@
"use strict";
-const { libLink } = require("@clusterio/lib");
+
+const { plainJson } = require("@clusterio/lib");
class MigrateInstanceRequest {
static type = "request";
static src = "control";
static dst = "controller";
+ static plugin = "gridworld";
static permission = "gridworld.migrate_instance";
+ constructor(instance_id, host_id) {
+ this.instance_id = instance_id;
+ this.host_id = host_id;
+ }
static jsonSchema = {
type: "object",
properties: {
@@ -15,19 +21,20 @@ class MigrateInstanceRequest {
required: ["instance_id", "host_id"],
additionalProperties: false,
};
- static Response = {
- jsonSchema: {
- type: "object",
- properties: {
- status: {
- type: "string",
- enum: ["success", "failure"],
- },
+ static fromJSON(json) {
+ return new this(json.instance_id, json.host_id);
+ }
+ static Response = plainJson({
+ type: "object",
+ properties: {
+ status: {
+ type: "string",
+ enum: ["success", "failure"],
},
- required: ["status"],
- additionalProperties: false,
},
- };
-}
+ required: ["status"],
+ additionalProperties: false,
+ });
+};
module.exports = MigrateInstanceRequest;
diff --git a/web/components/CreateGridworldForm.jsx b/web/components/CreateGridworldForm.jsx
index a3263df..9feff3e 100644
--- a/web/components/CreateGridworldForm.jsx
+++ b/web/components/CreateGridworldForm.jsx
@@ -1,7 +1,7 @@
import React, { useContext, useState } from "react";
-import { useHistory } from "react-router";
+import { useNavigate } from "react-router-dom";
-import { ControlContext, useHostList } from "@clusterio/web_ui";
+import { ControlContext, useHosts } from "@clusterio/web_ui";
import "../index.css";
import { Form, Input, Button, Select, InputNumber, Checkbox } from "antd";
@@ -17,10 +17,10 @@ const tailLayout = {
};
function NewGridworldForm() {
- let history = useHistory();
+ let navigate = useNavigate();
let control = useContext(ControlContext);
let [loading, setLoading] = useState();
- let [hostList] = useHostList();
+ let [hostList] = useHosts();
async function onFinish(values) {
// console.log("Success:", values);
@@ -28,7 +28,7 @@ function NewGridworldForm() {
await control.send(new messages.CreateFactionGrid(values));
setLoading(false);
await new Promise(resolve => setTimeout(resolve, 1500));
- history.push("/gridworld");
+ navigate("/gridworld");
};
function onFinishFailed(errorInfo) {
@@ -77,7 +77,7 @@ function NewGridworldForm() {
diff --git a/web/components/GridVisualizer.jsx b/web/components/GridVisualizer.jsx
index 6879def..ef00463 100644
--- a/web/components/GridVisualizer.jsx
+++ b/web/components/GridVisualizer.jsx
@@ -1,6 +1,6 @@
import React, { useContext, useState } from "react";
import { Row, Col } from "antd";
-import { Map, Polyline, Rectangle, Tooltip, TileLayer, SVGOverlay, Marker, Popup, Circle } from "react-leaflet";
+import { MapContainer, Polyline, Rectangle, Tooltip, TileLayer, SVGOverlay, Marker, Popup, Circle } from "react-leaflet";
import { ControlContext, useInstance, statusColors } from "@clusterio/web_ui";
import { useMapData } from "../model/mapData";
@@ -37,7 +37,7 @@ export default function GridVisualizer(props) {
- {mapData.map_data?.length ? : ""}
+ : ""}
diff --git a/web/components/InstanceModal.jsx b/web/components/InstanceModal.jsx
index f373a84..e5f85ba 100644
--- a/web/components/InstanceModal.jsx
+++ b/web/components/InstanceModal.jsx
@@ -1,6 +1,7 @@
import React, { useContext } from "react";
import { Button, Descriptions, Space, Popconfirm, Typography, Tabs } from "antd";
import DeleteOutlined from "@ant-design/icons/DeleteOutlined";
+import { useNavigate } from "react-router-dom";
import {
ControlContext,
@@ -14,15 +15,16 @@ import {
LogConsole,
InstanceConfigTree,
} from "@clusterio/web_ui";
-import lib from "@clusterio/lib";
+import * as lib from "@clusterio/lib";
import MigrateInstanceButton from "./MigrateInstanceButton";
function InstanceModal(props) {
let control = useContext(ControlContext);
let [instance] = useInstance(props.instance_id);
- let [host] = useHost(instance["assigned_host"]);
+ let [host] = useHost(instance?.["assigned_host"]);
let account = useAccount();
+ let navigate = useNavigate();
return <>
{props.instance_id && <>
@@ -44,9 +46,9 @@ function InstanceModal(props) {
okButtonProps={{ danger: true }}
onConfirm={() => {
control.send(
- new lib.InstanceDeleteRequest({ instanceId })
+ new lib.InstanceDeleteRequest(instanceId)
).then(() => {
- history.push("/instances");
+ navigate("/instances");
}).catch(notifyErrorHandler("Error deleting instance"));
}}
>
diff --git a/web/components/MigrateInstanceButton.jsx b/web/components/MigrateInstanceButton.jsx
index 418ccd0..8f43d7e 100644
--- a/web/components/MigrateInstanceButton.jsx
+++ b/web/components/MigrateInstanceButton.jsx
@@ -16,7 +16,7 @@ export default function MigrateInstanceButton(props) {
: "",
showModal(false)}
instanceId={props.instanceId}
/>,
diff --git a/web/components/MigrateInstanceModal.jsx b/web/components/MigrateInstanceModal.jsx
index 1588c3f..96898db 100644
--- a/web/components/MigrateInstanceModal.jsx
+++ b/web/components/MigrateInstanceModal.jsx
@@ -1,14 +1,14 @@
import React, { useContext, useState } from "react";
import { Modal, Form, Select } from "antd";
-import { ControlContext, useInstance, useHostList } from "@clusterio/web_ui";
+import { ControlContext, useInstance, useHosts } from "@clusterio/web_ui";
import MigrateInstanceRequest from "../../src/instance_migration/info/MigrateInstanceRequest";
export default function MigrateInstanceModal(props) {
const control = useContext(ControlContext);
let [isWorking, setWorking] = useState(false);
- let [hostList] = useHostList();
+ let [hostList] = useHosts();
let [instance] = useInstance(props.instanceId);
let [form] = Form.useForm();
@@ -19,7 +19,7 @@ export default function MigrateInstanceModal(props) {
return {
if (isWorking) {
document.location = document.location;
diff --git a/web/components/RefreshTileDataButton.jsx b/web/components/RefreshTileDataButton.jsx
index d61bfd8..045615d 100644
--- a/web/components/RefreshTileDataButton.jsx
+++ b/web/components/RefreshTileDataButton.jsx
@@ -16,7 +16,7 @@ export default function RefreshTileDataButton() {
: "",
showModal(false)}
/>,
];
diff --git a/web/components/RefreshTileDataModal.jsx b/web/components/RefreshTileDataModal.jsx
index 3b8748c..5cdfeef 100644
--- a/web/components/RefreshTileDataModal.jsx
+++ b/web/components/RefreshTileDataModal.jsx
@@ -1,13 +1,13 @@
import React, { useContext, useState } from "react";
import { Progress, Modal, InputNumber } from "antd";
-import { ControlContext, useInstanceList, notifyErrorHandler } from "@clusterio/web_ui";
+import { ControlContext, useInstances, notifyErrorHandler } from "@clusterio/web_ui";
import ThrottledPromise from "../lib/ThrottledPromise";
import messages from "../../messages";
export default function RefreshTileDataModal(props) {
const control = useContext(ControlContext);
- let [instanceList] = useInstanceList();
+ let [instanceList] = useInstances();
let [isWorking, setWorking] = useState(false);
let [percent, setPercent] = useState(0); // Completed + in progress
let [success, setSuccess] = useState(0); // Completed
@@ -22,7 +22,7 @@ export default function RefreshTileDataModal(props) {
return {
if (isWorking) {
document.location = document.location;
diff --git a/web/index.jsx b/web/index.jsx
index 9c05510..82ef91d 100644
--- a/web/index.jsx
+++ b/web/index.jsx
@@ -1,7 +1,6 @@
import React from "react";
-import { libPlugin } from "@clusterio/lib";
-import { notifyErrorHandler } from "@clusterio/web_ui";
+import { BaseWebPlugin, notifyErrorHandler } from "@clusterio/web_ui";
import OverviewPage from "./pages/OverviewPage";
import CreateGridworldPage from "./pages/CreateGridworldPage";
@@ -9,7 +8,7 @@ import FactionsPage from "./pages/FactionsPage";
import FactionViewPage from "./pages/FactionViewPage";
import messages from "../messages";
-export class WebPlugin extends libPlugin.BaseWebPlugin {
+export class WebPlugin extends BaseWebPlugin {
async init() {
this.pages = [
{
diff --git a/web/model/mapData.jsx b/web/model/mapData.jsx
index ed225d1..d19f5bf 100644
--- a/web/model/mapData.jsx
+++ b/web/model/mapData.jsx
@@ -1,12 +1,12 @@
import React, { useEffect, useContext, useState } from "react";
-import { ControlContext, useInstanceList } from "@clusterio/web_ui";
+import { ControlContext, useInstances } from "@clusterio/web_ui";
import messages from "../../messages";
-const { logger } = libLogging;
+const { logger } = require("@clusterio/lib");
export function useMapData(id) {
- let [instances] = useInstanceList();
+ let [instances] = useInstances();
let control = useContext(ControlContext);
let [mapData, setMapData] = useState({ loading: true });
diff --git a/web/pages/CreateGridworldPage.jsx b/web/pages/CreateGridworldPage.jsx
index bb36193..6bad80f 100644
--- a/web/pages/CreateGridworldPage.jsx
+++ b/web/pages/CreateGridworldPage.jsx
@@ -1,7 +1,6 @@
import React from "react";
-import { PageHeader } from "antd";
-import { PageLayout } from "@clusterio/web_ui";
+import { PageHeader, PageLayout } from "@clusterio/web_ui";
import "../index.css";
import NewGridworldForm from "../components/CreateGridworldForm";
diff --git a/web/pages/FactionViewPage.jsx b/web/pages/FactionViewPage.jsx
index 0394060..e22d97e 100644
--- a/web/pages/FactionViewPage.jsx
+++ b/web/pages/FactionViewPage.jsx
@@ -1,8 +1,8 @@
import React, { useEffect, useContext, useState } from "react";
import { useParams } from "react-router-dom";
-import { Alert, Descriptions, Spin, Table, PageHeader } from "antd";
+import { Alert, Descriptions, Spin, Table } from "antd";
-import { ControlContext, PageLayout } from "@clusterio/web_ui";
+import { ControlContext, PageLayout, PageHeader } from "@clusterio/web_ui";
import useFactionList from "../providers/useFactionList";
export default function FactionViewPage() {
diff --git a/web/pages/FactionsPage.jsx b/web/pages/FactionsPage.jsx
index 002d1e6..fc56a2d 100644
--- a/web/pages/FactionsPage.jsx
+++ b/web/pages/FactionsPage.jsx
@@ -1,16 +1,15 @@
import React, { useContext } from "react";
-import { useHistory } from "react-router-dom";
-import { Button, PageHeader, Popconfirm, Table } from "antd";
+import { useNavigate } from "react-router-dom";
+import { Button, Popconfirm, Table } from "antd";
import DeleteOutlined from "@ant-design/icons/DeleteOutlined";
import "../index.css";
-import { libLink } from "@clusterio/lib";
-import { ControlContext, PageLayout, useAccount, notifyErrorHandler } from "@clusterio/web_ui";
+import { ControlContext, PageLayout, PageHeader, useAccount } from "@clusterio/web_ui";
import useFactionList from "../providers/useFactionList";
function FactionsPage() {
const control = useContext(ControlContext);
- const history = useHistory();
+ const navigate = useNavigate();
const factions = useFactionList(control);
let account = useAccount();
@@ -58,7 +57,7 @@ function FactionsPage() {
rowKey="faction_id"
onRow={faction => ({
onClick: event => {
- history.push(`/gridworld/factions/${faction.faction_id}/view`);
+ navigate(`/gridworld/factions/${faction.faction_id}/view`);
},
})}
/>
diff --git a/web/pages/OverviewPage.jsx b/web/pages/OverviewPage.jsx
index 1984511..a5dd434 100644
--- a/web/pages/OverviewPage.jsx
+++ b/web/pages/OverviewPage.jsx
@@ -1,19 +1,19 @@
import React, { useContext } from "react";
-import { useHistory } from "react-router-dom";
-import { Button, PageHeader, Popconfirm } from "antd";
+import { useNavigate } from "react-router-dom";
+import { Button, Popconfirm } from "antd";
import GithubOutlined from "@ant-design/icons/GithubOutlined";
import DeleteOutlined from "@ant-design/icons/DeleteOutlined";
import lib from "@clusterio/lib";
-import { ControlContext, PageLayout, useInstanceList, useAccount, notifyErrorHandler } from "@clusterio/web_ui";
+import { ControlContext, PageLayout, PageHeader, useInstances, useAccount, notifyErrorHandler } from "@clusterio/web_ui";
import "../index.css";
import GridVisualizer from "../components/GridVisualizer";
import RefreshTileDataButton from "../components/RefreshTileDataButton";
function OverviewPage() {
const control = useContext(ControlContext);
- const history = useHistory();
- let [instanceList] = useInstanceList();
+ const navigate = useNavigate();
+ let [instanceList] = useInstances();
let account = useAccount();
return
@@ -25,7 +25,7 @@ function OverviewPage() {
,
account.hasPermission("core.instance.delete")