Default message handler

master
SX 2021-04-07 12:53:45 +03:00
parent 039a469915
commit 9f48beb9b0
7 changed files with 121 additions and 130 deletions

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

@ -0,0 +1,11 @@
name: mineunit
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: mt-mods/mineunit-actions@v0.2

View File

@ -32,61 +32,3 @@ beerchat.send_message = function(name, message, channel)
minetest.sound_play(beerchat.channel_message_sound, { to_player = name, gain = beerchat.sounds_default_gain } )
end
end -- send_message
-- Send message to players near position.
-- radius and pos are optional to ensure backward compatibility of public API.
-- Returns true when someone heard whisper and false if nobody else can hear whisper (cancelled, too far, no position)
local whisper_color = "#aaaaaa"
local whisper_string = "|#${channel_name}| <${from_player}> whispers: ${message}"
beerchat.whisper = function(name, msg, radius, pos)
radius = radius or 32
-- if position not given try to use player position, this is done here to ensure backward compatibility
if not pos then
local player = minetest.get_player_by_name(name)
if not player then
return false
end
pos = player:get_pos()
end
if not beerchat.execute_callbacks('before_whisper', name, msg, beerchat.main_channel_name, radius, pos) then
-- Whispering was cancelled by one of external callbacks
return false
end
-- true if someone heard the player
local successful = false
for _, other_player in ipairs(minetest.get_connected_players()) do
-- calculate distance
local opos = other_player:get_pos()
local distance = vector.distance(opos, pos)
if distance < radius then
-- player in range
local target = other_player:get_player_name()
-- Checking if the target is in this channel
if beerchat.is_player_subscribed_to_channel(target, beerchat.main_channel_name) then
-- check if muted
if not beerchat.has_player_muted_player(target, name) then
-- mark as sent if anyone else is hearing it
if name ~= target then
successful = true
end
-- deliver message
beerchat.send_message(
target,
beerchat.format_message(whisper_string, {
channel_name = beerchat.main_channel_name,
from_player = name,
to_player = target,
message = msg,
color = whisper_color
}),
beerchat.main_channel_name
)
end
end
end
end
return successful
end

View File

@ -43,45 +43,3 @@ beerchat.register_callback("on_send_on_channel", function(msg, target)
return false
end
end)
-- FIXME: Add default message handler last, on_mods_loaded hack should
-- be replaced by calling default handler directly from router.lua
-- This hack does not take into account that other mods might attempt to do same.
minetest.register_on_mods_loaded(function()
beerchat.register_on_chat_message(function(name, message)
local channel_name = beerchat.currentPlayerChannel[name]
if not minetest.check_player_privs(name, "shout") then
-- the player does not have the shout priv, skip processing to channels
return false -- mark as "not handled"
end
if not beerchat.channels[channel_name] then
minetest.chat_send_player(
name,
"Channel "..channel_name.." does not exist, switching back to "..
beerchat.main_channel_name..". Please resend your message"
)
beerchat.currentPlayerChannel[name] = beerchat.main_channel_name
minetest.get_player_by_name(name):get_meta():set_string(
"beerchat:current_channel", beerchat.main_channel_name)
return true
end
if not beerchat.channels[channel_name] then
minetest.chat_send_player(name, "Channel "..channel_name.." does not exist")
elseif message == "" then
minetest.chat_send_player(name,
"Please enter the message you would like to send to the channel")
elseif not beerchat.is_player_subscribed_to_channel(name, channel_name) then
minetest.chat_send_player(name,
"You need to join this channel in order to be able to send messages to it")
else
beerchat.on_channel_message(channel_name, name, message)
beerchat.send_on_channel(name, channel_name, message)
end
return true
end)
end)

View File

@ -4,10 +4,10 @@
local MP = minetest.get_modpath("beerchat")
local function load_plugin(name, enable_default)
if minetest.settings:get_bool("beerchat.enable_"..name, enable_default) then
print("Loading beerchat plugin: " .. name)
minetest.log("info", "Loading beerchat extension: " .. name)
dofile(MP.."/plugin/"..name..".lua")
else
print("Beerchat plugin disabled: " .. name)
minetest.log("info", "Beerchat extension disabled: " .. name)
end
end

View File

