Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smart AFK Kick #205

Merged
merged 3 commits into from
Apr 24, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/_file_loader.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ return {
'modules.addons.discord-alerts',
'modules.addons.chat-reply',
'modules.addons.tree-decon',
'modules.addons.afk-kick',

--- Data
'modules.data.statistics',
Expand Down
9 changes: 9 additions & 0 deletions config/afk_kick.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
return {
admin_as_active = true, --- @setting admin_as_active When true admins will be treated as active regardless of afk time
trust_as_active = true, --- @setting trust_as_active When true trusted players (by playtime) will be treated as active regardless of afk time
active_role = 'Veteran', --- @setting active_role When not nil a player with this role will be treated as active regardless of afk time
afk_time = 3600*10, --- @setting afk_time The time in ticks that must pass for a player to be considered afk
kick_time = 3600*30, --- @setting kick_time The time in ticks that must pass without any active players for all players to be kicked
trust_time = 3600*60*10, --- @setting trust_time The time in ticks that a player must be online for to count as trusted
update_time = 3600*30, --- @setting update_time How often in ticks the script check for active players
Cooldude2606 marked this conversation as resolved.
Show resolved Hide resolved
}
66 changes: 66 additions & 0 deletions modules/addons/afk-kick.lua
Original file line number Diff line number Diff line change
@@ -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 give to for gui to show
Cooldude2606 marked this conversation as resolved.
Show resolved Hide resolved
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 5 minutes
Cooldude2606 marked this conversation as resolved.
Show resolved Hide resolved
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 = 'All players were kicked because everyone was afk.',
Cooldude2606 marked this conversation as resolved.
Show resolved Hide resolved
}.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)