mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 03:25:23 +09:00
Refactored UPS monitor as clusterio plugin (#398)
* Refactor server ups * Use catalogs * Move to own plugin * Use web config * Remove External.get_server_ups * Update workspace version requirement * Remove need for storage * Add locale * Fix CI
This commit is contained in:
30
exp_server_ups/index.ts
Normal file
30
exp_server_ups/index.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
declare module "@clusterio/lib" {
|
||||
export interface InstanceConfigFields {
|
||||
"exp_server_ups.update_interval": number;
|
||||
"exp_server_ups.average_interval": number;
|
||||
}
|
||||
}
|
||||
|
||||
export const plugin: lib.PluginDeclaration = {
|
||||
name: "exp_server_ups",
|
||||
title: "ExpGaming - Server UPS",
|
||||
description: "Clusterio plugin providing in game server ups counter",
|
||||
|
||||
instanceEntrypoint: "./dist/node/instance",
|
||||
instanceConfigFields: {
|
||||
"exp_server_ups.update_interval": {
|
||||
title: "Update Interval",
|
||||
description: "Frequency at which updates are exchanged with factorio (ms)",
|
||||
type: "number",
|
||||
initialValue: 1000,
|
||||
},
|
||||
"exp_server_ups.average_interval": {
|
||||
title: "Average Interval",
|
||||
description: "Number of update intervals to average updates per second across",
|
||||
type: "number",
|
||||
initialValue: 60
|
||||
},
|
||||
},
|
||||
};
|
||||
48
exp_server_ups/instance.ts
Normal file
48
exp_server_ups/instance.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { BaseInstancePlugin } from "@clusterio/host";
|
||||
|
||||
export class InstancePlugin extends BaseInstancePlugin {
|
||||
private updateInterval?: ReturnType<typeof setInterval>;
|
||||
private gameTimes: number[] = [];
|
||||
|
||||
async onStart() {
|
||||
this.updateInterval = setInterval(this.updateUps.bind(this), this.instance.config.get("exp_server_ups.update_interval"));
|
||||
}
|
||||
|
||||
async onStop() {
|
||||
if (this.updateInterval) {
|
||||
clearInterval(this.updateInterval);
|
||||
}
|
||||
}
|
||||
|
||||
async onInstanceConfigFieldChanged(field: string, curr: unknown): Promise<void> {
|
||||
if (field === "exp_server_ups.update_interval") {
|
||||
await this.onStop();
|
||||
await this.onStart();
|
||||
} else if (field === "exp_server_ups.average_interval") {
|
||||
this.gameTimes.splice(curr as number);
|
||||
}
|
||||
}
|
||||
|
||||
async updateUps() {
|
||||
let ups = 0;
|
||||
const collected = this.gameTimes.length - 1;
|
||||
if (collected > 0) {
|
||||
const minTick = this.gameTimes[0];
|
||||
const maxTick = this.gameTimes[collected];
|
||||
const interval = this.instance.config.get("exp_server_ups.update_interval") / 1000;
|
||||
ups = (maxTick - minTick) / (collected * interval);
|
||||
}
|
||||
|
||||
try {
|
||||
const newGameTime = await this.sendRcon(`/_rcon return exp_server_ups.update(${ups})`);
|
||||
this.gameTimes.push(Number(newGameTime));
|
||||
} catch (error: any) {
|
||||
this.logger.error(`Failed to receive new game time: ${error}`);
|
||||
}
|
||||
|
||||
if (collected > this.instance.config.get("exp_server_ups.average_interval")) {
|
||||
this.gameTimes.shift();
|
||||
}
|
||||
}
|
||||
}
|
||||
95
exp_server_ups/module/control.lua
Normal file
95
exp_server_ups/module/control.lua
Normal file
@@ -0,0 +1,95 @@
|
||||
--[[-- Gui - Server UPS
|
||||
Adds a server ups counter in the top right corner and a command to toggle it
|
||||
]]
|
||||
|
||||
local Gui = require("modules/exp_gui")
|
||||
local ExpUtil = require("modules/exp_util")
|
||||
local Commands = require("modules/exp_commands")
|
||||
|
||||
--- Label to show the server ups, drawn to screen on join
|
||||
local server_ups = Gui.element("server_ups")
|
||||
:track_all_elements()
|
||||
:draw{
|
||||
type = "label",
|
||||
name = Gui.property_from_name,
|
||||
}
|
||||
:style{
|
||||
font = "default-game",
|
||||
}
|
||||
:player_data(function(def, element)
|
||||
local player = Gui.get_player(element)
|
||||
local existing = def.data[player]
|
||||
if not existing or not existing.valid then
|
||||
return element -- Only set if no previous
|
||||
end
|
||||
end)
|
||||
|
||||
--- Update the caption for all online players
|
||||
--- @param ups number The UPS to be displayed
|
||||
local function update_server_ups(ups)
|
||||
local caption = ("%.1f (%.1f%%)"):format(ups, ups * 5 / 3)
|
||||
for _, element in server_ups:online_elements() do
|
||||
element.caption = caption
|
||||
end
|
||||
end
|
||||
|
||||
--- Stores the visible state of server ups element for a player
|
||||
local PlayerData = require("modules/exp_legacy/expcore/player_data")
|
||||
local UsesServerUps = PlayerData.Settings:combine("UsesServerUps")
|
||||
UsesServerUps:set_default(false)
|
||||
UsesServerUps:set_metadata{
|
||||
permission = "command/server-ups",
|
||||
stringify = function(value) return value and "Visible" or "Hidden" end,
|
||||
}
|
||||
|
||||
--- Change the visible state when your data loads
|
||||
UsesServerUps:on_load(function(player_name, visible)
|
||||
local player = assert(game.get_player(player_name))
|
||||
server_ups.data[player].visible = visible or false
|
||||
end)
|
||||
|
||||
--- Toggles if the server ups is visbile
|
||||
Commands.new("server-ups", { "exp_server-ups.description" })
|
||||
:add_aliases{ "sups", "ups" }
|
||||
:register(function(player)
|
||||
local visible = not UsesServerUps:get(player)
|
||||
server_ups.data[player].visible = visible
|
||||
UsesServerUps:set(player, visible)
|
||||
end)
|
||||
|
||||
--- Add an interface which can be called from rcon
|
||||
Commands.add_rcon_static("exp_server_ups", {
|
||||
update = function(ups)
|
||||
ExpUtil.assert_argument_type(ups, "number", 1, "ups")
|
||||
update_server_ups(ups)
|
||||
return game.tick
|
||||
end
|
||||
})
|
||||
|
||||
--- Set the location of the label
|
||||
local function set_location(event)
|
||||
local player = game.players[event.player_index]
|
||||
local element = server_ups.data[player]
|
||||
if not element then
|
||||
element = server_ups(player.gui.screen)
|
||||
element.visible = UsesServerUps:get(player)
|
||||
end
|
||||
|
||||
local uis = player.display_scale
|
||||
local res = player.display_resolution
|
||||
element.location = { x = res.width - 363 * uis, y = 31 * uis } -- below ups and clock
|
||||
end
|
||||
|
||||
local e = defines.events
|
||||
|
||||
return {
|
||||
elements = {
|
||||
server_ups = server_ups,
|
||||
},
|
||||
events = {
|
||||
[e.on_player_created] = set_location,
|
||||
[e.on_player_joined_game] = set_location,
|
||||
[e.on_player_display_resolution_changed] = set_location,
|
||||
[e.on_player_display_scale_changed] = set_location,
|
||||
},
|
||||
}
|
||||
2
exp_server_ups/module/locale/en.cfg
Normal file
2
exp_server_ups/module/locale/en.cfg
Normal file
@@ -0,0 +1,2 @@
|
||||
[exp_server-ups]
|
||||
description=Toggle the server UPS display.
|
||||
2
exp_server_ups/module/locale/zh-CN.cfg
Normal file
2
exp_server_ups/module/locale/zh-CN.cfg
Normal file
@@ -0,0 +1,2 @@
|
||||
[exp_server-ups]
|
||||
description=啟動 UPS 顯示
|
||||
2
exp_server_ups/module/locale/zh-TW.cfg
Normal file
2
exp_server_ups/module/locale/zh-TW.cfg
Normal file
@@ -0,0 +1,2 @@
|
||||
[exp_server-ups]
|
||||
description=啟動 UPS 顯示
|
||||
14
exp_server_ups/module/module.json
Normal file
14
exp_server_ups/module/module.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "exp_server_ups",
|
||||
"load": [
|
||||
"control.lua"
|
||||
],
|
||||
"require": [
|
||||
],
|
||||
"dependencies": {
|
||||
"clusterio": "*",
|
||||
"exp_commands": "*",
|
||||
"exp_util": "*",
|
||||
"exp_gui": "*"
|
||||
}
|
||||
}
|
||||
3
exp_server_ups/module/module_exports.lua
Normal file
3
exp_server_ups/module/module_exports.lua
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
-- Access the exports from other modules using require("modules/exp_server_ups")
|
||||
return require("modules/exp_server_ups/control").elements.server_ups
|
||||
40
exp_server_ups/package.json
Normal file
40
exp_server_ups/package.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "@expcluster/server_ups",
|
||||
"version": "0.1.0",
|
||||
"description": "Clusterio plugin providing in game server ups counter",
|
||||
"author": "Cooldude2606 <https://github.com/Cooldude2606>",
|
||||
"license": "MIT",
|
||||
"repository": "explosivegaming/ExpCluster",
|
||||
"main": "dist/node/index.js",
|
||||
"scripts": {
|
||||
"prepare": "tsc --build && webpack-cli --env production"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@clusterio/lib": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "catalog:",
|
||||
"@types/node": "catalog:",
|
||||
"@clusterio/lib": "catalog:",
|
||||
"webpack": "catalog:",
|
||||
"webpack-cli": "catalog:",
|
||||
"webpack-merge": "catalog:"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sinclair/typebox": "catalog:",
|
||||
"@expcluster/lib_util": "workspace:^",
|
||||
"@expcluster/lib_gui": "workspace:^",
|
||||
"@expcluster/lib_commands": "workspace:^"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"keywords": [
|
||||
"clusterio",
|
||||
"clusterio-plugin",
|
||||
"factorio"
|
||||
]
|
||||
}
|
||||
4
exp_server_ups/tsconfig.browser.json
Normal file
4
exp_server_ups/tsconfig.browser.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../tsconfig.browser.json",
|
||||
"include": [ "web/**/*.tsx", "web/**/*.ts", "package.json" ],
|
||||
}
|
||||
6
exp_server_ups/tsconfig.json
Normal file
6
exp_server_ups/tsconfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "./tsconfig.node.json" }
|
||||
]
|
||||
}
|
||||
5
exp_server_ups/tsconfig.node.json
Normal file
5
exp_server_ups/tsconfig.node.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": "../tsconfig.node.json",
|
||||
"include": ["./**/*.ts"],
|
||||
"exclude": ["test/*", "./dist/*"],
|
||||
}
|
||||
0
exp_server_ups/web/index.tsx
Normal file
0
exp_server_ups/web/index.tsx
Normal file
29
exp_server_ups/webpack.config.js
Normal file
29
exp_server_ups/webpack.config.js
Normal file
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const { merge } = require("webpack-merge");
|
||||
|
||||
const common = require("@clusterio/web_ui/webpack.common");
|
||||
|
||||
module.exports = (env = {}) => merge(common(env), {
|
||||
context: __dirname,
|
||||
entry: "./web/index.tsx",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "dist", "web"),
|
||||
},
|
||||
plugins: [
|
||||
new webpack.container.ModuleFederationPlugin({
|
||||
name: "exp_server_ups",
|
||||
library: { type: "window", name: "plugin_exp_server_ups" },
|
||||
exposes: {
|
||||
"./": "./index.ts",
|
||||
"./package.json": "./package.json",
|
||||
"./web": "./web/index.tsx",
|
||||
},
|
||||
shared: {
|
||||
"@clusterio/lib": { import: false },
|
||||
"@clusterio/web_ui": { import: false },
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
Reference in New Issue
Block a user