mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 11:35:22 +09:00
Merge branch 'patch/5.7.1'
This commit is contained in:
@@ -56,6 +56,7 @@ All are welcome to make pull requests and issues for this scenario, if you are i
|
||||
|
||||
| Scenario Version* | Version Name | Factorio Version** |
|
||||
|---|---|---|
|
||||
| [v5.7][s5.7] | Warp System | [v0.17.47][f0.17.47] |
|
||||
| [v5.6][s5.6] | Information Guis | [v0.17.44][f0.17.44] |
|
||||
| [v5.5][s5.5] | Gui System | [v0.17.43][f0.17.43] |
|
||||
| [v5.4][s5.4] | Admin Controls | [v0.17.32][f0.17.32] |
|
||||
@@ -73,6 +74,7 @@ All are welcome to make pull requests and issues for this scenario, if you are i
|
||||
|
||||
\*\* Factorio versions show the version they were made for, often the minimum requirement.
|
||||
|
||||
[s5.7]: https://github.com/explosivegaming/scenario/releases/tag/5.7.0
|
||||
[s5.6]: https://github.com/explosivegaming/scenario/releases/tag/5.6.0
|
||||
[s5.5]: https://github.com/explosivegaming/scenario/releases/tag/5.5.0
|
||||
[s5.4]: https://github.com/explosivegaming/scenario/releases/tag/5.4.0
|
||||
@@ -86,6 +88,7 @@ All are welcome to make pull requests and issues for this scenario, if you are i
|
||||
[s1.0]: https://github.com/explosivegaming/scenario/releases/tag/v1.0
|
||||
[s0.1]: https://github.com/explosivegaming/scenario/releases/tag/v0.1
|
||||
|
||||
[f0.17.47]: https://wiki.factorio.com/Version_history/0.17.0#0.17.47
|
||||
[f0.17.44]: https://wiki.factorio.com/Version_history/0.17.0#0.17.44
|
||||
[f0.17.43]: https://wiki.factorio.com/Version_history/0.17.0#0.17.43
|
||||
[f0.17.32]: https://wiki.factorio.com/Version_history/0.17.0#0.17.32
|
||||
|
||||
@@ -213,12 +213,13 @@ Gui.classes.left_frames = LeftFrames
|
||||
|
||||
LeftFrames._prototype:on_draw(player,frame) --- Use to draw your elements to the new frame
|
||||
LeftFrames._prototype:on_update(player,frame) --- Use to edit your frame when there is no need to redraw it
|
||||
LeftFrames._prototype:on_player_toggle(player,frame) --- Triggered when the player toggle the left frame
|
||||
LeftFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add
|
||||
]]
|
||||
|
||||
local CenterFrames = require 'expcore.gui.center'
|
||||
Gui.get_center_flow = CenterFrames.get_flow
|
||||
Gui.toggle_left_frame = CenterFrames.toggle_frame
|
||||
Gui.toggle_center_frame = CenterFrames.toggle_frame
|
||||
Gui.draw_center_frame = CenterFrames.draw_frame
|
||||
Gui.redraw_center_frame = CenterFrames.redraw_frames
|
||||
Gui.new_center_frame = CenterFrames.new_frame
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
|
||||
LeftFrames._prototype:on_draw(player,frame) --- Use to draw your elements to the new frame
|
||||
LeftFrames._prototype:on_update(player,frame) --- Use to edit your frame when there is no need to redraw it
|
||||
LeftFrames._prototype:on_player_toggle(player,frame) --- Is triggered when the player presses the toggle button
|
||||
LeftFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add
|
||||
]]
|
||||
local Gui = require 'expcore.gui.core'
|
||||
@@ -58,7 +59,8 @@ local LeftFrames = {
|
||||
frames={},
|
||||
_prototype=Gui._prototype_factory{
|
||||
on_draw = Gui._event_factory('on_draw'),
|
||||
on_update = Gui._event_factory('on_update')
|
||||
on_update = Gui._event_factory('on_update'),
|
||||
on_player_toggle = Gui._event_factory('on_player_toggle')
|
||||
}
|
||||
}
|
||||
setmetatable(LeftFrames._prototype, {
|
||||
@@ -138,7 +140,12 @@ function LeftFrames.new_frame(permision_name)
|
||||
mt.__call = self.event_handler
|
||||
|
||||
self:on_click(function(player,_element)
|
||||
self:toggle(player)
|
||||
local visible = self:toggle(player)
|
||||
|
||||
if self.events.on_player_toggle then
|
||||
local frame = self:get_frame(player)
|
||||
self.events.on_player_toggle(player,frame,visible)
|
||||
end
|
||||
end)
|
||||
|
||||
LeftFrames.frames[self.name] = self
|
||||
@@ -258,6 +265,10 @@ Buttons.new_button()
|
||||
for _,define in pairs(LeftFrames.frames) do
|
||||
local frame = LeftFrames.get_frame(define.name,player)
|
||||
frame.visible = false
|
||||
|
||||
if define.events.on_player_toggle then
|
||||
define.events.on_player_toggle(player,frame,false)
|
||||
end
|
||||
end
|
||||
element.visible = false
|
||||
end)
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
|
||||
local Game = require 'utils.game'
|
||||
local Event = require 'utils.event'
|
||||
local Sudo = require 'expcore.sudo'
|
||||
|
||||
local Permissions_Groups = {
|
||||
groups={}, -- store for the different groups that are created
|
||||
@@ -130,7 +131,7 @@ end
|
||||
-- @treturn boolean true if the player was added successfully, false other wise
|
||||
function Permissions_Groups.set_player_group(player,group)
|
||||
player = Game.get_player_from_any(player)
|
||||
local group = Permissions_Groups.get_group_by_name(group)
|
||||
group = Permissions_Groups.get_group_by_name(group)
|
||||
if not group or not player then return false end
|
||||
group:add_player(player)
|
||||
return true
|
||||
@@ -228,7 +229,7 @@ function Permissions_Groups._prototype:add_player(player)
|
||||
player = Game.get_player_from_any(player)
|
||||
local group = self:get_raw()
|
||||
if not group or not player then return false end
|
||||
group.add_player(player)
|
||||
Sudo('add-player-to-permission-group',group,player)
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -239,7 +240,7 @@ function Permissions_Groups._prototype:remove_player(player)
|
||||
player = Game.get_player_from_any(player)
|
||||
local group = self:get_raw()
|
||||
if not group or not player then return false end
|
||||
group.remove_player(player)
|
||||
Sudo('remove-player-from-permission-group',group,player)
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -279,4 +280,11 @@ Event.on_init(function()
|
||||
Permissions_Groups.reload_permissions()
|
||||
end)
|
||||
|
||||
Sudo.register('add-player-to-permission-group',function(permission_group,player)
|
||||
permission_group.add_player(player)
|
||||
end)
|
||||
Sudo.register('remove-player-from-permission-group',function(permission_group,player)
|
||||
permission_group.remove_player(player)
|
||||
end)
|
||||
|
||||
return Permissions_Groups
|
||||
@@ -158,6 +158,7 @@ local Game = require 'utils.game'
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
local Groups = require 'expcore.permission_groups'
|
||||
local Sudo = require 'expcore.sudo'
|
||||
local Colours = require 'resources.color_presets'
|
||||
local write_json = ext_require('expcore.common','write_json')
|
||||
|
||||
@@ -466,7 +467,9 @@ end
|
||||
-- flag param - player - the player that has had they roles changed
|
||||
-- flag param - state - the state of the flag, aka if the flag is present
|
||||
function Roles.define_flag_trigger(name,callback)
|
||||
Roles.config.flags[name] = callback -- this can desync if there are upvalues
|
||||
local sudo_name = 'role-flag-'..name
|
||||
Roles.config.flags[name] = sudo_name
|
||||
Sudo.register(sudo_name,callback)
|
||||
end
|
||||
|
||||
--- Sets the default role which every player will have, this needs to be called at least once
|
||||
@@ -753,12 +756,9 @@ end
|
||||
local function role_update(event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
-- Updates flags given to the player
|
||||
for flag,callback in pairs(Roles.config.flags) do
|
||||
for flag,sudo_name in pairs(Roles.config.flags) do
|
||||
local state = Roles.player_has_flag(player,flag)
|
||||
local success,err = pcall(callback,player,state)
|
||||
if not success then
|
||||
log{'expcore-roles.error-log-format-flag',flag,err}
|
||||
end
|
||||
Sudo(sudo_name,player,state)
|
||||
end
|
||||
-- Updates the players permission group
|
||||
local highest = Roles.get_player_highest_role(player)
|
||||
@@ -766,7 +766,7 @@ local function role_update(event)
|
||||
if highest.permission_group[1] then
|
||||
local group = game.permissions.get_group(highest.permission_group[2])
|
||||
if group then
|
||||
group.add_player(player)
|
||||
Sudo('add-player-to-permission-group',group,player)
|
||||
end
|
||||
else
|
||||
Groups.set_player_group(player,highest.permission_group)
|
||||
|
||||
78
expcore/sudo.lua
Normal file
78
expcore/sudo.lua
Normal file
@@ -0,0 +1,78 @@
|
||||
--- An extention of task and token to allow a single require to register and run functions bypassing all permissions
|
||||
--[[
|
||||
>>>> Usage
|
||||
To use sudo you must register the allowed functions when the files are loaded, often this will just be giving access to
|
||||
some functions within a module if you expect that some parts may be blocked by in game permissions or a custom system you have made
|
||||
|
||||
-- this will be blocked if the current player (from a command or gui) is not admin
|
||||
local function make_admin(player)
|
||||
player.admin = true
|
||||
end
|
||||
|
||||
-- here we give sudo access to the function under the name "make-admin"
|
||||
Sudo.register('make-admin',make_admin)
|
||||
|
||||
-- this will allow us to bypass this by runing one tick later outside of any player scope
|
||||
Sudo.run('make-admin',game.player)
|
||||
|
||||
>>>> Functions
|
||||
Sudo.register(name,callback) --- Registers a new callback under the given name, used to avoid desynces
|
||||
Sudo.get(name) --- Gets the function that is registered under the given name
|
||||
Sudo.run(name,...) --- Runs the function that is registered under the given name, you may supply any number of params as needed
|
||||
]]
|
||||
local Task = require 'utils.task'
|
||||
local Token = require 'utils.token'
|
||||
|
||||
local Sudo = {
|
||||
tokens={}
|
||||
}
|
||||
|
||||
local internal_run =
|
||||
Token.register(function(params)
|
||||
local func = Token.get(params.token)
|
||||
func(unpack(params.params))
|
||||
end)
|
||||
|
||||
--- Registers a new callback under the given name, used to avoid desynces
|
||||
-- @tparam string name the name that will be used to call this function
|
||||
-- @tparam function callback the function that will be called by this name
|
||||
function Sudo.register(name,callback)
|
||||
if _LIFECYCLE == 8 then
|
||||
error('Calling Sudo.register after on_init() or on_load() has run is a desync risk.', 2)
|
||||
end
|
||||
|
||||
if Sudo.tokens[name] then
|
||||
error(name..' is already registered',2)
|
||||
end
|
||||
|
||||
Sudo.tokens[name] = Token.register(callback)
|
||||
end
|
||||
|
||||
--- Gets the function that is registered under the given name
|
||||
-- @tparam string name the name of the function you want to get
|
||||
function Sudo.get(name)
|
||||
local token = Sudo.tokens[name]
|
||||
return token and Token.get(token)
|
||||
end
|
||||
|
||||
--- Runs the function that is registered under the given name, you may supply any number of params as needed
|
||||
-- @tparam name string the name of the function you want to run
|
||||
-- @tparam[opt] any ... the other params that you want to pass to your function
|
||||
function Sudo.run(name,...)
|
||||
local token = Sudo.tokens[name]
|
||||
|
||||
if not token then
|
||||
error('Sudo does not have access to run "'..tostring(name)..'" please make sure it is registered to sudo',2)
|
||||
end
|
||||
|
||||
Task.set_timeout_in_ticks(1, internal_run, {
|
||||
token = token,
|
||||
params = {...}
|
||||
})
|
||||
end
|
||||
|
||||
return setmetatable(Sudo,{
|
||||
__call = function(self,...)
|
||||
self.run(...)
|
||||
end
|
||||
})
|
||||
@@ -84,7 +84,7 @@ main-caption=Warp List
|
||||
main-tooltip=Warp list, must be within __1__ tiles to use
|
||||
sub-tooltip=Warps can only be used every __1__ seconds and when within __2__ tiles
|
||||
too-close=Cant make warp; too close to warp: __1__
|
||||
last-edit=Last edited by __1__ at __2__
|
||||
last-edit=Last edited by __1__ at __2__\nClick to view on map
|
||||
add-tooltip=Add new warp
|
||||
confirm-tooltip=Save changes
|
||||
cancel-tooltip=Discard changes
|
||||
|
||||
@@ -11,7 +11,8 @@ local interface_modules = {
|
||||
['Group']='expcore.permission_groups',
|
||||
['Roles']='expcore.roles',
|
||||
['Store']='expcore.store',
|
||||
['Gui']='expcore.gui'
|
||||
['Gui']='expcore.gui',
|
||||
['Sudo']='expcore.sudo'
|
||||
}
|
||||
|
||||
-- loads all the modules given in the above table
|
||||
|
||||
@@ -82,7 +82,7 @@ Gui.new_button()
|
||||
end)
|
||||
:on_click(function(player,element)
|
||||
local reason = element.parent.entry.text or 'Non Given'
|
||||
local action_name = Store.get_child(action_name_store,player.name)
|
||||
local action_name = Store.get(action_name_store,player.name)
|
||||
local reason_callback = config[action_name].reason_callback
|
||||
reason_callback(player,reason)
|
||||
Store.clear(action_player_store,player.name)
|
||||
@@ -339,6 +339,20 @@ player_list_name = player_list:uid()
|
||||
Store.register(action_player_store,function(value,category)
|
||||
local player = Game.get_player_from_any(category)
|
||||
update_action_bar(player)
|
||||
|
||||
local frame = player_list:get_frame(player)
|
||||
local data_table = frame.container.scroll.table
|
||||
for _,next_player in pairs(game.connected_players) do
|
||||
local element = data_table[next_player.name][open_action_bar.name]
|
||||
local style = 'frame_button'
|
||||
if next_player.name == value then
|
||||
style = 'tool_button'
|
||||
end
|
||||
element.style = style
|
||||
Gui.set_paddinge(element,-2,-2,-2,-2)
|
||||
element.style.width = 8
|
||||
element.style.height = 14
|
||||
end
|
||||
end)
|
||||
|
||||
--- When the action name is changed the reason input will update
|
||||
|
||||
@@ -12,16 +12,19 @@ local format_time,table_keys,table_values,table_keysort = ext_require('expcore.c
|
||||
local warp_list
|
||||
local warp_name_store = 'gui.left.warps.names'
|
||||
local warp_icon_store = 'gui.left.warps.tags'
|
||||
local warp_player_in_range_store = 'gui.left.warps.allowed'
|
||||
local warp_player_in_range_store = 'gui.left.warps.in_range'
|
||||
|
||||
local warp_details = {}
|
||||
local force_warps = {}
|
||||
local keep_open = {}
|
||||
Global.register({
|
||||
warp_details=warp_details,
|
||||
force_warps=force_warps
|
||||
force_warps=force_warps,
|
||||
keep_open=keep_open
|
||||
},function(tbl)
|
||||
force_warps = tbl.force_warps
|
||||
warp_details = tbl.warp_details
|
||||
keep_open = tbl.keep_open
|
||||
end)
|
||||
|
||||
--- Returns if a player is allowed to edit the given warp
|
||||
@@ -236,6 +239,16 @@ local function remove_warp(warp_id)
|
||||
warp_details[warp_id] = nil
|
||||
end
|
||||
|
||||
--- Used on the name label to allow zoom to map
|
||||
local zoom_to_map_name = Gui.uid_name()
|
||||
Gui.on_click(zoom_to_map_name,function(event)
|
||||
local warp_id = event.element.parent.name
|
||||
local warp = warp_details[warp_id]
|
||||
local position = warp.position
|
||||
event.player.zoom_to_world(position,1.5)
|
||||
end)
|
||||
|
||||
|
||||
--- This timer controls when a player is able to warp, eg every 60 seconds
|
||||
local warp_timer =
|
||||
Gui.new_progressbar()
|
||||
@@ -247,7 +260,9 @@ Gui.new_progressbar()
|
||||
style.color = Colors.light_blue
|
||||
end)
|
||||
:on_store_complete(function(player_name,reset)
|
||||
Store.set(warp_player_in_range_store,player_name,true)
|
||||
-- this is to force an update of the button
|
||||
local in_range = Store.get(warp_player_in_range_store,player_name)
|
||||
Store.set(warp_player_in_range_store,player_name,in_range)
|
||||
end)
|
||||
|
||||
--- When the button is clicked it will teleport the player
|
||||
@@ -274,7 +289,9 @@ end)
|
||||
|
||||
if config.bypass_warp_limits_permision and not Roles.player_allowed(player,config.bypass_warp_limits_permision) then
|
||||
warp_timer:set_store(player.name,0)
|
||||
Store.set(warp_player_in_range_store,player.name,false)
|
||||
-- this is to force an update of the buttons
|
||||
local in_range = Store.get(warp_player_in_range_store,player.name)
|
||||
Store.set(warp_player_in_range_store,player.name,in_range)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -453,11 +470,12 @@ function generate_warp(player,element,warp_id)
|
||||
end
|
||||
|
||||
-- draws/updates the warp area
|
||||
local element_type = warp_area.warp and warp_area.warp.type or nil
|
||||
local label_element = warp_area.warp or warp_area[zoom_to_map_name] or nil
|
||||
local element_type = label_element and label_element.type or nil
|
||||
if not editing and element_type == 'label' then
|
||||
-- update the label already present
|
||||
warp_area.warp.caption = warp_name
|
||||
warp_area.warp.tooltip = {'warp-list.last-edit',last_edit_player,format_time(last_edit_time)}
|
||||
label_element.caption = warp_name
|
||||
label_element.tooltip = {'warp-list.last-edit',last_edit_player,format_time(last_edit_time)}
|
||||
icon_area[goto_warp.name].sprite = 'item/'..warp_icon
|
||||
|
||||
elseif not editing then
|
||||
@@ -485,7 +503,7 @@ function generate_warp(player,element,warp_id)
|
||||
|
||||
local label =
|
||||
warp_area.add{
|
||||
name='warp',
|
||||
name=zoom_to_map_name,
|
||||
type='label',
|
||||
caption=warp_name,
|
||||
tooltip={'warp-list.last-edit',last_edit_player,format_time(last_edit_time)}
|
||||
@@ -639,6 +657,9 @@ end)
|
||||
generate_warp(player,data_table,warp_id)
|
||||
end
|
||||
end)
|
||||
:on_player_toggle(function(player,element,visible)
|
||||
keep_open[player.name] = visible
|
||||
end)
|
||||
|
||||
--- When the name of a warp is updated this is triggered
|
||||
Store.register(warp_name_store,function(value,warp_id)
|
||||
@@ -691,6 +712,10 @@ Store.register(warp_player_in_range_store,function(value,player_name)
|
||||
local timer = warp_timer:get_store(player_name)
|
||||
local state = not timer and value
|
||||
|
||||
if not keep_open[player.name] then
|
||||
Gui.toggle_left_frame(warp_list.name,player,value)
|
||||
end
|
||||
|
||||
if force_warps[force.name] then
|
||||
for _,warp_id in pairs(force_warps[force.name]) do
|
||||
local element = table_area['icon-'..warp_id][goto_warp.name]
|
||||
@@ -717,35 +742,33 @@ Event.on_nth_tick(math.floor(60/config.update_smothing),function()
|
||||
end
|
||||
|
||||
for _,player in pairs(game.connected_players) do
|
||||
local timer = warp_timer:get_store(player.name)
|
||||
local role = config.bypass_warp_limits_permision and Roles.player_allowed(player,config.bypass_warp_limits_permision)
|
||||
local was_in_range = Store.get(warp_player_in_range_store,player.name)
|
||||
local force = player.force
|
||||
local warps = force_warps[force.name]
|
||||
|
||||
if not timer and not role then
|
||||
local force = player.force
|
||||
local warps = force_warps[force.name]
|
||||
|
||||
if warps then
|
||||
local surface = player.surface.index
|
||||
local pos = player.position
|
||||
local px,py = pos.x,pos.y
|
||||
|
||||
for _,warp_id in pairs(warps) do
|
||||
local warp = warp_details[warp_id]
|
||||
local wpos = warp.position
|
||||
if warp.surface.index == surface then
|
||||
local dx,dy = px-wpos.x,py-wpos.y
|
||||
if not warp.editing and (dx*dx)+(dy*dy) < rs2 or (dx*dx)+(dy*dy) < r2 then
|
||||
if warps then
|
||||
local surface = player.surface.index
|
||||
local pos = player.position
|
||||
local px,py = pos.x,pos.y
|
||||
for _,warp_id in pairs(warps) do
|
||||
local warp = warp_details[warp_id]
|
||||
local wpos = warp.position
|
||||
if warp.surface.index == surface then
|
||||
local dx,dy = px-wpos.x,py-wpos.y
|
||||
if not warp.editing and (dx*dx)+(dy*dy) < rs2 or (dx*dx)+(dy*dy) < r2 then
|
||||
if not was_in_range then
|
||||
Store.set(warp_player_in_range_store,player.name,true)
|
||||
return
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
if was_in_range then
|
||||
Store.set(warp_player_in_range_store,player.name,false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end)
|
||||
@@ -757,6 +780,9 @@ Event.add(defines.events.on_player_created,function(event)
|
||||
|
||||
local allowed = config.bypass_warp_limits_permision and Roles.player_allowed(player,config.bypass_warp_limits_permision) or false
|
||||
Store.set(warp_player_in_range_store,player.name,allowed)
|
||||
if allowed then
|
||||
warp_timer:set_store(player.name,1)
|
||||
end
|
||||
|
||||
if not force_warps[force_name] then
|
||||
add_spawn(player)
|
||||
|
||||
Reference in New Issue
Block a user