adv_chat/message.lua

237 lines
8.4 KiB
Lua

-- TODO handle <https://example.com> and mentions like @<ID> or @<!ID> (modification of Discord bot needed)
message={}
function message.new(chatter, mentions, content)
return {chatter=chatter, mentions=mentions, content=content}
end
local function unicode(message)
message.unicode_content = message.unicode_content or parse_unicode(message.content)
return message.unicode_content
end
local function colorized(message)
if not message.colorized_content then
message.colorized_content, message.uncolorized_content=colorize_message(unicode(message))
end
return message.colorized_content
end
local function uncolorized(message)
if not message.uncolorized_content then
message.colorized_content, message.uncolorized_content=colorize_message(unicode(message))
end
message.uncolorized_content=minetest.strip_colors(message.uncolorized_content)
return message.uncolorized_content
end
local to = {
minetest = {
from={
internal=function(message)
return message.content
end,
minetest = colorized,
irc = function(message)
message.colorized_content = irc_to_minetest(colorized(message))
return message.colorized_content
end,
discord = uncolorized
}
},
irc = {
from={
internal=function(message)
return message.content
end,
minetest = function(message)
return colorized(message)
end,
irc = function(message)
return colorized(message)
end,
discord = function(message)
return minetest_to_irc(colorized(message))
end
}
},
discord = {
from={
internal=function(message)
return minetest.strip_colors(message.content)
end,
minetest = uncolorized,
irc = function(message)
return uncolorized(message)
end,
discord = uncolorized
}
}
}
local builders = to
builders.minetest.scheme = schemes.minetest
builders.irc.scheme = schemes.irc
builders.discord.scheme = schemes.discord
function message.mentionpart(msg)
if not msg.mentionpart then
msg.invalid_mentions={}
msg.targets={}
msg.valid_targets={}
msg.mentionpart={}
for _, mention in ipairs(msg.mentions or {}) do
if not msg.targets[mention] then
msg.targets[mention]=true
if roles[mention] then
table.insert(msg.mentionpart, roles[mention].color)
table.insert(msg.mentionpart, mention)
msg.valid_targets[mention] = roles[mention]
elseif chatters[mention] then
table.insert(msg.mentionpart, chatters[mention].color)
table.insert(msg.mentionpart, mention)
msg.valid_targets[mention] = chatters[mention]
else
table.insert(msg.invalid_mentions, mention)
end
end
end
end
end
local mentionpart_builders = {
irc=nil,
discord=function(msg)
if not msg.uncolorized_mentionpart then
msg.uncolorized_mentionpart={}
for i=2, #msg.mentionpart, 2 do
table.insert(msg.uncolorized_mentionpart,msg.mentionpart[i])
end
end
return "uncolorized_mentionpart"
end,
minetest=function(msg)
if not msg.mt_mentionpart then
msg.mt_mentionpart={}
for index, item in ipairs(msg.mentionpart) do
table.insert(msg.mt_mentionpart, ((index % 2 == 0) and item) or minetest.get_color_escape_sequence(item))
end
end
return "mt_mentionpart"
end
}
local function wrap_builder(source, goal, wrapper)
local old_builder = builders[source].from[goal]
builders[source].from[goal] = function(msg) return wrapper(old_builder(msg)) end
end
if bridges.discord then
if not bridges.discord.convert_internal_markdown then
wrap_builder("discord", "internal", escape_markdown)
end
if not bridges.discord.convert_minetest_markdown then
wrap_builder("discord", "minetest", escape_markdown)
end
if bridges.discord.handle_irc_styles == "escape_markdown" then
wrap_builder("discord", "irc", escape_markdown)
elseif bridges.discord.handle_irc_styles ~= "disabled" then
wrap_builder("discord", "irc", irc_to_markdown)
end
end
if bridges.irc then
if bridges.irc.handle_discord_markdown == "strip" then
wrap_builder("irc", "discord", strip_markdown)
elseif bridges.irc.handle_discord_markdown ~= "disabled" then
wrap_builder("irc", "discord", markdown_to_irc)
end
if bridges.irc.handle_minetest_markdown == "strip" then
wrap_builder("irc", "minetest", strip_markdown)
elseif bridges.irc.handle_discord_markdown ~= "disabled" then
wrap_builder("irc", "minetest", markdown_to_irc)
end
if bridges.irc.handle_internal_markdown == "strip" then
wrap_builder("irc", "internal", strip_markdown)
elseif bridges.irc.handle_discord_markdown ~= "disabled" then
wrap_builder("irc", "internal", markdown_to_irc)
end
if bridges.irc.convert_minetest_colors=="disabled" then
mentionpart_builders.irc=mentionpart_builders.discord
else
local old_from_minetest = builders.irc.from.minetest
builders.irc.from.minetest=function(msg) return minetest_to_irc(old_from_minetest(msg)) end
local old_from_internal = builders.irc.from.internal
builders.irc.from.internal=function(msg) return minetest_to_irc(old_from_internal(msg)) end
mentionpart_builders.irc=function(msg)
if not msg.irc_mentionpart then
msg.irc_mentionpart={}
for index, item in ipairs(msg.mentionpart) do
if index % 2 == 0 then
table.insert(msg.irc_mentionpart, item)
elseif item ~= "#FFFFFF" then
table.insert(msg.irc_mentionpart, convert_color_to_irc(item:sub(2)))
end
table.insert(msg.irc_mentionpart, ((index % 2 == 0) and item) or (item ~= "#FFFFFF" and convert_color_to_irc(item:sub(2))))
end
end
return "irc_mentionpart"
end
end
end
function message.mentionpart_target(msg, target)
local builder=mentionpart_builders[target]
message.mentionpart(msg)
local name=builder(msg)
local text = name.."_text"
if not msg[text] then
msg[text]=table.concat(msg[name], builders[target].mention_delim)
end
return msg[text]
end
function message.build(msg, target)
local build=target.."_build"
if not msg[build] then
local builder = builders[target]
if msg.internal then
msg[build]=builder.from.internal(msg)
return msg[build]
end
local conversion = builder.from[msg.chatter.service]
local content = conversion(msg)
local source = (msg.chatter.name and msg.chatter.name)
if source and msg.chatter.color then
if target=="minetest" then
source=minetest.get_color_escape_sequence(msg.chatter.color)..source
elseif target=="irc" and bridges.irc.style_conversion.color~="disabled" then
local to_escape, color=convert_color_to_irc(msg.chatter.color:sub(2))
if source:sub(1,1)==to_escape then
source=string.char(0x02)..string.char(0x02)..source
end
source=color..source
end
end
local mentions = (msg.mentions and next(msg.mentions) and builder.scheme.mention_prefix..message.mentionpart_target(msg, target)..builder.scheme.content_prefix)
if not mentions and source then source=source..builder.scheme.content_prefix end
msg[build]=builder.scheme.message_prefix..(source or "")..(mentions or "")..content..builder.scheme.message_suffix
end
return msg[build]
end
function message.handle_on_chat_messages(msg)
local on_chat_messages = call_registered_on_chat_messages((msg.chatter and msg.chatter.name) or "", msg.content, msg)
if on_chat_messages then
msg.handled_by_on_chat_messages = on_chat_messages
return on_chat_messages
end
end