mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 03:25:23 +09:00
Merge branch 'main' into aperx
This commit is contained in:
10
.github/workflows/fmtk.yml
vendored
10
.github/workflows/fmtk.yml
vendored
@@ -9,18 +9,22 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
cache: "pnpm"
|
||||
- name: Install FMTK
|
||||
run: |
|
||||
npm install factoriomod-debug
|
||||
npx fmtk luals-addon
|
||||
pnpm install factoriomod-debug
|
||||
pnpm exec fmtk luals-addon
|
||||
jq '.["workspace.library"] += ["${{ github.workspace }}/factorio/library"] | .["runtime.plugin"] = "${{ github.workspace }}/factorio/plugin.lua"' .luarc.json > temp.luarc.json
|
||||
jq -s '.[0] * .[1].settings' temp.luarc.json ${{ github.workspace }}/factorio/config.json > check.luarc.json
|
||||
- name: Install LuaLS
|
||||
run: |
|
||||
wget https://github.com/LuaLS/lua-language-server/releases/download/3.13.9/lua-language-server-3.13.9-linux-x64.tar.gz -q -O lusls.tar.gz
|
||||
wget https://github.com/LuaLS/lua-language-server/releases/download/3.15.0/lua-language-server-3.15.0-linux-x64.tar.gz -q -O lusls.tar.gz
|
||||
mkdir luals && tar -xf lusls.tar.gz -C luals && rm lusls.tar.gz
|
||||
- name: Run Lint Report
|
||||
shell: bash
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,7 +1,5 @@
|
||||
dist/
|
||||
node_modules/
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
.vscode
|
||||
exp_util/node-compile-cache/
|
||||
exp_commands/node-compile-cache/
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"inferParamType": true
|
||||
},
|
||||
"$comment-name-style-check": "Disabled below until config issue fixed: https://github.com/LuaLS/lua-language-server/issues/2643",
|
||||
"$comment-type-mismatch": "Disabled unless opened due to performance concerns, time reduced to 10s from 400s",
|
||||
"diagnostics": {
|
||||
"unusedLocalExclude": [ "_*", "i", "j", "k", "v" ],
|
||||
"groupFileStatus": {
|
||||
@@ -37,7 +38,10 @@
|
||||
"neededFileStatus": {
|
||||
"no-unknown": "None!",
|
||||
"spell-check": "None!",
|
||||
"name-style-check": "None!"
|
||||
"name-style-check": "None!",
|
||||
"assign-type-mismatch": "Opened!",
|
||||
"return-type-mismatch": "Opened!",
|
||||
"param-type-mismatch": "Opened!"
|
||||
}
|
||||
},
|
||||
"nameStyle.config": {
|
||||
|
||||
@@ -25,7 +25,7 @@ local Commands = require("modules/exp_commands")
|
||||
local add, parse = Commands.add_data_type, Commands.parse_input
|
||||
local valid, invalid = Commands.status.success, Commands.status.invalid_input
|
||||
|
||||
local types = {} --- @class Commands._types
|
||||
local types = {} --- @class Commands.types
|
||||
|
||||
--- A boolean value where true is one of: yes, y, true, 1
|
||||
types.boolean =
|
||||
|
||||
@@ -76,11 +76,11 @@ local Commands = {
|
||||
},
|
||||
}
|
||||
|
||||
--- @class Commands._status: table<string, Commands.Status>
|
||||
--- @class Commands.status: table<string, Commands.Status>
|
||||
--- Contains the different status values a command can return
|
||||
Commands.status = {}
|
||||
|
||||
--- @class Commands._types: table<string, Commands.InputParser | Commands.InputParserFactory>
|
||||
--- @class Commands.types: table<string, Commands.InputParser | Commands.InputParserFactory>
|
||||
--- Stores all input parsers and validators for different data types
|
||||
Commands.types = {}
|
||||
|
||||
@@ -595,6 +595,7 @@ end
|
||||
--- @param parameter string The raw command parameter that was used
|
||||
--- @param detail any
|
||||
local function log_command(comment, command, player, parameter, detail)
|
||||
if player.index == 0 and comment == "Command Ran" then return end
|
||||
ExpUtil.write_json("log/commands.log", {
|
||||
comment = comment,
|
||||
command_name = command.name,
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.19"
|
||||
"@clusterio/lib": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@clusterio/lib": "2.0.0-alpha.19",
|
||||
"@types/node": "^20.14.9",
|
||||
"typescript": "^5.5.3"
|
||||
"@clusterio/lib": "catalog:",
|
||||
"@types/node": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"dependencies": {
|
||||
"@expcluster/lib_util": "workspace:*",
|
||||
"@sinclair/typebox": "^0.30.4"
|
||||
"@expcluster/lib_util": "workspace:^",
|
||||
"@sinclair/typebox": "catalog:"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
41
exp_groups/package.json
Normal file
41
exp_groups/package.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "@expcluster/permission_groups",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"description": "Example Description. Package. Change me in package.json",
|
||||
"main": "dist/node/index.js",
|
||||
"scripts": {
|
||||
"$prepare": "tsc --build && webpack-cli --env production"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.20",
|
||||
"@clusterio/web_ui": "^2.0.0-alpha.20.b",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/node": "^20.4.5",
|
||||
"@types/react": "^18.2.21",
|
||||
"antd": "^5.13.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"typescript": "^5.5.3",
|
||||
"webpack": "^5.98.0",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-merge": "^5.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sinclair/typebox": "^0.30.4",
|
||||
"fs-extra": "^11.2.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"keywords": [
|
||||
"clusterio",
|
||||
"factorio"
|
||||
]
|
||||
}
|
||||
@@ -110,8 +110,9 @@ end
|
||||
--- @param value unknown
|
||||
function GuiData._metatable.__newindex(self, key, value)
|
||||
assert(type(key) == "userdata", "Index type '" .. ExpUtil.get_class_name(key) .. "' given to GuiData. Must be of type userdata.")
|
||||
local object_name = key.object_name --- @diagnostic disable-line assign-type-mismatch
|
||||
local object_name = key.object_name
|
||||
if object_name == "LuaGuiElement" then
|
||||
--- @cast key LuaGuiElement
|
||||
local data = self.element_data
|
||||
local player_elements = data[key.player_index]
|
||||
if not player_elements then
|
||||
@@ -121,8 +122,10 @@ function GuiData._metatable.__newindex(self, key, value)
|
||||
player_elements[key.index] = value
|
||||
registration_numbers[reg_obj(key)] = key.player_index
|
||||
elseif object_name == "LuaPlayer" then
|
||||
--- @cast key LuaPlayer
|
||||
self.player_data[key.index] = value
|
||||
elseif object_name == "LuaForce" then
|
||||
--- @cast key LuaForce
|
||||
self.force_data[key.index] = value
|
||||
else
|
||||
error("Unsupported object class '" .. object_name .. "' given as index to GuiData.")
|
||||
|
||||
@@ -28,7 +28,7 @@ local GuiIter = {
|
||||
_scopes = registered_scopes,
|
||||
}
|
||||
|
||||
local function nop() return nil, nil end
|
||||
local function no_loop() return nil, nil end
|
||||
|
||||
--- Get the next valid element
|
||||
--- @param elements table<uint, LuaGuiElement>
|
||||
@@ -51,9 +51,9 @@ end
|
||||
--- @param online boolean?
|
||||
--- @return uint?, LuaPlayer?, table<uint, LuaGuiElement>?
|
||||
local function next_valid_player(scope_elements, players, prev_index, online)
|
||||
local index, player = nil, nil
|
||||
local index, player = prev_index, nil
|
||||
while true do
|
||||
index, player = next(players, prev_index)
|
||||
index, player = next(players, index)
|
||||
while player and not player.valid do
|
||||
scope_elements[player.index] = nil
|
||||
index, player = next(players, index)
|
||||
@@ -66,7 +66,7 @@ local function next_valid_player(scope_elements, players, prev_index, online)
|
||||
|
||||
if online == nil or player.connected == online then
|
||||
local player_elements = scope_elements[player.index]
|
||||
if player_elements and #player_elements > 0 then
|
||||
if player_elements and next(player_elements) then
|
||||
return index, player, player_elements
|
||||
end
|
||||
end
|
||||
@@ -78,13 +78,13 @@ end
|
||||
--- @param player LuaPlayer
|
||||
--- @return ExpGui_GuiIter.ReturnType
|
||||
function GuiIter.player_elements(scope, player)
|
||||
if not player.valid then return nop end
|
||||
if not player.valid then return no_loop end
|
||||
|
||||
local scope_elements = registered_scopes[scope]
|
||||
if not scope_elements then return nop end
|
||||
if not scope_elements then return no_loop end
|
||||
|
||||
local player_elements = scope_elements[player.index]
|
||||
if not player_elements then return nop end
|
||||
if not player_elements then return no_loop end
|
||||
|
||||
local element_index, element = nil, nil
|
||||
return function()
|
||||
@@ -101,7 +101,7 @@ end
|
||||
--- @return ExpGui_GuiIter.ReturnType
|
||||
function GuiIter.filtered_elements(scope, players, online)
|
||||
local scope_elements = registered_scopes[scope]
|
||||
if not scope_elements then return nop end
|
||||
if not scope_elements then return no_loop end
|
||||
|
||||
local index, player, player_elements = nil, nil, nil
|
||||
local element_index, element = nil, nil
|
||||
@@ -128,7 +128,7 @@ end
|
||||
--- @return ExpGui_GuiIter.ReturnType
|
||||
function GuiIter.all_elements(scope)
|
||||
local scope_elements = registered_scopes[scope]
|
||||
if not scope_elements then return nop end
|
||||
if not scope_elements then return no_loop end
|
||||
|
||||
local player_index, player_elements, player = nil, nil, nil
|
||||
local element_index, element = nil, nil
|
||||
@@ -193,7 +193,7 @@ function GuiIter.get_online_elements(scope, filter)
|
||||
return GuiIter.filtered_elements(scope, game.connected_players)
|
||||
elseif class_name == "LuaPlayer" then
|
||||
--- @cast filter LuaPlayer
|
||||
if not filter.connected then return nop end
|
||||
if not filter.connected then return no_loop end
|
||||
return GuiIter.player_elements(scope, filter)
|
||||
elseif class_name == "LuaForce" then
|
||||
--- @cast filter LuaForce
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.19"
|
||||
"@clusterio/lib": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.19",
|
||||
"@types/node": "^20.14.9",
|
||||
"typescript": "^5.5.3"
|
||||
"@clusterio/lib": "catalog:",
|
||||
"@types/node": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"dependencies": {
|
||||
"@expcluster/lib_util": "workspace:*",
|
||||
"@sinclair/typebox": "^0.30.4"
|
||||
"@expcluster/lib_util": "workspace:^",
|
||||
"@sinclair/typebox": "catalog:"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@@ -51,7 +51,6 @@ return {
|
||||
"modules.gui.task-list",
|
||||
"modules.gui.warp-list",
|
||||
"modules.gui.player-list",
|
||||
"modules.gui.server-ups",
|
||||
"modules.gui.bonus",
|
||||
"modules.gui.vlayer",
|
||||
"modules.gui.research",
|
||||
|
||||
@@ -116,16 +116,6 @@ function External.get_server_status(server_id, raw)
|
||||
return not raw and server_id == current and "Current" or assert(servers[server_id], "No status found for server with id: " .. tostring(server_id))
|
||||
end
|
||||
|
||||
--[[-- Gets the ups of the current server
|
||||
@usage-- Get the ups of the current server
|
||||
local server_ups = External.get_server_ups()
|
||||
|
||||
]]
|
||||
function External.get_server_ups()
|
||||
assert(var, "No external data was found, use External.valid() to ensure external data exists.")
|
||||
return assert(var.server_ups, "No server ups was found, please ensure that the external service is running")
|
||||
end
|
||||
|
||||
--[[-- Connect a player to the given server
|
||||
@tparam LuaPlayer player The player that you want to request to join a different server
|
||||
@tparam string server_id The internal id of the server to connect to, can also be any address but this will show Unknown Server
|
||||
|
||||
@@ -327,10 +327,6 @@ attempt=Attempt
|
||||
difference=Diff
|
||||
main-tooltip=Research GUI
|
||||
|
||||
[server-ups]
|
||||
description=Toggle the server UPS display.
|
||||
no-ext=No external source was found, cannot display server ups.
|
||||
|
||||
[tool]
|
||||
main-tooltip=Tool
|
||||
apply=Apply
|
||||
|
||||
@@ -335,10 +335,6 @@ attempt=用時
|
||||
difference=差距
|
||||
main-tooltip=研究介面
|
||||
|
||||
[server-ups]
|
||||
description=啟動 UPS 顯示
|
||||
no-ext=沒找到外置數據,沒法顯示。
|
||||
|
||||
[tool]
|
||||
main-tooltip=工具
|
||||
apply=應用
|
||||
|
||||
@@ -335,10 +335,6 @@ attempt=用時
|
||||
difference=差距
|
||||
main-tooltip=研究介面
|
||||
|
||||
[server-ups]
|
||||
description=啟動 UPS 顯示
|
||||
no-ext=沒找到外置數據,沒法顯示。
|
||||
|
||||
[tool]
|
||||
main-tooltip=工具
|
||||
apply=應用
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
--[[-- Gui Module - Server UPS
|
||||
- Adds a server ups counter in the top right and a command to toggle is
|
||||
@gui server-ups
|
||||
@alias server_ups
|
||||
]]
|
||||
|
||||
local Gui = require("modules/exp_gui")
|
||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||
local External = require("modules.exp_legacy.expcore.external") --- @dep expcore.external
|
||||
local Commands = require("modules/exp_commands")
|
||||
|
||||
--- Stores the visible state of server ups
|
||||
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep 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,
|
||||
}
|
||||
|
||||
--- Label to show the server ups
|
||||
-- @element server_ups
|
||||
local server_ups = Gui.element("server_ups")
|
||||
:draw{
|
||||
type = "label",
|
||||
caption = "SUPS = 60.0",
|
||||
name = Gui.property_from_name,
|
||||
}
|
||||
:style{
|
||||
font = "default-game",
|
||||
}
|
||||
|
||||
--- Change the visible state when your data loads
|
||||
UsesServerUps:on_load(function(player_name, visible)
|
||||
local player = game.players[player_name]
|
||||
local label = player.gui.screen[server_ups.name]
|
||||
|
||||
--- @diagnostic disable-next-line undefined-field
|
||||
if not External.valid() or not storage.ext.var.server_ups then visible = false end
|
||||
label.visible = visible or false
|
||||
end)
|
||||
|
||||
--- Toggles if the server ups is visbile
|
||||
Commands.new("server-ups", { "server-ups.description" })
|
||||
:add_aliases{ "sups", "ups" }
|
||||
:register(function(player)
|
||||
local label = player.gui.screen[server_ups.name]
|
||||
if not External.valid() then
|
||||
label.visible = false
|
||||
return Commands.status.error{ "server-ups.no-ext" }
|
||||
end
|
||||
label.visible = not label.visible
|
||||
UsesServerUps:set(player, label.visible)
|
||||
end)
|
||||
|
||||
-- Set the location of the label
|
||||
-- 1920x1080: x=1455, y=30 (ui scale 100%)
|
||||
local function set_location(event)
|
||||
local player = game.players[event.player_index]
|
||||
local label = player.gui.screen[server_ups.name]
|
||||
if not label then
|
||||
label = server_ups(player.gui.screen)
|
||||
label.visible = UsesServerUps:get(player)
|
||||
end
|
||||
local res = player.display_resolution
|
||||
local uis = player.display_scale
|
||||
-- below ups and clock
|
||||
-- label.location = {x=res.width-423*uis, y=50*uis}
|
||||
label.location = { x = res.width - 363 * uis, y = 31 * uis }
|
||||
end
|
||||
|
||||
-- Draw the label when the player joins
|
||||
Event.add(defines.events.on_player_created, set_location)
|
||||
Event.add(defines.events.on_player_joined_game, set_location)
|
||||
|
||||
-- Update the caption for all online players
|
||||
-- percentage of game speed
|
||||
Event.on_nth_tick(60, function()
|
||||
if External.valid() then
|
||||
local caption = External.get_server_ups() .. " (" .. string.format("%.1f", External.get_server_ups() * 5 / 3) .. "%)"
|
||||
for _, player in pairs(game.connected_players) do
|
||||
player.gui.screen[server_ups.name].caption = caption
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Update when res or ui scale changes
|
||||
Event.add(defines.events.on_player_display_resolution_changed, set_location)
|
||||
Event.add(defines.events.on_player_display_scale_changed, set_location)
|
||||
@@ -13,17 +13,17 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.19"
|
||||
"@clusterio/lib": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.20",
|
||||
"@types/node": "^20.4.5",
|
||||
"typescript": "^5.5.3"
|
||||
"@clusterio/lib": "catalog:",
|
||||
"@types/node": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"dependencies": {
|
||||
"@expcluster/lib_commands": "workspace:*",
|
||||
"@expcluster/lib_util": "workspace:*",
|
||||
"@sinclair/typebox": "^0.30.4"
|
||||
"@expcluster/lib_commands": "workspace:^",
|
||||
"@expcluster/lib_util": "workspace:^",
|
||||
"@sinclair/typebox": "catalog:"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@@ -18,7 +18,7 @@ local valid, invalid = Commands.status.success, Commands.status.invalid_input
|
||||
local Roles = require("modules.exp_legacy.expcore.roles")
|
||||
local highest_role = Roles.get_player_highest_role
|
||||
|
||||
local types = {} --- @class Commands._types
|
||||
local types = {} --- @class Commands.types
|
||||
|
||||
--- A role defined by exp roles
|
||||
types.role = add("role", Commands.types.key_of(Roles.config.roles))
|
||||
|
||||
@@ -13,25 +13,25 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.19"
|
||||
"@clusterio/lib": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.20",
|
||||
"@clusterio/web_ui": "^2.0.0-alpha.20.b",
|
||||
"@types/node": "^20.4.5",
|
||||
"@types/react": "^18.2.21",
|
||||
"antd": "^5.13.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"typescript": "^5.5.3",
|
||||
"webpack": "^5.98.0",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-merge": "^5.9.0"
|
||||
"@clusterio/lib": "catalog:",
|
||||
"@clusterio/web_ui": "catalog:",
|
||||
"@types/node": "catalog:",
|
||||
"@types/react": "catalog:",
|
||||
"antd": "catalog:",
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:",
|
||||
"typescript": "catalog:",
|
||||
"webpack": "catalog:",
|
||||
"webpack-cli": "catalog:",
|
||||
"webpack-merge": "catalog:"
|
||||
},
|
||||
"dependencies": {
|
||||
"@expcluster/lib_commands": "workspace:*",
|
||||
"@expcluster/lib_util": "workspace:*",
|
||||
"@sinclair/typebox": "^0.30.4"
|
||||
"@expcluster/lib_commands": "workspace:^",
|
||||
"@expcluster/lib_util": "workspace:^",
|
||||
"@sinclair/typebox": "catalog:"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
onExit() {
|
||||
if (this.updateInterval) {
|
||||
clearInterval(this.updateInterval);
|
||||
}
|
||||
}
|
||||
|
||||
async onInstanceConfigFieldChanged(field: string, curr: unknown): Promise<void> {
|
||||
if (field === "exp_server_ups.update_interval") {
|
||||
this.onExit();
|
||||
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 },
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
@@ -13,15 +13,15 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.19"
|
||||
"@clusterio/lib": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.20",
|
||||
"@types/node": "^20.14.9",
|
||||
"typescript": "^5.5.3"
|
||||
"@clusterio/lib": "catalog:",
|
||||
"@types/node": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sinclair/typebox": "^0.30.4"
|
||||
"@sinclair/typebox": "catalog:"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"watch": "tsc --build --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.5.3"
|
||||
"typescript": "catalog:"
|
||||
}
|
||||
}
|
||||
4266
pnpm-lock.yaml
generated
Normal file
4266
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,16 @@
|
||||
packages:
|
||||
- "*"
|
||||
- "*"
|
||||
|
||||
catalog:
|
||||
"@clusterio/lib": ^2.0.0-alpha.21
|
||||
"@clusterio/web_ui": ^2.0.0-alpha.21
|
||||
"@sinclair/typebox": ^0.30.4
|
||||
"@types/node": ^20.14.9
|
||||
"@types/react": ^18.2.21
|
||||
"typescript": ^5.5.3
|
||||
"antd": ^5.13.0
|
||||
"react": ^18.2.0
|
||||
"react-dom": ^18.2.0
|
||||
"webpack": ^5.98.0
|
||||
"webpack-cli": ^5.1.4
|
||||
"webpack-merge": ^5.9.0
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
{ "path": "./exp_gui/" },
|
||||
{ "path": "./exp_legacy/" },
|
||||
{ "path": "./exp_scenario/" },
|
||||
{ "path": "./exp_server_ups/" },
|
||||
{ "path": "./exp_util/" },
|
||||
],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user