Add cloaked chat

• Allow cloaked players to chat to other players with the "cloaking" privilege.
 • Add "/cloak_chat" and "/cloak-chat" to allow players to send chat messages into cloaked chat without being cloaked.
 • Allow "/teleport" to teleport cloaked players (provided the player running the command has the "cloaking" privilege).
 • Replace 'cloaking.fn_name = function(...)' with 'function cloaking.fn_name(...)'.
 • Update copyrights.
 • Add Star Trek reference to README.md.
This commit is contained in:
luk3yx 2019-02-10 13:49:56 +13:00
parent b795cf8e8a
commit 548c65d26f
8 changed files with 145 additions and 23 deletions

View File

@ -1,6 +1,6 @@
# Minetest cloaking mod
Allows players to cloak and uncloak.
Allows players to cloak and uncloak, inspired by Star Trek's [cloaking device].
## What is cloaking?
@ -27,6 +27,9 @@ privileges.
- `/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`.
## How do I download cloaking?
@ -44,10 +47,16 @@ Cloaking adds the following functions:
- `cloaking.cloak_player(player)`: Cloaks a player.
- `cloaking.uncloak_player(player)`: Uncloaks a player.
- `cloaking.get_cloaked_players()`: Gets a list of cloaked player names.
- `cloaking.get_connected_names()`: Gets a list of cloaked and uncloaked player
names.
- `cloaking.is_cloaked(player)`: Checks if a player is cloaked.
- `cloaking.on_chat_message(player, message)`: Returns `true` and warns `player`
if they are cloaked and trying to send a chat message, otherwise returns
`nil`.
- `cloaking.chat`: Cloaked chat API, this is `nil` if cloaked chat is disabled.
- `cloaking.chat.send(message)`: Sends a message to cloaked chat.
- `cloaking.chat.prefix`: The text (`-Cloaked-`) that is prepended to cloaked
chat messages before they are sent to players.
It also adds the following functions that ignore cloaked players and can
interact with them:
@ -60,3 +69,5 @@ 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
when cloaking is not loaded this parameter is simply ignored.
[cloaking device]: https://memory-alpha.fandom.com/wiki/Cloaking_device

View File

@ -1,14 +1,14 @@
--
-- Minetest cloaking mod: chat3 fixes
--
-- © 2018 by luk3yx
-- © 2019 by luk3yx
--
-- Override minetest.get_connected_players() so it lists cloaked players for
-- chat3.
local get_uncloaked_players = minetest.get_connected_players
minetest.get_connected_players = function()
function minetest.get_connected_players()
local d = debug.getinfo(2)
if d.func == chat3.send or d.func == minetest.chatcommands['me'].func then
return cloaking.get_connected_players()
@ -20,7 +20,7 @@ end
-- Override get_player_by_name() to allow chat3 to access cloaked players.
local get_uncloaked_player_by_name = minetest.get_player_by_name
minetest.get_player_by_name = function(player)
function minetest.get_player_by_name(player)
local d = debug.getinfo(2)
if d.func == chat3.send or d.func == minetest.chatcommands["me"].func then
return cloaking.get_player_by_name(player)

View File