@ -1,28 +1,74 @@
local whisper_default_range = 32 -- Default whisper range when whispering without specifying a radius
local whisper_max_range = 200 -- Maximum whisper range that can be specified when whispering
-- $ chat a.k.a. dollar chat code, to whisper messages in chat to nearby players only using $,
-- optionally supplying a radius e.g. $32 Hello
beerchat.register_on_chat_message(function(name, message)
-- Handle only messages beginning with $
if message:sub(1,1) ~= "$" then
-- Message not handled, continue processing message
-- Returns true when someone heard whisper and false if nobody else can hear whisper (cancelled, too far, no position)
local function whisper(pos, radius, name, msg, channel, fmtstr, color)
if not beerchat.execute_callbacks('before_whisper', name, msg, channel, radius, pos) then
-- Whispering was cancelled by one of external callbacks
return false
end
local sradius, msg = string.match(message, "^$(.-) (.*)")
local radius = tonumber(sradius) or whisper_default_range
if radius > whisper_max_range then
minetest.chat_send_player(name, "You cannot whisper outside of a radius of " .. whisper_max_range .. " nodes")
elseif msg == "" then
minetest.chat_send_player(name, "Please enter the message you would like to whisper to nearby players")
elseif not beerchat.whisper(name, msg, radius) then
minetest.chat_send_player(name, "no one heard you whispering!")
-- true if someone heard the player
local successful = false
for _, other_player in ipairs(minetest.get_connected_players()) do
-- calculate distance
local opos = other_player:get_pos()
local distance = vector.distance(opos, pos)
if distance < radius then
-- player in range
local target = other_player:get_player_name()
-- Checking if the target is in this channel
if beerchat.is_player_subscribed_to_channel(target, channel) then
-- check if muted
if not beerchat.has_player_muted_player(target, name) then
-- mark as sent if anyone else is hearing it
if name ~= target then
successful = true
end
-- deliver message
beerchat.send_message(
target,
beerchat.format_message(fmtstr, {
channel_name = channel,
from_player = name,
to_player = target,
message = msg,
color = color
}),
channel
)
end
end
end
end
return successful
end
-- Message handled, stop processing message
return true
local whisper_default_range = tonumber(minetest.settings:get("beerchat.whisper.range")) or 32
local whisper_max_range = tonumber(minetest.settings:get("beerchat.whisper.max_range")) or 200
local whisper_color = minetest.settings:get("beerchat.whisper.color") or "#aaaaaa"
local whisper_string = minetest.settings:get("beerchat.whisper.format") or
"|#${channel_name}| <${from_player}> whispers: ${message}"
local whisper_channel = beerchat.main_channel_name
end)
-- Send message to players near position, public API function for backward compatibility.
-- $ chat a.k.a. dollar chat code, to whisper messages in chat to nearby players only using $,
-- optionally supplying a radius e.g. $32 Hello
beerchat.whisper = function(name, message)
-- Handle only messages beginning with $
if message:sub(1,1) == "$" then
local sradius, msg = string.match(message, "^$(.-) (.*)")
local radius = tonumber(sradius) or whisper_default_range
local player = minetest.get_player_by_name(name)
if radius > whisper_max_range then
minetest.chat_send_player(name, "You cannot whisper outside of a radius of "..whisper_max_range.." nodes")
elseif msg == "" then
minetest.chat_send_player(name, "Please enter the message you would like to whisper to nearby players")
elseif player then
if not whisper(player:get_pos(), radius, name, msg, whisper_channel, whisper_string, whisper_color) then
minetest.chat_send_player(name, "no one heard you whispering!")
end
end
-- Message handled, stop processing message
return true
end
end
beerchat.register_on_chat_message(beerchat.whisper)

View File

@ -8,6 +8,32 @@ function beerchat.register_on_chat_message(func)
table.insert(on_chat_message_handlers, func)
end
local function default_message_handler(name, message)
-- Do not allow players without shout priv to chat in channels
if not minetest.check_player_privs(name, "shout") then
return true
end
local channel_name = beerchat.currentPlayerChannel[name]
if not beerchat.channels[channel_name] then
minetest.chat_send_player(
name,
"Channel "..channel_name.." does not exist, switching back to "..
beerchat.main_channel_name..". Please resend your message"
)
beerchat.currentPlayerChannel[name] = beerchat.main_channel_name
minetest.get_player_by_name(name):get_meta():set_string("beerchat:current_channel", beerchat.main_channel_name)
elseif message == "" then
minetest.chat_send_player(name, "Please enter the message you would like to send to the channel")
elseif not beerchat.is_player_subscribed_to_channel(name, channel_name) then
minetest.chat_send_player(name, "You need to join this channel in order to be able to send messages to it")
else
beerchat.on_channel_message(channel_name, name, message)
beerchat.send_on_channel(name, channel_name, message)
end
return true
end
-- All messages are handled either by sending to channel or through special plugin function.
minetest.register_on_chat_message(function(name, message)
@ -17,7 +43,7 @@ minetest.register_on_chat_message(function(name, message)
message = msg_data.message
name = msg_data.name
else
print("Beerchat message discarded by on_receive hook, contents went to /dev/null")
minetest.log("verbose", "Beerchat message discarded by on_receive hook, contents went to /dev/null")
return true
end
@ -28,9 +54,6 @@ minetest.register_on_chat_message(function(name, message)
return true
end
end
-- This should never happen, beerchat must handle all messages.
-- FIXME: Call default handler directly here instead of using hacky on_mods_loaded hook in message.lua
error("Beerchat was unable to handle message: " .. dump(name) .. ", " .. dump(message))
-- None of extensions handled current message, call through default message handler
return default_message_handler(name, message)
end)

11
spec/init_spec.lua Normal file
View File

@ -0,0 +1,11 @@
require("mineunit")
mineunit("core")
describe("Mod initialization", function()
it("Wont crash", function()
sourcefile("init")
end)
end)