mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 11:35:22 +09:00
Merge branch 'dev' into feature/admin-markers
This commit is contained in:
66
modules/addons/afk-kick.lua
Normal file
66
modules/addons/afk-kick.lua
Normal file
@@ -0,0 +1,66 @@
|
||||
--- Kicks players when all players on the server are afk
|
||||
-- @addon afk-kick
|
||||
|
||||
local Event = require 'utils.event' --- @dep utils.event
|
||||
local Global = require 'utils.global' --- @dep utils.global
|
||||
local config = require 'config.afk_kick' --- @dep config.afk_kick
|
||||
local Async = require 'expcore.async' --- @dep expcore.async
|
||||
|
||||
--- Optional roles require
|
||||
local Roles
|
||||
if config.active_role then
|
||||
Roles = require 'expcore.roles'
|
||||
end
|
||||
|
||||
--- Globals
|
||||
local primitives = { last_active = 0 }
|
||||
Global.register(primitives, function(tbl)
|
||||
primitives = tbl
|
||||
end)
|
||||
|
||||
--- Kicks an afk player, used to add a delay so the gui has time to appear
|
||||
local kick_player =
|
||||
Async.register(function(player)
|
||||
if game.tick - primitives.last_active < config.kick_time then return end -- Safety Catch
|
||||
game.kick_player(player, 'AFK while no active players on the server')
|
||||
end)
|
||||
|
||||
--- Check for an active player every update_time number of ticks
|
||||
Event.on_nth_tick(config.update_time, function()
|
||||
-- Check for active players
|
||||
for _, player in ipairs(game.connected_players) do
|
||||
if player.afk_time < config.afk_time
|
||||
or config.admin_as_active and config.player.admin
|
||||
or config.trust_as_active and player.online_time > config.trust_time
|
||||
or config.active_role and Roles.player_has_role(player, config.active_role) then
|
||||
-- Active player was found
|
||||
primitives.last_active = game.tick
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- No active player was found, check if players should be kicked
|
||||
if game.tick - primitives.last_active < config.kick_time then return end
|
||||
|
||||
-- Kick time exceeded, kick all players
|
||||
for _, player in ipairs(game.connected_players) do
|
||||
-- Add a frame to say why the player was kicked
|
||||
local res = player.display_resolution
|
||||
local uis = player.display_scale
|
||||
player.gui.screen.add{
|
||||
type = 'frame',
|
||||
name = 'afk-kick',
|
||||
caption = {'afk-kick.message'},
|
||||
}.location = { x=res.width*(0.5 - 0.11*uis), y=res.height*(0.5 - 0.14*uis) }
|
||||
|
||||
-- Kick the player, some delay needed because network delay
|
||||
Async.wait(10, kick_player, player)
|
||||
end
|
||||
end)
|
||||
|
||||
--- Remove the screen gui if it is present
|
||||
Event.add(defines.events.on_player_joined_game, function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
local frame = player.gui.screen["afk-kick"]
|
||||
if frame and frame.valid then frame.destroy() end
|
||||
end)
|
||||
@@ -59,7 +59,7 @@ local function emit_event(args)
|
||||
}
|
||||
|
||||
local new_value, inline = value:gsub('<inline>', '', 1)
|
||||
if inline then
|
||||
if inline > 0 then
|
||||
field.value = new_value
|
||||
field.inline = true
|
||||
end
|
||||
@@ -87,6 +87,7 @@ if config.player_reports then
|
||||
color=Colors.yellow,
|
||||
['Player']='<inline>'..player_name,
|
||||
['By']='<inline>'..by_player_name,
|
||||
['Report Count']='<inline>'..Reports.count_reports(player_name),
|
||||
['Reason']=event.reason
|
||||
}
|
||||
end)
|
||||
@@ -99,7 +100,7 @@ if config.player_reports then
|
||||
color=Colors.green,
|
||||
['Player']='<inline>'..player_name,
|
||||
['By']='<inline>'..event.removed_by_name,
|
||||
['Amount']='<inline>'..event.batch_count
|
||||
['Report Count']='<inline>'..event.batch_count
|
||||
}
|
||||
end)
|
||||
end
|
||||
@@ -109,12 +110,14 @@ if config.player_warnings then
|
||||
local Warnings = require 'modules.control.warnings' --- @dep modules.control.warnings
|
||||
Event.add(Warnings.events.on_warning_added, function(event)
|
||||
local player_name, by_player_name = get_player_name(event)
|
||||
local player = game.get_player(player_name)
|
||||
emit_event{
|
||||
title='Warning',
|
||||
description='A player has been given a warning',
|
||||
color=Colors.yellow,
|
||||
['Player']='<inline>'..player_name,
|
||||
['By']='<inline>'..by_player_name,
|
||||
['Warning Count']='<inline>'..Warnings.count_warnings(player),
|
||||
['Reason']=event.reason
|
||||
}
|
||||
end)
|
||||
@@ -127,7 +130,7 @@ if config.player_warnings then
|
||||
color=Colors.green,
|
||||
['Player']='<inline>'..player_name,
|
||||
['By']='<inline>'..event.removed_by_name,
|
||||
['Amount']='<inline>'..event.batch_count
|
||||
['Warning Count']='<inline>'..event.batch_count
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
25
modules/addons/report-jail.lua
Normal file
25
modules/addons/report-jail.lua
Normal file
@@ -0,0 +1,25 @@
|
||||
--- When a player is reported, the player is automatically jailed if the combined playtime of the reporters exceeds the reported player
|
||||
-- @addon report-jail
|
||||
|
||||
local Event = require 'utils.event' ---@dep utils.event
|
||||
local Jail = require 'modules.control.jail' ---@dep modules.control.jail
|
||||
local Reports = require 'modules.control.reports' --- @dep modules.control.reports
|
||||
local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common
|
||||
|
||||
--- Returns the playtime of the reporter. Used when calculating the total playtime of all reporters
|
||||
local function reporter_playtime(_, by_player_name, _)
|
||||
local player = game.get_player(by_player_name)
|
||||
if player == nil then return 0 end
|
||||
return player.online_time
|
||||
end
|
||||
|
||||
--- Tests the combined playtime of all reporters against the reported player
|
||||
Event.add(Reports.events.on_player_reported, function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
local total_playtime = Reports.count_reports(player, reporter_playtime)
|
||||
if total_playtime < player.online_time*1.5 then return end
|
||||
-- Combined playtime is greater than 150% of the reported's playtime
|
||||
local player_name_color = format_chat_player_name(player)
|
||||
Jail.jail_player(player, '<reports>', 'Reported by too many players, please wait for a moderator.')
|
||||
game.print{'report-jail.jail', player_name_color}
|
||||
end)
|
||||
@@ -9,6 +9,15 @@ local Reports = require 'modules.control.reports' --- @dep modules.control.repor
|
||||
local format_chat_player_name = _C.format_chat_player_name--- @dep expcore.common
|
||||
require 'config.expcore.command_general_parse'
|
||||
|
||||
--- Print a message to all players who match the value of admin
|
||||
local function print_to_players(admin, message)
|
||||
for _, player in ipairs(game.connected_players) do
|
||||
if player.admin == admin then
|
||||
player.print(message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Reports a player and notifies moderators
|
||||
-- @command report
|
||||
-- @tparam LuaPlayer player the player to report, some players are immune
|
||||
@@ -19,6 +28,8 @@ Commands.new_command('report', 'Reports a player and notifies moderators')
|
||||
if not input then return end
|
||||
if Roles.player_has_flag(input, 'report-immune') then
|
||||
return reject{'expcom-report.player-immune'}
|
||||
elseif player == input then
|
||||
return reject{'expcom-report.self-report'}
|
||||
else
|
||||
return input
|
||||
end
|
||||
@@ -30,8 +41,8 @@ end)
|
||||
local action_player_name_color = format_chat_player_name(action_player)
|
||||
local by_player_name_color = format_chat_player_name(player)
|
||||
if Reports.report_player(action_player, player.name, reason) then
|
||||
game.print{'expcom-report.non-admin', action_player_name_color, reason}
|
||||
Roles.print_to_roles_higher('Trainee', {'expcom-report.admin', action_player_name_color, by_player_name_color, reason})
|
||||
print_to_players(false, {'expcom-report.non-admin', action_player_name_color, reason})
|
||||
print_to_players(true, {'expcom-report.admin', action_player_name_color, by_player_name_color, reason})
|
||||
else
|
||||
return Commands.error{'expcom-report.already-reported'}
|
||||
end
|
||||
|
||||
167
modules/commands/search.lua
Normal file
167
modules/commands/search.lua
Normal file
@@ -0,0 +1,167 @@
|
||||
--[[-- Commands Module - Inventory Search
|
||||
- Adds commands that will search all players inventories for an item
|
||||
@commands InventorySearch
|
||||
]]
|
||||
|
||||
local Commands = require 'expcore.commands' --- @dep expcore.commands
|
||||
local format_number = require('util').format_number --- @dep util
|
||||
local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common
|
||||
local format_time = _C.format_time
|
||||
require 'config.expcore.command_general_parse'
|
||||
|
||||
--- Input parse for items by name
|
||||
local function item_parse(input, _, reject)
|
||||
if input == nil then return end
|
||||
local lower_input = input:lower():gsub(' ', '-')
|
||||
|
||||
-- Simple Case - internal name is given
|
||||
local item = game.item_prototypes[lower_input]
|
||||
if item then return item end
|
||||
|
||||
-- Second Case - rich text is given
|
||||
local item_name = input:match('%[item=([0-9a-z-]+)%]')
|
||||
item = game.item_prototypes[item_name]
|
||||
if item then return item end
|
||||
|
||||
-- No item found, we do not attempt to search all prototypes as this will be expensive
|
||||
return reject{'expcom-inv-search.reject-item', lower_input}
|
||||
end
|
||||
|
||||
--- Search all players for this item
|
||||
local function search_players(players, item)
|
||||
local head = 1
|
||||
local found = {}
|
||||
|
||||
-- Check the item count of all players
|
||||
for _, player in pairs(players) do
|
||||
local item_count = player.get_item_count(item.name)
|
||||
if item_count > 0 then
|
||||
-- Add the player to the array as they have the item
|
||||
found[head] = { player=player, count=item_count, online_time=player.online_time }
|
||||
head = head + 1
|
||||
end
|
||||
end
|
||||
|
||||
return found
|
||||
end
|
||||
|
||||
--- Custom sort function which only retains 5 greatest values
|
||||
local function sort_players(players, func)
|
||||
local sorted = {}
|
||||
local values = {}
|
||||
local threshold = nil
|
||||
|
||||
-- Loop over all provided players
|
||||
for index, player in ipairs(players) do
|
||||
local value = func(player)
|
||||
-- Check if the item will make the top 5 elements
|
||||
if value > threshold or index <= 5 then
|
||||
local inserted = false
|
||||
values[player] = value
|
||||
-- Find where in the top 5 to insert the element
|
||||
for next_index, next_player in ipairs(sorted) do
|
||||
if value > values[next_player] then
|
||||
table.insert(sorted, next_index, player)
|
||||
inserted = true
|
||||
break
|
||||
end
|
||||
end
|
||||
-- Insert the element, this can only be called when index <= 5
|
||||
if not inserted then
|
||||
sorted[#sorted+1] = player
|
||||
end
|
||||
-- Update the threshold
|
||||
if sorted[6] then
|
||||
threshold = values[sorted[5]]
|
||||
values[sorted[6]] = nil
|
||||
sorted[6] = nil
|
||||
else
|
||||
threshold = values[sorted[#sorted]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return sorted
|
||||
end
|
||||
|
||||
--- Display to the player the top players which were found
|
||||
local function display_players(player, players, item)
|
||||
player.print{'expcom-inv-search.results-heading', item.name}
|
||||
for index, data in ipairs(players) do
|
||||
local player_name_color = format_chat_player_name(data.player)
|
||||
local amount = format_number(data.count)
|
||||
local time = format_time(data.online_time)
|
||||
player.print{'expcom-inv-search.results-item', index, player_name_color, amount, time}
|
||||
end
|
||||
end
|
||||
|
||||
--- Return the amount of an item a player has
|
||||
local function amount_sort(data)
|
||||
return data.count
|
||||
end
|
||||
|
||||
--- Get a list of players sorted by the quantity of an item in their inventory
|
||||
-- @command search-amount
|
||||
-- @tparam LuaItemPrototype item The item to search for in players inventories
|
||||
Commands.new_command('search-amount', 'Display players sorted by the quantity of an item held')
|
||||
:add_alias('ia')
|
||||
:add_param('item', false, item_parse)
|
||||
:enable_auto_concat()
|
||||
:register(function(player, item)
|
||||
local players = search_players(game.players, item)
|
||||
if #players == 0 then return {'expcom-inv-search.results-none', item.name} end
|
||||
local top_players = sort_players(players, amount_sort)
|
||||
display_players(player, top_players, item)
|
||||
end)
|
||||
|
||||
--- Return the index of the player, higher means they joined more recently
|
||||
local function recent_sort(data)
|
||||
return data.player.index
|
||||
end
|
||||
|
||||
--- Get a list of players who have the given item, sorted by how recently they joined
|
||||
-- @command search-recent
|
||||
-- @tparam LuaItemPrototype item The item to search for in players inventories
|
||||
Commands.new_command('search-recent', 'Display players who hold an item sorted by join time')
|
||||
:add_alias('ir')
|
||||
:add_param('item', false, item_parse)
|
||||
:enable_auto_concat()
|
||||
:register(function(player, item)
|
||||
local players = search_players(game.players, item)
|
||||
if #players == 0 then return {'expcom-inv-search.results-none', item.name} end
|
||||
local top_players = sort_players(players, recent_sort)
|
||||
display_players(player, top_players, item)
|
||||
end)
|
||||
|
||||
--- Return the the amount of an item a player has divided by their playtime
|
||||
local function combined_sort(data)
|
||||
return data.count/data.online_time
|
||||
end
|
||||
|
||||
--- Get a list of players sorted by quantity held and play time
|
||||
-- @command search
|
||||
-- @tparam LuaItemPrototype item The item to search for in players inventories
|
||||
Commands.new_command('search', 'Display players sorted by the quantity of an item held and playtime')
|
||||
:add_alias('i')
|
||||
:add_param('item', false, item_parse)
|
||||
:enable_auto_concat()
|
||||
:register(function(player, item)
|
||||
local players = search_players(game.players, item)
|
||||
if #players == 0 then return {'expcom-inv-search.results-none', item.name} end
|
||||
local top_players = sort_players(players, combined_sort)
|
||||
display_players(player, top_players, item)
|
||||
end)
|
||||
|
||||
--- Get a list of online players sorted by quantity held and play time
|
||||
-- @command search-online
|
||||
-- @tparam LuaItemPrototype item The item to search for in players inventories
|
||||
Commands.new_command('search-online', 'Display online players sorted by the quantity of an item held and playtime')
|
||||
:add_alias('io')
|
||||
:add_param('item', false, item_parse)
|
||||
:enable_auto_concat()
|
||||
:register(function(player, item)
|
||||
local players = search_players(game.connected_players, item)
|
||||
if #players == 0 then return {'expcom-inv-search.results-none', item.name} end
|
||||
local top_players = sort_players(players, combined_sort)
|
||||
display_players(player, top_players, item)
|
||||
end)
|
||||
@@ -132,7 +132,7 @@ function Reports.report_player(player, by_player_name, reason)
|
||||
if not player then return end
|
||||
local player_name = player.name
|
||||
|
||||
reason = reason or 'Non given.'
|
||||
if reason == nil or not reason:find("/S") then reason = 'No reason given' end
|
||||
|
||||
local reports = user_reports[player_name]
|
||||
if not reports then
|
||||
|
||||
@@ -72,9 +72,10 @@ Gui.element{
|
||||
}
|
||||
:style(Gui.sprite_style(30, -1, { left_margin = -2, right_margin = -1 }))
|
||||
:on_click(function(player, element)
|
||||
local reason = element.parent.entry.text or 'Non Given'
|
||||
local reason = element.parent.entry.text
|
||||
local action_name = SelectedAction:get(player)
|
||||
local reason_callback = config.buttons[action_name].reason_callback
|
||||
if reason == nil or not reason:find("/S") then reason = 'no reason given' end
|
||||
reason_callback(player, reason)
|
||||
SelectedPlayer:remove(player)
|
||||
SelectedAction:remove(player)
|
||||
|
||||
Reference in New Issue
Block a user