updated wisp and tchat

wsc-master-rebase
flyc0r 2020-10-04 04:32:19 +02:00 committed by Schmappie Eldress
parent 2551ddbf1d
commit 51408076dc
4 changed files with 163 additions and 67 deletions

View File

@ -11,9 +11,9 @@ load_mod_aflight = false
load_mod_geass = false
load_mod_autowarp = true
load_mod_panicm = true
load_mod_wisp = true
load_mod_tchat = true
load_mod_esp = true
load_mod_antigone = false
load_mod_dte = true
load_mod_wisp = true
load_mod_flightaura = false

View File

@ -1,7 +1,7 @@
---
-- coras teamchat .. indev v0.5
--
-- adds a team chat for you and a couple friends, also prevents accidental sending of coordinates
-- adds a team chat for you and a couple friends, also prevents accidental sending of coordinates
-- to say something in teamchat either activate teammode in the dragonfire menu or use .t message
--
-- supports the Wisp encrypted whisper mod
@ -86,9 +86,9 @@ init_settings({
tchat_view_team_list = true,
tchat_view_player_list = true,
tchat_team_mode = false,
tchat_colorize_team = false,
tchat_prefix_message = "TCHAT",
tchat_prefix_receive = "From",
tchat_prefix_self = "To Yourself",
@ -96,7 +96,7 @@ init_settings({
tchat_hide_sent = true,
tchat_blacklist = "",
tchat_chat_length = 6,
tchat_chat_width = 80
})
@ -146,8 +146,8 @@ tchat.team = minetest.parse_json(storage:get_string("tchat_team"))
local message_confirmed_safe = false
-- coordinate matching
local pattern = "[-]?%d[,.%d]*"
local space = "%s+"
local pattern = "[-]?%d[.%d]*"
local space = "[,%s]+"
local pattern_three = pattern .. space .. pattern .. space .. pattern
local pattern_two = pattern .. space .. pattern
@ -209,7 +209,7 @@ end
local function display_chat()
return minetest.localplayer:hud_add({
hud_elem_type = 'text',
name = "üüTeamüchat",
name = "Teamchat",
text = "Team Chat\n\n" .. chat_str,
number = 0xEEFFEE,
direction = 0,
@ -233,7 +233,7 @@ local function display_player_list()
})
end
-- should prob have all team members with online ones colored
-- should prob have all team members with online ones colored
local function display_team_list()
return minetest.localplayer:hud_add({
hud_elem_type = 'text',
@ -284,7 +284,7 @@ local function update_chat_str()
chat_str = table.concat(limit_list(string.split(chat_str, "\n"), chat_length - 1), "\n")
-- update chat (do it here so external mods can add to the chat)
auto_update(chat_idx, "Teamüü Chat\n\n" .. chat_str)
auto_update(chat_idx, "Team Chat\n\n" .. chat_str)
end
local function team_add_self()
@ -313,11 +313,11 @@ local function dm(player, message)
end
-- send
function tchat.send(message)
if tchat.contains_coords(message) or in_list(blacklist, minetest.localplayer:get_name()) then
function tchat.send(message, force_coords)
if (tchat.contains_coords(message) and not force_coords) or in_list(blacklist, minetest.localplayer:get_name()) then
return
end
local me = minetest.localplayer:get_name()
if not in_list(tchat.team, minetest.localplayer:get_name()) then
@ -325,7 +325,7 @@ function tchat.send(message)
end
update_team_online()
tchat.chat_append("L " .. me .. ": " .. message)
for k, p in ipairs(tchat.team_online) do
@ -336,11 +336,13 @@ function tchat.send(message)
return true
end
function tchat.send_conditional(message, inverse)
if tchat.contains_coords(message) then
function tchat.send_conditional(message, inverse, force_coords)
if tchat.contains_coords(message) and not force_coords then
return
end
team_mode = minetest.settings:get_bool("tchat_team_mode")
local tm = team_mode
if inverse then
tm = not team_mode
@ -392,7 +394,7 @@ end
function tchat.chat_append(message)
tchat.chat[#tchat.chat + 1] = message
autoclear_chat()
minetest.log("action", "[tchat] " .. minetest.localplayer:get_name() .. "@" .. server_id .. " " .. message)
update_chat_str()
@ -467,7 +469,7 @@ local function clean_message(message)
message = message:gsub(message_prefix, "")
message = message:gsub("^" .. message_receive, "")
message = message:gsub("^" .. message_receive_self, minetest.localplayer:get_name())
message = message:gsub(": ", ": ")
message = message:match("^%s*(.-)%s*$")
@ -486,15 +488,15 @@ table.insert(minetest.registered_on_receiving_chat_message, 1, function(message)
end
local player = message:match(message_receive .. " (.+): " .. message_prefix)
local from_self = message:sub(1, message_receive_self:len()) == message_receive_self
local received = message:sub(1, message_receive:len()) == message_receive
local sent = message:sub(1, message_to:len()) == message_to
if sent and not from_self then
return true
end
if not from_self and not in_list(tchat.team_online, player) then
return
end
@ -524,7 +526,7 @@ minetest.register_globalstep(function()
-- update HUD
auto_update(player_list_idx, "Players\n\n" .. table.concat(tchat.players, "\n"))
auto_update(team_list_idx, "Team\n\n" .. get_team_str())
player_list_epoch = os.time()
end
@ -544,9 +546,20 @@ minetest.register_chatcommand("t", {
params = "<message>",
description = "Send a message to your team chat, or regular chat if team mode is on.",
func = function(message)
if tchat.contains_coords(message) then
minetest.display_chat_message("Message contained coordinates, be careful.")
return
end
tchat.send_conditional(message, true)
end
})
minetest.register_chatcommand("tcoords", {
params = "<message>",
description = "Send a message containing coordinates to teamchat.",
func = function(message)
tchat.send(message, true)
end
})
minetest.register_chatcommand("tlist", {
description = "List your team.",
func = function(param)

View File

@ -1,10 +1,9 @@
local env = minetest.request_insecure_environment()
env.os.execute("echo test > test.txt")
local openssl = env.require("openssl")
-- Wisp by system32
-- CC0/Unlicense 2020
-- version 0.8
-- version 1.0
--
-- a clientmod for minetest that lets people send 1 on 1 encrypted messages
-- also has a public interface for other mods
@ -17,7 +16,9 @@ local openssl = env.require("openssl")
--
-- Methods
-- send(player, message) - send a message
-- register_on_receive(function(message)) - register a callback
-- register_on_receive(function(message)) - register a receiving callback (includes To: messages), if it returns true the message will not be shown to the player
-- register_on_receive_split(function(player, message)) - register_on_receive but player and message are pre split
-- register_on_send_split(function(player, message)) - register a sending callback, if it returns true the message will not be sent
--
-- Properties
-- players - list of online players (updated every 2 seconds , when someone may have left, and when a message is queued)
@ -27,13 +28,17 @@ local openssl = env.require("openssl")
-- PATCHING MINETEST
--
-- in src/script/lua_api/l_util.cpp add the following to ModApiUtil:InitializeClient()
-- API_FCT(request_insecure_environment);
-- in src/script/lua_api/l_util.cpp add the following to ModApiUtil:InitializeClient() below API_FCT(decompress);
--[[
API_FCT(request_insecure_environment);
--]]
--
-- in src/script/cpp_api/s_security.cpp add the following below int thread = getThread(L); in ScriptApiSecurity:initializeSecurityClient()
-- // Backup globals to the registry
-- lua_getglobal(L, "_G");
-- lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
--[[
// Backup globals to the registry
lua_getglobal(L, "_G");
lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
--]]
--
-- Recompile Minetest (just using make -j$(nproc) is fine)
@ -90,7 +95,9 @@ init_settings({
wisp_curve = "prime256v1",
wisp_cipher = "aes256",
wisp_digest = "sha256",
wisp_whisper = "msg"
wisp_iv_size = 8,
wisp_whisper = "msg",
wisp_hide_sent = true
})
-- players must agree on these
@ -98,7 +105,10 @@ local prefix = minetest.settings:get("wisp_prefix")
local curve = minetest.settings:get("wisp_curve")
local cipher = minetest.settings:get("wisp_cipher")
local digest = minetest.settings:get("wisp_digest")
local iv_size = minetest.settings:get("wisp_iv_size")
local whisper = minetest.settings:get("wisp_whisper")
local hide_sent = minetest.settings:get_bool("wisp_hide_sent")
local my_key = openssl.pkey.new("ec", curve)
local my_ec = my_key:parse().ec
@ -134,6 +144,31 @@ local function in_list(list, value)
return false
end
local function append(list, item)
list[#list + 1] = item
end
local function popfirst(t)
local out = {}
for i = 2, #t do
out[#out + 1] = t[i]
end
return out
end
local function unpack(t, i)
if type(t) ~= "table" then
return t
end
i = i or 1
if t[i] ~= nil then
return t[i], unpack(t, i + 1)
end
end
-- key trading
@ -166,18 +201,51 @@ end
-- encryption
local function run_callbacks(list, params)
for k, v in ipairs(list) do
if v(unpack(params)) then
return true
end
end
end
-- encrypt and send
local function message_send(player, message)
local function message_send(player, message, hide_to, force_send)
local me = minetest.localplayer:get_name()
if run_callbacks(wisp.send_split_callbacks, {player, message}) then
return
end
-- for displaying the To: stuff
if not hide_to then
local target = player
if target == me then
target = "Yourself"
end
local display_message = "To " .. target .. ": " .. message
local callback_value = run_callbacks(wisp.receive_callbacks, display_message)
callback_value = callback_value or run_callbacks(wisp.receive_split_callbacks, {player, message})
if not callback_value then
minetest.display_chat_message(display_message)
end
end
-- actual encryption
local friend = friends[player]
if friend == nil then
return
end
local nonce = openssl.random(8, true)
local message = openssl.cipher.encrypt(cipher, message, friend.key, nonce)
local final_message = b64_encode(nonce) .. " " .. b64_encode(message)
local nonce = openssl.random(iv_size, true)
local enc_message = openssl.cipher.encrypt(cipher, message, friend.key, nonce)
local final_message = b64_encode(nonce) .. " " .. b64_encode(enc_message)
dm(player, prefix .. "E " .. final_message)
if player ~= me or force_send then
dm(player, prefix .. "E " .. final_message)
end
end
-- decrypt and show
@ -188,17 +256,16 @@ local function message_receive(player, message)
end
local nonce = b64_decode(qsplit(message)[1])
local message = b64_decode(qsplit(message)[2])
local final_message = openssl.cipher.decrypt(cipher, message, friend.key, nonce)
final_message = "From " .. player .. ": " .. final_message
local enc_message = b64_decode(qsplit(message)[2])
local dec_message = openssl.cipher.decrypt(cipher, enc_message, friend.key, nonce)
final_message = "From " .. player .. ": " .. dec_message
for k, v in ipairs(wisp.callbacks) do
if v(final_message) then
return
end
local callback_value = run_callbacks(wisp.receive_callbacks, final_message)
callback_value = callback_value or run_callbacks(wisp.receive_split_callbacks, {player, dec_message})
if not callback_value then
minetest.display_chat_message(final_message)
end
minetest.display_chat_message(final_message)
end
@ -232,21 +299,17 @@ local function encrypted(message)
end
end
local function popfirst(t)
local out = {}
for i = 2, #t do
out[#out + 1] = t[i]
end
return out
-- check if a message is 'Message sent.' or similar
local function message_sent(message)
return message == "Message sent."
end
wisp = {}
wisp.callbacks = {}
wisp.receive_callbacks = {}
wisp.receive_split_callbacks = {}
wisp.send_split_callbacks = {}
wisp.players = {}
@ -256,8 +319,13 @@ local player_check_epoch = 0
-- messages are enqueued and dequeued once they can be sent
local queue = {}
local function enqueue(player, message)
queue[#queue + 1] = {player = player, message = message}
local function enqueue(player, message, hide_to, force_send)
append(queue, {
player = player,
message = message,
hide_to = hide_to,
force_send = force_send
})
wisp.players = minetest.get_player_names()
end
@ -266,7 +334,7 @@ local function dequeue()
local out = queue[1]
for k, v in ipairs(queue) do
if k ~= 1 then
new_queue[#new_queue + 1] = v
append(new_queue, v)
end
end
queue = new_queue
@ -278,15 +346,23 @@ local function peek()
end
function wisp.send(player, message)
if friends[player] == nil then
function wisp.send(player, message, hide_to, force_send)
if (player ~= minetest.localplayer:get_name() or force_send) and friends[player] == nil then
establish(player)
end
enqueue(player, message)
enqueue(player, message, hide_to, force_send)
end
function wisp.register_on_receive(func)
wisp.callbacks[#wisp.callbacks + 1] = func
append(wisp.receive_callbacks, func)
end
function wisp.register_on_receive_split(func)
append(wisp.receive_split_callbacks, func)
end
function wisp.register_on_send_split(func)
append(wisp.send_split_callbacks, func)
end
@ -294,6 +370,11 @@ end
minetest.register_on_receiving_chat_message(
function(message)
-- hide Message sent.
if hide_sent and message_sent(message) then
return true
end
-- if its a PM
local player, msg = pm(message)
if player and msg then
@ -331,16 +412,17 @@ minetest.register_globalstep(
wisp.players = minetest.get_player_names()
end
if peek() then
local p = peek()
if p then
if not in_list(wisp.players, peek().player) then
minetest.display_chat_message("Player " .. peek().player .. " is not online. If they are please resend the message.")
dequeue()
return
end
if friends[peek().player] then
if (p.player == minetest.localplayer:get_name() and not p.force_send) or friends[p.player] then
local v = dequeue()
message_send(v.player, v.message)
message_send(v.player, v.message, v.hide_to, v.force_send)
end
end
end
@ -353,8 +435,7 @@ minetest.register_chatcommand("e", {
func = function(param)
local player = qsplit(param)[1]
local message = table.concat(popfirst(qsplit(param)), " ")
minetest.log(".e " .. tostring(player) .. ": " .. tostring(message))
if player == nil or message == nil then
if player == nil then
minetest.display_chat_message("Player not specified.")
return
end

View File

@ -2,4 +2,6 @@ wisp_prefix (Prefix for encrypted messages) string &**&
wisp_curve (Curve for ECDH) string prime256v1
wisp_cipher (Cipher for messages) string aes256
wisp_digest (Digest for shared secrets) string sha256
wisp_iv_size (Size in bytes for initialization vector nonce) int 8
wisp_whisper (Whisper command) string msg
wisp_hide_sent (Hide "Message sent." server messages) bool true