Add luacheck and /shadow.

This commit is contained in:
luk3yx 2021-02-06 13:35:28 +13:00
parent 305f1c54cb
commit bdd68b0e32
12 changed files with 136 additions and 71 deletions

11
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,11 @@
on: [push, pull_request]
name: build
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: lint
uses: Roang-zero1/factorio-mod-luacheck@master
with:
luacheckrc_url: ""

14
.luacheckrc Normal file
View File

@ -0,0 +1,14 @@
max_line_length = 80
globals = {
'areas',
'chat3',
'cloaking',
'minetest',
'irc',
}
read_globals = {
string = {fields = {'split', 'trim'}},
table = {fields = {'copy'}},
}

View File

@ -1,6 +1,6 @@
# The MIT License (MIT)
Copyright © 2019 by luk3yx
Copyright © 2018-2021 by luk3yx
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,6 +1,9 @@
# Minetest cloaking mod
Allows players to cloak and uncloak, inspired by Star Trek's [cloaking device].
Allows admins to become invisible and appear as if they are not in-game at all.
Inspired by Star Trek's [cloaking device].
[cloaking device]: https://memory-alpha.fandom.com/wiki/Cloaking_device
## What is cloaking?
@ -8,11 +11,10 @@ In this instance, cloaking is a way to go invisible and become undetectable by
most mods (unless they explicitly want to detect cloaked players, so they can
still send chat messages to them).
## Why is cloaking so hacky, and where does it send the 'left the game' messages?
## Why is cloaking so hacky?
Cloaking sends no left the game messages, it leaves that up to the built-in left
the game functions. The aim of cloaking is to trick other mods into thinking the
player is not in-game, and for this it must be hacky.
The aim of cloaking is to trick other mods into thinking the player is not
in-game, and a lot of hacks are used to do this.
## Help, it crashes
@ -21,24 +23,28 @@ running around, or by a bug in cloaking itself.
## How do I use cloaking?
Cloaking adds a modding API and two chatcommands. Both of these require the
`cloaking` privilege to execute, however you can uncloak yourself without any
privileges.
Cloaking adds a modding API and some chatcommands. All of the chatcommands
require the "cloaking" privilege to execute, with the exception of `/uncloak`
when used on yourself.
- `/cloak [victim]`: Cloaks yourself, alternatively an unsuspecting `victim`.
- `/uncloak [victim]`: Uncloaks yourself, or a `victim`.
- `/cloak_chat <message>`: Sends `<message>` to all online players with the
`cloaking` privilege. You can disable cloaked chat by setting
`cloaking.enable_cloaked_chat` to `false` in `minetest.conf`.
`cloaking` privilege.
- You can disable cloaked chat by adding
`cloaking.enable_cloaked_chat = false` to minetest.conf.
- `/shadow [victim]`: Attaches you to a player. If `victim` is not specified,
this command will detach you instead.
- Requires both the "cloaking" and "teleport" privileges.
- This command can only be used while cloaked.
- You can disable this by adding `cloaking.enable_shadow = false` to
minetest.conf.
## How do I download cloaking?
You can either run
`git clone https://git.minetest.land/luk3yx/cloaking.git`, or download
a [zip](https://git.minetest.land/luk3yx/cloaking/archive/master.zip) or
[tar.gz](https://git.minetest.land/luk3yx/cloaking/archive/master.tar.gz)
file. You will need to rename the downloaded folder to `cloaking` (if it
doesn't already have that name) for it to work properly.
`git clone https://git.minetest.land/luk3yx/cloaking.git` or download this mod
from [ContentDB](https://content.minetest.net/packages/luk3yx/cloaking).
## How do I use the API?
@ -50,8 +56,7 @@ Cloaking adds the following functions:
- `cloaking.get_connected_names()`: Gets a list of cloaked and uncloaked player
names.
- `cloaking.is_cloaked(player)`: Checks if a player is cloaked.
- `cloaking.hide_player(player)`: Hides a player without cloaking them. If/when
minetest.hide_player() gets introduced, this will become an alias for that.
- `cloaking.hide_player(player)`: Hides a player without cloaking them.
- `cloaking.unhide_player(player)`: Unhides a player previously hidden with
`cloaking.hide_player()`.
- `cloaking.chat`: Cloaked chat API, this is `nil` if cloaked chat is disabled.
@ -70,7 +75,7 @@ If you have made chatcommand work with players that aren't in-game, you can add
`_allow_while_cloaked = true` to the chatcommand definition. If you explicitly
don't want your chatcommand working with cloaked players, you can add
`_disallow_while_cloaked = true` to the definition.
These modifications do not require that you add `cloaking` to `depends.txt`, as
These modifications do not require that you add cloaking as a dependency, as
when cloaking is not loaded this parameter is simply ignored.
## Backported bugfixes
@ -87,5 +92,3 @@ if it determines they are necessary for your server:
If you do not want this for whatever reason (although I do not recommend it),
you can disable these backports by adding `cloaking.backport_bugfixes = false`
to your minetest.conf.
[cloaking device]: https://memory-alpha.fandom.com/wiki/Cloaking_device

View File

@ -1,7 +1,7 @@
--
-- Minetest cloaking mod: chat3 fixes
--
-- © 2019 by luk3yx
-- Copyright © 2019 by luk3yx
--
-- Override minetest.get_connected_players() so it lists cloaked players for

View File

@ -1,7 +1,7 @@
--
-- Minetest cloaking mod: chatcommands
--
-- © 2019 by luk3yx
-- Copyright © 2018-2021 by luk3yx
--
minetest.register_privilege('cloaking',
@ -12,21 +12,22 @@ minetest.register_chatcommand("cloak", {
description = "Cloak a player so they are not visible.",
privs = {cloaking = true},
_allow_while_cloaked = true,
func = function(player, victim)
func = function(name, victim)
if not victim or victim == '' then
victim = player
victim = name
end
local p = cloaking.get_player_by_name(victim)
if not p then
return false, "Could not find a player with the name '" .. victim .. "'!"
return false, "Could not find a player with the name '" ..
victim .. "'!"
end
if cloaking.is_cloaked(victim) then
return false, victim .. " is already cloaked!"
end
minetest.log('action', player .. ' cloaks ' .. victim .. '.')
minetest.log('action', name .. ' cloaks ' .. victim .. '.')
cloaking.cloak(p)
return true, "Cloaked!"
end
@ -36,16 +37,16 @@ minetest.register_chatcommand("uncloak", {
params = "[victim]",
description = "Uncloak a player so they are visible.",
_allow_while_cloaked = true,
func = function(player, victim)
func = function(name, victim)
if not victim or victim == '' then
victim = player
elseif not minetest.get_player_privs(player).cloaking then
victim = name
elseif not minetest.get_player_privs(name).cloaking then
return false, "You don't have permission to uncloak someone else."
end
if victim == '*' then
minetest.log('action', player .. ' uncloaks everyone.')
minetest.log('action', name .. ' uncloaks everyone.')
for _, player in ipairs(cloaking.get_cloaked_players()) do
cloaking.uncloak(player)
end
@ -54,14 +55,15 @@ minetest.register_chatcommand("uncloak", {
local p = cloaking.get_player_by_name(victim)
if not p then
return false, "Could not find a player with the name '" .. victim .. "'!"
return false, "Could not find a player with the name '" ..
victim .. "'!"
end
if not cloaking.is_cloaked(victim) then
return false, victim .. " is not cloaked!"
end
minetest.log('action', player .. ' uncloaks ' .. victim .. '.')
minetest.log('action', name .. ' uncloaks ' .. victim .. '.')
cloaking.uncloak(p)
return true, "Uncloaked!"
end

View File

@ -1,7 +1,7 @@
--
-- Minetest player cloaking mod: "Cloaked chat"
--
-- © 2019 by luk3yx
-- Copyright © 2019 by luk3yx
--
cloaking.chat = {prefix = '-Cloaked-'}

View File

@ -1,7 +1,7 @@
--
-- Minetest player cloaking mod: Core functions
--
-- © 2019 by luk3yx
-- Copyright © 2018-2021 by luk3yx
--
cloaking = {}
@ -76,11 +76,12 @@ end
-- Don't allow chat or chatcommands in all commands that don't have the
-- allow_while_cloaked parameter set.
local override_chatcommands = function()
for name, def in pairs(minetest.registered_chatcommands) do
local function override_chatcommands()
local chatcommands = minetest.registered_chatcommands
for cmd_name, def in pairs(chatcommands) do
if not def.allow_while_cloaked and not def._allow_while_cloaked then
local real_cmd = def.func
minetest.chatcommands[name].func = function(name, param)
chatcommands[cmd_name].func = function(name, param)
if cloaked_players[name] then
local pass, r1, r2
if def._disallow_while_cloaked then
@ -166,10 +167,9 @@ end
-- "Hide" players
local hidden = {}
function cloaking.hide_player(player, preserve_attrs)
function cloaking.hide_player(player_or_name, preserve_attrs)
-- Sanity check
local victim
local player, victim = player_and_name(player, true)
local player, victim = player_and_name(player_or_name, true)
if not player then return end
-- Save existing attributes
@ -202,9 +202,9 @@ minetest.register_on_leaveplayer(function(player)
end)
-- "Unhide" players
function cloaking.unhide_player(player)
function cloaking.unhide_player(player_or_name)
-- Sanity check
local player, victim = player_and_name(player, true)
local player, victim = player_and_name(player_or_name, true)
if not player or hidden[victim] == nil then return end
-- Get the data
@ -236,11 +236,11 @@ function cloaking.unhide_player(player)
end
-- The cloak and uncloak functions
local use_areas = minetest.get_modpath('areas') and areas and areas.hud
function cloaking.cloak(player)
local use_areas = minetest.global_exists('areas') and areas.hud
function cloaking.cloak(player_or_name)
if not chatcommands_modified then override_chatcommands() end
local player, victim = player_and_name(player, true)
local player, victim = player_and_name(player_or_name, true)
if not player then return end
cloaking.hide_player(player, false)
@ -275,8 +275,8 @@ function cloaking.cloak(player)
minetest.log('verbose', victim .. ' was cloaked.')
end
function cloaking.uncloak(player)
local player, victim = player_and_name(player, false)
function cloaking.uncloak(player_or_name)
local player, victim = player_and_name(player_or_name, false)
if not player then return end
cloaked_players[victim] = nil
@ -296,15 +296,9 @@ function cloaking.uncloak(player)
end
-- API functions
function cloaking.auto_uncloak(player)
if type(player) ~= "string" then
player = player:get_player_name()
end
if cloaked_players[player] then
cloaking.uncloak(player)
end
end
cloaking.auto_uncloak = cloaking.uncloak
-- Don't use delayed_uncloak outside of this mod.
function cloaking.delayed_uncloak(player)
local victim = player:get_player_name()
if cloaked_players[victim] then
@ -319,8 +313,7 @@ end
-- Register cloaking.delayed_uncloak "manually" so that the profiler can't
-- hijack it, preventing it from running.
minetest.registered_on_leaveplayers[#minetest.registered_on_leaveplayers + 1]
= cloaking.delayed_uncloak
table.insert(minetest.registered_on_leaveplayers, cloaking.delayed_uncloak)
minetest.callback_origins[cloaking.delayed_uncloak] = {
mod = 'cloaking',
name = 'delayed_uncloak'

View File

@ -15,25 +15,22 @@ if minetest.get_modpath('irc') then
dofile(path .. '/irc.lua')
end
-- Attempt to support older versions of Minetest
local cloaked_chat = 'cloaking.enable_cloaked_chat'
local backport_bugfixes = 'cloaking.backport_bugfixes'
if minetest.settings and minetest.settings.get_bool then
cloaked_chat = minetest.settings:get_bool(cloaked_chat)
backport_bugfixes = minetest.settings:get_bool(backport_bugfixes)
else
cloaked_chat = minetest.setting_getbool(cloaked_chat)
backport_bugfixes = minetest.setting_getbool(backport_bugfixes)
end
-- Load cloaked chat if enabled
local cloaked_chat = minetest.settings:get_bool('cloaking.enable_cloaked_chat')
if cloaked_chat or cloaked_chat == nil then
dofile(path .. '/cloaked-chat.lua')
end
-- Load /shadow if enabled
local shadow = minetest.settings:get_bool('cloaking.enable_shadow')
if shadow or shadow == nil then
dofile(path .. '/shadow.lua')
end
-- The following code is for backporting bugfixes, if the setting was disabled
-- simply return now.
if backport_bugfixes ~= nil and not backport_bugfixes then
local backport_fixes = minetest.settings:get_bool('cloaking.backport_bugfixes')
if backport_fixes ~= nil and not backport_fixes then
return
end

View File

@ -1,7 +1,7 @@
--
-- Minetest cloaking mod: IRC fixes
--
-- © 2019 by luk3yx
-- Copyright © 2019 by luk3yx
--
local irc_sendLocal = irc.sendLocal

View File

@ -2,5 +2,8 @@
# chat channel.
cloaking.enable_cloaked_chat (Cloaked chat) bool true
# Enables /shadow.
cloaking.enable_shadow (Shadow command) bool true
# Backports certain bugfixes to older versions of Minetest.
cloaking.backport_bugfixes (Backport MT bugfixes) bool true

42
shadow.lua Normal file
View File

@ -0,0 +1,42 @@
--
-- Minetest player cloaking mod
--
-- Copyright © 2021 by luk3yx
--
minetest.register_chatcommand('shadow', {
privs = {cloaking = true, teleport = true},
description = 'Attaches you to a player. If `victim` is not specified, ' ..
'this command will detach you instead.',
params = '[victim]',
func = function(name, param)
if not cloaking.is_cloaked(name) then
return false, 'You must be cloaked to use /shadow!'
elseif name == param then
return false, 'You cannot shadow yourself!'
end
local player = cloaking.get_player_by_name(name)
if param == '' then
player:set_detach()
return true, 'You are free to move normally.'
end
local victim = cloaking.get_player_by_name(param)
if not victim then
return false, ('Invalid player %q.'):format(param)
end
player:set_attach(victim, '', {x=0, y=0, z=0}, {x=0, y=0, z=0})
return true, ('You are now shadowing %q.'):format(param)
end
})
-- Detach on uncloak
minetest.register_on_joinplayer(function(player)
if not minetest.check_player_privs(player, "cloaking", "teleport") then
return
end
local parent = player:get_attach()
if minetest.is_player(parent) and parent:is_player() then
player:set_detach()
end
end)