@expcluster/permission-groups 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/controller.ts +434 -0
- package/dist/browser/messages.d.ts +527 -0
- package/dist/browser/messages.d.ts.map +1 -0
- package/dist/browser/messages.js +561 -0
- package/dist/browser/messages.js.map +1 -0
- package/dist/browser/package.json +49 -0
- package/dist/browser/tsconfig.browser.tsbuildinfo +1 -0
- package/dist/browser/web/components/AssignmentForm.d.ts +7 -0
- package/dist/browser/web/components/AssignmentForm.d.ts.map +1 -0
- package/dist/browser/web/components/AssignmentForm.js +29 -0
- package/dist/browser/web/components/AssignmentForm.js.map +1 -0
- package/dist/browser/web/components/AssignmentsTable.d.ts +2 -0
- package/dist/browser/web/components/AssignmentsTable.d.ts.map +1 -0
- package/dist/browser/web/components/AssignmentsTable.js +61 -0
- package/dist/browser/web/components/AssignmentsTable.js.map +1 -0
- package/dist/browser/web/components/DeleteConfirm.d.ts +6 -0
- package/dist/browser/web/components/DeleteConfirm.d.ts.map +1 -0
- package/dist/browser/web/components/DeleteConfirm.js +7 -0
- package/dist/browser/web/components/DeleteConfirm.js.map +1 -0
- package/dist/browser/web/components/GroupForm.d.ts +5 -0
- package/dist/browser/web/components/GroupForm.d.ts.map +1 -0
- package/dist/browser/web/components/GroupForm.js +22 -0
- package/dist/browser/web/components/GroupForm.js.map +1 -0
- package/dist/browser/web/components/GroupViewPage.d.ts +2 -0
- package/dist/browser/web/components/GroupViewPage.d.ts.map +1 -0
- package/dist/browser/web/components/GroupViewPage.js +161 -0
- package/dist/browser/web/components/GroupViewPage.js.map +1 -0
- package/dist/browser/web/components/GroupsTable.d.ts +2 -0
- package/dist/browser/web/components/GroupsTable.d.ts.map +1 -0
- package/dist/browser/web/components/GroupsTable.js +29 -0
- package/dist/browser/web/components/GroupsTable.js.map +1 -0
- package/dist/browser/web/components/RoleMappingForm.d.ts +7 -0
- package/dist/browser/web/components/RoleMappingForm.d.ts.map +1 -0
- package/dist/browser/web/components/RoleMappingForm.js +32 -0
- package/dist/browser/web/components/RoleMappingForm.js.map +1 -0
- package/dist/browser/web/components/RoleMappingsTable.d.ts +2 -0
- package/dist/browser/web/components/RoleMappingsTable.d.ts.map +1 -0
- package/dist/browser/web/components/RoleMappingsTable.js +64 -0
- package/dist/browser/web/components/RoleMappingsTable.js.map +1 -0
- package/dist/browser/web/index.d.ts +13 -0
- package/dist/browser/web/index.d.ts.map +1 -0
- package/dist/browser/web/index.js +60 -0
- package/dist/browser/web/index.js.map +1 -0
- package/dist/node/controller.d.ts +37 -0
- package/dist/node/controller.d.ts.map +1 -0
- package/dist/node/controller.js +372 -0
- package/dist/node/controller.js.map +1 -0
- package/dist/node/index.d.ts +10 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +196 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/instance.d.ts +40 -0
- package/dist/node/instance.d.ts.map +1 -0
- package/dist/node/instance.js +155 -0
- package/dist/node/instance.js.map +1 -0
- package/dist/node/messages.d.ts +527 -0
- package/dist/node/messages.d.ts.map +1 -0
- package/dist/node/messages.js +620 -0
- package/dist/node/messages.js.map +1 -0
- package/dist/node/tsconfig.node.tsbuildinfo +1 -0
- package/dist/web/manifest.json +10 -0
- package/dist/web/static/exp_groups.afefd90b210f7c8e0df2.js +543 -0
- package/dist/web/static/index_ts.f7d30aa0c13ff0be393a.js +22 -0
- package/dist/web/static/main.c2178975889c1c720e80.js +653 -0
- package/dist/web/static/messages_ts.65a81c17fb37953c5d68.js +22 -0
- package/dist/web/static/package_json.aab0d3f37da0567c250c.js +22 -0
- package/dist/web/static/vendors-node_modules_pnpm_ant-design_icons_6_2_3_rea_94b50600dfe79448cabf92d130d83059_node_mo-c79f54.cf768c64b40c811ce6c9.js +273 -0
- package/dist/web/static/vendors-node_modules_pnpm_sinclair_typebox_0_30_4_node_modules_sinclair_typebox_typebox_js.7fa46fac84f2e9324e54.js +22 -0
- package/dist/web/static/web_index_tsx-webpack_sharing_consume_default_react.b4766180f4d467b7b24f.js +102 -0
- package/index.ts +183 -0
- package/instance.ts +171 -0
- package/messages.ts +692 -0
- package/module/control.lua +438 -0
- package/module/globals.lua +11 -0
- package/module/module.json +12 -0
- package/module/module_exports.lua +3 -0
- package/package.json +47 -0
- package/tsconfig.browser.json +4 -0
- package/tsconfig.json +7 -0
- package/tsconfig.node.json +5 -0
- package/web/components/AssignmentForm.tsx +74 -0
- package/web/components/AssignmentsTable.tsx +111 -0
- package/web/components/DeleteConfirm.tsx +16 -0
- package/web/components/GroupForm.tsx +45 -0
- package/web/components/GroupViewPage.tsx +287 -0
- package/web/components/GroupsTable.tsx +49 -0
- package/web/components/RoleMappingForm.tsx +106 -0
- package/web/components/RoleMappingsTable.tsx +107 -0
- package/web/index.tsx +108 -0
- package/webpack.config.js +34 -0
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
--[[-- ExpGroups
|
|
2
|
+
Adds permission group syncing to clusterio
|
|
3
|
+
]]
|
|
4
|
+
|
|
5
|
+
local clusterio_api = require("modules/clusterio/api")
|
|
6
|
+
local compat = require("modules/clusterio/compat") --[[@as LibCompat]]
|
|
7
|
+
|
|
8
|
+
--- Top level module table, contains event handlers and public methods
|
|
9
|
+
--- @class ExpGroups
|
|
10
|
+
local ExpGroups = {}
|
|
11
|
+
|
|
12
|
+
--- @class ExpPermissionGroups.GroupPermissions
|
|
13
|
+
--- @field is_blacklist boolean
|
|
14
|
+
--- @field permissions string[]?
|
|
15
|
+
|
|
16
|
+
--- @class ExpPermissionGroups.GroupRecord
|
|
17
|
+
--- @field id number
|
|
18
|
+
--- @field name string
|
|
19
|
+
--- @field permissions ExpPermissionGroups.GroupPermissions?
|
|
20
|
+
--- @field is_deleted boolean
|
|
21
|
+
|
|
22
|
+
--- @class ExpPermissionGroups.AssignmentRecord
|
|
23
|
+
--- @field name string
|
|
24
|
+
--- @field group_id number
|
|
25
|
+
--- @field is_deleted boolean
|
|
26
|
+
|
|
27
|
+
--- @class ExpPermissionGroups.ScriptData
|
|
28
|
+
--- @field factorio_to_clusterio_id table<number, number?>
|
|
29
|
+
--- @field clusterio_id_to_group table<number, LuaPermissionGroup?>
|
|
30
|
+
--- @field dirty_groups table<number, LuaPermissionGroup>
|
|
31
|
+
--- @field dirty_players table<string, LuaPlayer>
|
|
32
|
+
--- @field emit_updates boolean
|
|
33
|
+
local script_data = {}
|
|
34
|
+
|
|
35
|
+
local function setup_script_data()
|
|
36
|
+
if compat.script_data["exp_groups"] == nil then
|
|
37
|
+
--- @type ExpPermissionGroups.ScriptData
|
|
38
|
+
compat.script_data["exp_groups"] = {
|
|
39
|
+
factorio_to_clusterio_id = {},
|
|
40
|
+
clusterio_id_to_group = {},
|
|
41
|
+
dirty_groups = {},
|
|
42
|
+
dirty_players = {},
|
|
43
|
+
emit_updates = false,
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
ExpGroups.on_load()
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
--[[
|
|
51
|
+
Helper methods
|
|
52
|
+
]]
|
|
53
|
+
|
|
54
|
+
--- Get the default factorio permission group
|
|
55
|
+
--- @return LuaPermissionGroup
|
|
56
|
+
local function get_default_group()
|
|
57
|
+
return assert(game.permissions.get_group("Default"))
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
--- Move all players from one group to another
|
|
61
|
+
--- @param group_src LuaPermissionGroup
|
|
62
|
+
--- @param group_dst LuaPermissionGroup
|
|
63
|
+
local function move_players(group_src, group_dst)
|
|
64
|
+
local add_player = group_dst.add_player
|
|
65
|
+
for _, player in pairs(group_src.players) do
|
|
66
|
+
add_player(player)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
--- Apply an encoded permission definition to a group
|
|
71
|
+
--- @param group LuaPermissionGroup
|
|
72
|
+
--- @param permissions ExpPermissionGroups.GroupPermissions
|
|
73
|
+
local function decode_group_permissions(group, permissions)
|
|
74
|
+
-- Construct a hash map for faster lookup
|
|
75
|
+
local action_map = {}
|
|
76
|
+
for _, input_action_name in pairs(assert(permissions.permissions)) do
|
|
77
|
+
action_map[input_action_name] = true
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
-- Apply the whitelist / backlist to the group
|
|
81
|
+
local is_blacklist = permissions.is_blacklist
|
|
82
|
+
local action_allowed = not is_blacklist
|
|
83
|
+
for input_action_name, input_action in pairs(defines.input_action) do
|
|
84
|
+
if action_map[input_action_name] then
|
|
85
|
+
group.set_allows_action(input_action, action_allowed)
|
|
86
|
+
else
|
|
87
|
+
group.set_allows_action(input_action, is_blacklist)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
--- Encode the permissions of a group in a shorthand format
|
|
93
|
+
--- @param group LuaPermissionGroup
|
|
94
|
+
--- @return ExpPermissionGroups.GroupPermissions
|
|
95
|
+
local function encode_group_permissions(group)
|
|
96
|
+
local whitelist = {} --- @type string[]
|
|
97
|
+
local blacklist = {} --- @type string[]
|
|
98
|
+
local whitelist_index = 0
|
|
99
|
+
local blacklist_index = 0
|
|
100
|
+
|
|
101
|
+
-- Construct the whitelist and blacklist
|
|
102
|
+
local allows_action = group.allows_action
|
|
103
|
+
for input_action_name, input_action in pairs(defines.input_action) do
|
|
104
|
+
if allows_action(input_action) then
|
|
105
|
+
whitelist[whitelist_index] = input_action_name
|
|
106
|
+
whitelist_index = whitelist_index + 1
|
|
107
|
+
else
|
|
108
|
+
blacklist[blacklist_index] = input_action_name
|
|
109
|
+
blacklist_index = blacklist_index + 1
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
-- Return the whitelist if it is smaller
|
|
114
|
+
if blacklist_index > whitelist_index then
|
|
115
|
+
return whitelist_index > 0
|
|
116
|
+
and { is_blacklist = false, permissions = whitelist }
|
|
117
|
+
or { is_blacklist = false }
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
-- Otherwise return the blacklist as it is smaller
|
|
121
|
+
return blacklist_index > 0
|
|
122
|
+
and { is_blacklist = true, permissions = blacklist }
|
|
123
|
+
or { is_blacklist = true }
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
--[[
|
|
127
|
+
State handlers
|
|
128
|
+
]]
|
|
129
|
+
|
|
130
|
+
--- Update the factorio permission group
|
|
131
|
+
--- @param group_record ExpPermissionGroups.GroupRecord
|
|
132
|
+
local function update_group(group_record)
|
|
133
|
+
assert(not group_record.is_deleted)
|
|
134
|
+
|
|
135
|
+
-- Try find the group by id and then then name
|
|
136
|
+
local group = script_data.clusterio_id_to_group[group_record.id]
|
|
137
|
+
if not group then
|
|
138
|
+
group = game.permissions.get_group(group_record.name)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
-- Create a new group or update the found group
|
|
142
|
+
if not group or not group.valid then
|
|
143
|
+
group = assert(game.permissions.create_group(group_record.name))
|
|
144
|
+
else
|
|
145
|
+
group.name = group_record.name
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
-- Update the permissions for the group
|
|
149
|
+
if group_record.permissions then
|
|
150
|
+
decode_group_permissions(group, group_record.permissions)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
-- Update the script data
|
|
154
|
+
script_data.factorio_to_clusterio_id[group.group_id] = group_record.id
|
|
155
|
+
script_data.clusterio_id_to_group[group_record.id] = group
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
--- Delete the factorio permission group
|
|
159
|
+
--- @param group_record ExpPermissionGroups.GroupRecord
|
|
160
|
+
local function delete_group(group_record)
|
|
161
|
+
assert(group_record.is_deleted)
|
|
162
|
+
|
|
163
|
+
local default_group = get_default_group()
|
|
164
|
+
local group = script_data.clusterio_id_to_group[group_record.id]
|
|
165
|
+
if group then
|
|
166
|
+
move_players(group, default_group)
|
|
167
|
+
group.destroy()
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
--- Update an assignment by moving the player to their new group
|
|
172
|
+
--- @param assignment_record ExpPermissionGroups.AssignmentRecord
|
|
173
|
+
local function update_assignment(assignment_record)
|
|
174
|
+
assert(not assignment_record.is_deleted)
|
|
175
|
+
|
|
176
|
+
local group = script_data.clusterio_id_to_group[assignment_record.group_id]
|
|
177
|
+
local player = assert(game.get_player(assignment_record.name))
|
|
178
|
+
if group then
|
|
179
|
+
group.add_player(player)
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
--- Clear an assignment by moving the player to the default group
|
|
184
|
+
--- @param assignment_record ExpPermissionGroups.AssignmentRecord
|
|
185
|
+
local function delete_assignment(assignment_record)
|
|
186
|
+
assert(assignment_record.is_deleted)
|
|
187
|
+
|
|
188
|
+
local default_group = get_default_group()
|
|
189
|
+
local player = assert(game.get_player(assignment_record.name))
|
|
190
|
+
default_group.add_player(player)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
--[[
|
|
194
|
+
Public methods
|
|
195
|
+
]]
|
|
196
|
+
|
|
197
|
+
--- Restore local references to persistent script data after load
|
|
198
|
+
function ExpGroups.on_load()
|
|
199
|
+
script_data = compat.script_data["exp_groups"]
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
--- Enable or disable emitting lua changes back to the instance plugin
|
|
203
|
+
--- @param enabled boolean?
|
|
204
|
+
function ExpGroups.set_emit_events(enabled)
|
|
205
|
+
script_data.emit_updates = enabled ~= false
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
--- Replace local state with expected controller state on startup
|
|
209
|
+
--- @param group_records ExpPermissionGroups.GroupRecord[]
|
|
210
|
+
function ExpGroups.initialise_groups(group_records)
|
|
211
|
+
local _emit_events = script_data.emit_updates
|
|
212
|
+
script_data.emit_updates = false
|
|
213
|
+
|
|
214
|
+
-- Update all the received groups
|
|
215
|
+
local seen_clusterio_ids = {} --- @type table<number, boolean>
|
|
216
|
+
for _, group_record in pairs(group_records) do
|
|
217
|
+
update_group(group_record)
|
|
218
|
+
seen_clusterio_ids[group_record.id] = true
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
-- Cleanup the script data, removing stale group ids
|
|
222
|
+
local factorio_to_clusterio_id = script_data.factorio_to_clusterio_id
|
|
223
|
+
local clusterio_id_to_group = script_data.clusterio_id_to_group
|
|
224
|
+
for factorio_id, clusterio_id in pairs(factorio_to_clusterio_id) do
|
|
225
|
+
if not seen_clusterio_ids[clusterio_id] then
|
|
226
|
+
factorio_to_clusterio_id[factorio_id] = nil
|
|
227
|
+
clusterio_id_to_group[clusterio_id] = nil
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
-- Remove all other groups
|
|
232
|
+
local default_group = get_default_group()
|
|
233
|
+
local default_group_id = default_group.group_id
|
|
234
|
+
for _, group in pairs(game.permissions.groups) do
|
|
235
|
+
if not factorio_to_clusterio_id[group.group_id] and group.group_id ~= default_group_id then
|
|
236
|
+
move_players(group, default_group)
|
|
237
|
+
group.destroy()
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
script_data.emit_updates = _emit_events
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
--- Receive an updated version of a group record
|
|
245
|
+
--- @param group_record ExpPermissionGroups.GroupRecord
|
|
246
|
+
function ExpGroups.receive_group_update(group_record)
|
|
247
|
+
local _emit_events = script_data.emit_updates
|
|
248
|
+
script_data.emit_updates = false
|
|
249
|
+
|
|
250
|
+
if group_record.is_deleted then
|
|
251
|
+
delete_group(group_record)
|
|
252
|
+
else
|
|
253
|
+
update_group(group_record)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
script_data.emit_updates = _emit_events
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
--- Receive an updated version of a assignment record
|
|
260
|
+
--- @param assignment_record ExpPermissionGroups.AssignmentRecord
|
|
261
|
+
function ExpGroups.receive_assignment_update(assignment_record)
|
|
262
|
+
local _emit_events = script_data.emit_updates
|
|
263
|
+
script_data.emit_updates = false
|
|
264
|
+
|
|
265
|
+
if assignment_record.is_deleted then
|
|
266
|
+
delete_assignment(assignment_record)
|
|
267
|
+
else
|
|
268
|
+
update_assignment(assignment_record)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
script_data.emit_updates = _emit_events
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
--- Get the current script data for debugging purposes
|
|
275
|
+
--- @package
|
|
276
|
+
function ExpGroups._script_data()
|
|
277
|
+
return script_data
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
--[[
|
|
281
|
+
IPC events
|
|
282
|
+
]]
|
|
283
|
+
|
|
284
|
+
--- Emit a group update to the instance plugin
|
|
285
|
+
--- @param group LuaPermissionGroup
|
|
286
|
+
local function emit_group_update(group)
|
|
287
|
+
clusterio_api.send_json("exp_group:group_updated", {
|
|
288
|
+
group_name = group.name,
|
|
289
|
+
group_id = script_data.factorio_to_clusterio_id[group.group_id],
|
|
290
|
+
permissions = encode_group_permissions(group),
|
|
291
|
+
})
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
--- Emit a group deletion to the instance plugin
|
|
295
|
+
--- @param group_id number
|
|
296
|
+
--- @param group_name string
|
|
297
|
+
local function emit_group_delete(group_id, group_name)
|
|
298
|
+
clusterio_api.send_json("exp_group:group_deleted", {
|
|
299
|
+
group_name = group_name,
|
|
300
|
+
group_id = script_data.factorio_to_clusterio_id[group_id],
|
|
301
|
+
})
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
--- Emit a player assignment to the instance plugin
|
|
305
|
+
--- @param assignments table<string, number>
|
|
306
|
+
local function emit_player_assignments(assignments)
|
|
307
|
+
clusterio_api.send_json("exp_group:player_assignments", {
|
|
308
|
+
assignments = assignments
|
|
309
|
+
})
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
--[[
|
|
313
|
+
IPC event queuing
|
|
314
|
+
]]
|
|
315
|
+
|
|
316
|
+
--- Mark a group as changed
|
|
317
|
+
--- @param group LuaPermissionGroup
|
|
318
|
+
local function mark_group_dirty(group)
|
|
319
|
+
script_data.dirty_groups[group.group_id] = group
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
--- Mark a player as changed
|
|
323
|
+
--- @param player LuaPlayer
|
|
324
|
+
local function mark_player_dirty(player)
|
|
325
|
+
script_data.dirty_players[player.name] = player
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
--- Flush queued group updates to the instance plugin
|
|
329
|
+
local function flush_group_updates()
|
|
330
|
+
-- Check if updates should be updated
|
|
331
|
+
if not script_data.emit_updates then
|
|
332
|
+
script_data.dirty_groups = {}
|
|
333
|
+
return
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
-- Get all the groups and emit their updates
|
|
337
|
+
for _, group in pairs(script_data.dirty_groups) do
|
|
338
|
+
if group.valid then
|
|
339
|
+
emit_group_update(group)
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
script_data.dirty_groups = {}
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
--- Flush queued player updates to the instance plugin
|
|
347
|
+
local function flush_player_updates()
|
|
348
|
+
-- Check if updates should be updated
|
|
349
|
+
if not script_data.emit_updates then
|
|
350
|
+
script_data.dirty_players = {}
|
|
351
|
+
return
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
-- Construct the update payload
|
|
355
|
+
local assignments = {} --- @type table<string, number>
|
|
356
|
+
for player_name, player in pairs(script_data.dirty_players) do
|
|
357
|
+
local group = player.valid and player.permission_group
|
|
358
|
+
if group then
|
|
359
|
+
assignments[player_name] = script_data.factorio_to_clusterio_id[group.group_id]
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
emit_player_assignments(assignments)
|
|
364
|
+
|
|
365
|
+
script_data.dirty_players = {}
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
--[[
|
|
369
|
+
Factorio events
|
|
370
|
+
]]
|
|
371
|
+
|
|
372
|
+
--- Handle clusterio server startup
|
|
373
|
+
local function on_server_startup()
|
|
374
|
+
setup_script_data()
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
--- Handle creation of permission groups
|
|
378
|
+
--- @param event EventData.on_permission_group_added
|
|
379
|
+
local function on_permission_group_added(event)
|
|
380
|
+
-- Check if updates should be updated
|
|
381
|
+
if not script_data.emit_updates then
|
|
382
|
+
return
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
mark_group_dirty(event.group)
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
--- Handle deletion of permission groups
|
|
389
|
+
--- @param event EventData.on_permission_group_deleted
|
|
390
|
+
local function on_permission_group_deleted(event)
|
|
391
|
+
-- Check if updates should be updated
|
|
392
|
+
if not script_data.emit_updates then
|
|
393
|
+
return
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
emit_group_delete(event.id, event.group_name)
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
--- Handle edits make to permission groups
|
|
400
|
+
--- @param event EventData.on_permission_group_edited
|
|
401
|
+
local function on_permission_group_edited(event)
|
|
402
|
+
-- Check if updates should be updated
|
|
403
|
+
if not script_data.emit_updates then
|
|
404
|
+
return
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
-- Check if this is a player or group event
|
|
408
|
+
if event.type == "add-player" or event.type == "remove-player" then
|
|
409
|
+
local player = assert(game.get_player(event.other_player_index))
|
|
410
|
+
mark_player_dirty(player)
|
|
411
|
+
else
|
|
412
|
+
mark_group_dirty(event.group)
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
--- Periodically flush queued changes
|
|
417
|
+
local function on_nth_tick_flush()
|
|
418
|
+
flush_group_updates()
|
|
419
|
+
flush_player_updates()
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
local e = defines.events
|
|
423
|
+
|
|
424
|
+
local events = {
|
|
425
|
+
[clusterio_api.events.on_server_startup] = on_server_startup,
|
|
426
|
+
[e.on_multiplayer_init] = on_server_startup,
|
|
427
|
+
[e.on_permission_group_added] = on_permission_group_added,
|
|
428
|
+
[e.on_permission_group_deleted] = on_permission_group_deleted,
|
|
429
|
+
[e.on_permission_group_edited] = on_permission_group_edited,
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
local on_nth_tick = {
|
|
433
|
+
[300] = on_nth_tick_flush,
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
ExpGroups.events = events --- @package
|
|
437
|
+
ExpGroups.on_nth_tick = on_nth_tick --- @package
|
|
438
|
+
return ExpGroups
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
--[[
|
|
2
|
+
It is best practice to not expose any globals because all modules share a global environment
|
|
3
|
+
However, sometimes you need globals, for example to access functions within rcon commands
|
|
4
|
+
Therefore, we advise that this should be the only file in your module to expose globals
|
|
5
|
+
Typically this would be your control file as shown in the example below
|
|
6
|
+
]]
|
|
7
|
+
|
|
8
|
+
--- @diagnostic disable: global-in-non-module
|
|
9
|
+
|
|
10
|
+
-- Access using `/sc exp_groups.foo()`
|
|
11
|
+
exp_groups = require("modules/exp_groups/control")
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@expcluster/permission-groups",
|
|
3
|
+
"version": "7.0.1",
|
|
4
|
+
"description": "Clusterio plugin providing syncing of permission groups",
|
|
5
|
+
"author": "Cooldude2606 <https://github.com/Cooldude2606>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": "explosivegaming/ExpCluster",
|
|
8
|
+
"main": "dist/node/index.js",
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=18"
|
|
11
|
+
},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"@clusterio/controller": "^2.0.0-alpha.27",
|
|
14
|
+
"@clusterio/host": "^2.0.0-alpha.27",
|
|
15
|
+
"@clusterio/lib": "^2.0.0-alpha.27",
|
|
16
|
+
"@clusterio/web_ui": "^2.0.0-alpha.27"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@ant-design/icons": "^6.2.3",
|
|
20
|
+
"@types/node": "^20.17.19",
|
|
21
|
+
"@types/react": "^18.3.18",
|
|
22
|
+
"antd": "^5.24.2",
|
|
23
|
+
"react": "^18.2.0",
|
|
24
|
+
"react-dom": "^18.2.0",
|
|
25
|
+
"react-router-dom": "^6.29.0",
|
|
26
|
+
"typescript": "^5.7.3",
|
|
27
|
+
"webpack": "^5.98.0",
|
|
28
|
+
"webpack-cli": "^5.1.4",
|
|
29
|
+
"webpack-merge": "^5.9.0",
|
|
30
|
+
"@clusterio/controller": "^2.0.0-alpha.27",
|
|
31
|
+
"@clusterio/host": "^2.0.0-alpha.27",
|
|
32
|
+
"@clusterio/lib": "^2.0.0-alpha.27",
|
|
33
|
+
"@clusterio/web_ui": "^2.0.0-alpha.27"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@sinclair/typebox": "^0.30.4"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"clusterio",
|
|
43
|
+
"clusterio-plugin",
|
|
44
|
+
"factorio"
|
|
45
|
+
],
|
|
46
|
+
"scripts": {}
|
|
47
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React, { useContext, useEffect } from "react";
|
|
2
|
+
import { Modal, Form, Select } from "antd";
|
|
3
|
+
|
|
4
|
+
import { ControlContext, useUsers } from "@clusterio/web_ui";
|
|
5
|
+
import * as messages from "../../messages";
|
|
6
|
+
import type { WebPlugin } from "..";
|
|
7
|
+
|
|
8
|
+
export default function AssignmentForm({ open, setOpen, initial }: {
|
|
9
|
+
open: boolean,
|
|
10
|
+
setOpen: (open: boolean) => void,
|
|
11
|
+
initial?: messages.AssignmentRecord,
|
|
12
|
+
}) {
|
|
13
|
+
const control = useContext(ControlContext);
|
|
14
|
+
const plugin = control.plugins.get("exp_groups") as WebPlugin;
|
|
15
|
+
|
|
16
|
+
const [groups] = plugin.useGroups();
|
|
17
|
+
const [users] = useUsers();
|
|
18
|
+
|
|
19
|
+
const [form] = Form.useForm();
|
|
20
|
+
|
|
21
|
+
function submit(values: any) {
|
|
22
|
+
if (initial) {
|
|
23
|
+
control.send(new messages.AssignmentUpdateRequest(
|
|
24
|
+
new messages.AssignmentRecord(
|
|
25
|
+
values.name,
|
|
26
|
+
values.groupId,
|
|
27
|
+
)
|
|
28
|
+
));
|
|
29
|
+
} else {
|
|
30
|
+
control.send(new messages.AssignmentCreateRequest(
|
|
31
|
+
values.name,
|
|
32
|
+
values.groupId,
|
|
33
|
+
));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
setOpen(false);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (open) {
|
|
41
|
+
form.resetFields();
|
|
42
|
+
form.setFieldsValue(initial);
|
|
43
|
+
}
|
|
44
|
+
}, [open, initial]);
|
|
45
|
+
|
|
46
|
+
return <Modal
|
|
47
|
+
title={initial ? "Edit Assignment" : "Create Assignment"}
|
|
48
|
+
open={open}
|
|
49
|
+
onCancel={() => setOpen(false)}
|
|
50
|
+
onOk={() => form.submit()}
|
|
51
|
+
>
|
|
52
|
+
<Form form={form} onFinish={submit}>
|
|
53
|
+
<Form.Item name="name" label="Player" rules={[{ required: true }]}>
|
|
54
|
+
<Select disabled={Boolean(initial)} showSearch>
|
|
55
|
+
{[...users.values()].map(u => (
|
|
56
|
+
<Select.Option key={u.name} value={u.name}>
|
|
57
|
+
{u.name}
|
|
58
|
+
</Select.Option>
|
|
59
|
+
))}
|
|
60
|
+
</Select>
|
|
61
|
+
</Form.Item>
|
|
62
|
+
|
|
63
|
+
<Form.Item name="groupId" label="Group" rules={[{ required: true }]}>
|
|
64
|
+
<Select>
|
|
65
|
+
{[...groups.values()].map(g => (
|
|
66
|
+
<Select.Option key={g.id} value={g.id}>
|
|
67
|
+
{g.name}
|
|
68
|
+
</Select.Option>
|
|
69
|
+
))}
|
|
70
|
+
</Select>
|
|
71
|
+
</Form.Item>
|
|
72
|
+
</Form>
|
|
73
|
+
</Modal>;
|
|
74
|
+
}
|