@ -1,7 +1,7 @@
--
-- Minetest cloaking mod: chatcommands
--
-- © 2018 by luk3yx
-- © 2019 by luk3yx
--
minetest.register_privilege('cloaking',
@ -26,6 +26,7 @@ minetest.register_chatcommand("cloak", {
return false, victim .. " is already cloaked!"
end
minetest.log('action', player .. ' cloaks ' .. victim .. '.')
cloaking.cloak(p)
return true, "Cloaked!"
end
@ -42,14 +43,16 @@ minetest.register_chatcommand("uncloak", {
return false, "You don't have permission to uncloak someone else."
end
if victim == '*' then
minetest.log('action', player .. ' uncloaks everyone.')
for _, player in ipairs(cloaking.get_cloaked_players()) do
cloaking.uncloak(player)
end
return true, "Uncloaked everyone!"
end
p = cloaking.get_player_by_name(victim)
local p = cloaking.get_player_by_name(victim)
if not p then
return false, "Could not find a player with the name '" .. victim .. "'!"
end
@ -58,7 +61,27 @@ minetest.register_chatcommand("uncloak", {
return false, victim .. " is not cloaked!"
end
minetest.log('action', player .. ' uncloaks ' .. victim .. '.')
cloaking.uncloak(p)
return true, "Uncloaked!"
end
})
-- Allow /teleport to be used on cloaked players if you have the "cloaking"
-- privilege.
local tp = minetest.registered_chatcommands['teleport'].func
minetest.override_chatcommand('teleport', {
func = function(name, param)
if minetest.check_player_privs(name, 'cloaking') then
local g = minetest.get_player_by_name
minetest.get_player_by_name = cloaking.get_player_by_name
local err, msg = tp(name, param)
minetest.get_player_by_name = g
return err, msg
else
return tp(name, param)
end
end
})

53
cloaked-chat.lua Normal file
View File

@ -0,0 +1,53 @@
--
-- Minetest player cloaking mod: "Cloaked chat"
--
-- © 2019 by luk3yx
--
cloaking.chat = {prefix = '-Cloaked-'}
-- Send a message to all players with the "cloaking" privilege.
function cloaking.chat.send(msg)
-- Add the "cloaked chat" prefix and remove newlines.
msg = msg:gsub('[\r\n]', ' ')
-- Log the chat message
minetest.log('action', 'CLOAKED CHAT: ' .. msg)
-- Send the message to everyone with the "cloaking" priv.
msg = cloaking.chat.prefix .. ' ' .. msg
for _, name in ipairs(cloaking.get_connected_names()) do
if minetest.check_player_privs(name, 'cloaking') then
minetest.chat_send_player(name, msg)
end
end
end
-- Create a '/cloak_chat' command
minetest.register_chatcommand('cloak_chat', {
params = '<message>',
description = 'Send a chat message to cloaked players.',
privs = {cloaking = true},
_allow_while_cloaked = true,
func = function(name, param)
cloaking.chat.send('<' .. name .. '> ' .. param)
end
})
minetest.registered_chatcommands['cloak-chat'] =
minetest.registered_chatcommands['cloak_chat']
-- Override cloaking.on_chat_message
function cloaking.on_chat_message(name, message)
if message:sub(1, 1) ~= "/" and cloaking.is_cloaked(name) then
if minetest.check_player_privs(name, 'cloaking') then
cloaking.chat.send('<' .. name .. '> ' .. message)
else
minetest.chat_send_player(name, "You cannot use chat while" ..
" cloaked. Please use /uncloak if you want to use chat.")
end
return true
end
end
minetest.registered_on_chat_messages[1] = cloaking.on_chat_message

View File

@ -1,7 +1,7 @@
--
-- Minetest player cloaking mod: Core functions
--
-- © 2018 by luk3yx
-- © 2019 by luk3yx
--
cloaking = {}
@ -16,7 +16,7 @@ local cloaked_players = {}
local chatcommands_modified = false
-- Override built-in functions
minetest.get_player_by_name = function(player)
function minetest.get_player_by_name(player)
if cloaked_players[player] then
return nil
else
@ -24,7 +24,7 @@ minetest.get_player_by_name = function(player)
end
end
minetest.get_objects_inside_radius = function(pos, radius)
function minetest.get_objects_inside_radius(pos, radius)
local objs = {}
for _, obj in ipairs(cloaking.get_objects_inside_radius(pos, radius)) do
if not cloaked_players[obj:get_player_name()] then
@ -34,7 +34,7 @@ minetest.get_objects_inside_radius = function(pos, radius)
return objs
end
minetest.get_server_status = function()
function minetest.get_server_status()
local status = cloaking.get_server_status()
local motd = status:sub(status:find('}', 1, true) + 0)
status = status:sub(1, status:find('{', 1, true))
@ -98,7 +98,8 @@ local override_chatcommands = function()
end
end
cloaking.on_chat_message = function(name, message)
-- Handle chat messages
function cloaking.on_chat_message(name, message)
if message:sub(1, 1) ~= "/" and cloaked_players[name] then
minetest.chat_send_player(name, "You cannot use chat while cloaked." ..
" Please use /uncloak if you want to use chat.")
@ -106,7 +107,11 @@ cloaking.on_chat_message = function(name, message)
end
end
minetest.register_on_chat_message(cloaking.on_chat_message)
table.insert(minetest.registered_on_chat_messages, 1, cloaking.on_chat_message)
minetest.callback_origins[cloaking.on_chat_message] = {
mod = 'cloaking',
name = 'on_chat_message'
}
-- Disallow some built-in commands.
for _, cmd in ipairs({'me', 'msg'}) do
@ -118,7 +123,8 @@ for _, cmd in ipairs({'me', 'msg'}) do
end
-- The cloak and uncloak functions
cloaking.cloak = function(player)
local use_areas = minetest.get_modpath('areas')
function cloaking.cloak(player)
if not chatcommands_modified then override_chatcommands() end
if type(player) == "string" then
player = cloaking.get_player_by_name(player)
@ -133,7 +139,7 @@ cloaking.cloak = function(player)
player:set_nametag_attributes({text = " "})
local t = nil
if areas and areas.hud and areas.hud[victim] then
if use_areas and areas.hud[victim] then
t = areas.hud[victim]
end
@ -150,9 +156,11 @@ cloaking.cloak = function(player)
player:hud_change(areas.hud[victim].areasId, "text", "Cloaked")
areas.hud[victim].oldAreas = ""
end
minetest.log('verbose', victim .. ' was cloaked.')
end
cloaking.uncloak = function(player)
function cloaking.uncloak(player)
if type(player) == "string" then
player = cloaking.get_player_by_name(player)
end
@ -176,10 +184,12 @@ cloaking.uncloak = function(player)
for _, f in ipairs(minetest.registered_on_joinplayers) do
f(player)
end
minetest.log('verbose', victim .. ' was uncloaked.')
end
-- API functions
cloaking.auto_uncloak = function(player)
function cloaking.auto_uncloak(player)
if type(player) ~= "string" then
player = player:get_player_name()
end
@ -188,7 +198,7 @@ cloaking.auto_uncloak = function(player)
end
end
cloaking.delayed_uncloak = function(player)
function cloaking.delayed_uncloak(player)
local victim = player:get_player_name()
if cloaked_players[victim] then
minetest.after(0.5, function()
@ -211,7 +221,7 @@ minetest.callback_origins[cloaking.delayed_uncloak] = {
-- The cloaking mod is so good it fools the built-in get_connected_players, so
-- overlay that with one that adds cloaked players in.
cloaking.get_connected_players = function()
function cloaking.get_connected_players()
local a = minetest.get_connected_players()
for player, cloaked in pairs(cloaked_players) do
if cloaked then
@ -221,7 +231,7 @@ cloaking.get_connected_players = function()
return a
end
cloaking.get_cloaked_players = function()
function cloaking.get_cloaked_players()
local players = {}
for player, cloaked in pairs(cloaked_players) do
if cloaked then
@ -231,7 +241,16 @@ cloaking.get_cloaked_players = function()
return players
end
cloaking.is_cloaked = function(player)
-- Allow mods to get a list of cloaked and uncloaked player names.
function cloaking.get_connected_names()
local a = cloaking.get_cloaked_players()
for _, player in ipairs(minetest.get_connected_players()) do
table.insert(a, player:get_player_name())
end
return a
end
function cloaking.is_cloaked(player)
if type(player) ~= "string" then player = player:get_player_name() end
return cloaked_players[player] and true or false
end

View File

@ -1,7 +1,7 @@
--
-- Minetest player cloaking mod
--
-- © 2018 by luk3yx
-- © 2019 by luk3yx
--
local path = minetest.get_modpath('cloaking')
dofile(path .. '/core.lua')
@ -14,3 +14,16 @@ end
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'
if minetest.settings and minetest.settings.get_bool then
cloaked_chat = minetest.settings:get_bool(cloaked_chat)
else
cloaked_chat = minetest.setting_getbool(cloaked_chat)
end
-- Load cloaked chat if enabled
if cloaked_chat or cloaked_chat == nil then
dofile(path .. '/cloaked-chat.lua')
end

View File

@ -1,12 +1,12 @@
--
-- Minetest cloaking mod: IRC fixes
--
-- © 2018 by luk3yx
-- © 2019 by luk3yx
--
local irc_sendLocal = irc.sendLocal
irc.sendLocal = function(msg)
function irc.sendLocal(msg)
for _, player in ipairs(cloaking.get_cloaked_players()) do
minetest.chat_send_player(player, msg)
end

3
settingtypes.txt Normal file
View File

@ -0,0 +1,3 @@
# Cloaked chat - Allow cloaked players with the "cloaking" priv to use a special
# chat channel.
cloaking.enable_cloaked_chat (Cloaked chat) bool true