rename api, add cc and bcc, handle multiple players
rename: src -> from, dst -> to
This commit is contained in:
parent
2d087eaa13
commit
522eb0a9ee
64
api.lua
64
api.lua
@ -14,6 +14,7 @@ all 4 parameters (old compat version)
|
||||
see: "Mail format" api.md
|
||||
--]]
|
||||
function mail.send(src, dst, subject, body)
|
||||
-- figure out format
|
||||
local m
|
||||
if dst == nil and subject == nil and body == nil then
|
||||
-- new format (one object param)
|
||||
@ -21,36 +22,75 @@ function mail.send(src, dst, subject, body)
|
||||
else
|
||||
-- old format
|
||||
m = {}
|
||||
m.src = src
|
||||
m.dst = dst
|
||||
m.from = src
|
||||
m.to = dst
|
||||
m.subject = subject
|
||||
m.body = body
|
||||
end
|
||||
|
||||
-- log mail send action
|
||||
if m.cc or m.bcc then
|
||||
if m.cc then
|
||||
cc = "CC: " .. m.cc
|
||||
if m.bcc then
|
||||
cc = cc .. " - "
|
||||
end
|
||||
else
|
||||
cc = ""
|
||||
end
|
||||
if m.bcc then
|
||||
bcc = "BCC: " .. m.bcc
|
||||
else
|
||||
bcc = ""
|
||||
end
|
||||
extra = "(" .. cc .. bcc .. ") "
|
||||
else
|
||||
extra = ""
|
||||
end
|
||||
minetest.log("action", "[mail] '" .. m.from .. "' sends mail to '" .. m.to ..
|
||||
extra .. "' with subject '" .. m.subject .. "' and body: '" .. m.body .. "'")
|
||||
|
||||
minetest.log("action", "[mail] '" .. m.src .. "' sends mail to '" .. m.dst ..
|
||||
"' with subject '" .. m.subject .. "' and body: '" .. m.body .. "'")
|
||||
|
||||
local messages = mail.getMessages(m.dst)
|
||||
-- normalize to, cc and bcc while compiling a list of all recipients
|
||||
local recipients = {}
|
||||
m.to = normalize_players_and_add_recipients(m.to, recipients)
|
||||
if m.cc then
|
||||
m.cc = normalize_players_and_add_recipients(m.cc, recipients)
|
||||
end
|
||||
if m.bcc then
|
||||
m.bcc = normalize_players_and_add_recipients(m.bcc, recipients)
|
||||
end
|
||||
|
||||
table.insert(messages, 1, {
|
||||
-- form the actual mail
|
||||
msg = {
|
||||
unread = true,
|
||||
sender = m.src,
|
||||
from = m.from,
|
||||
to = m.to,
|
||||
subject = m.subject,
|
||||
body = m.body,
|
||||
time = os.time(),
|
||||
})
|
||||
mail.setMessages(m.dst, messages)
|
||||
}
|
||||
if m.cc then
|
||||
msg.cc = m.cc
|
||||
end
|
||||
|
||||
-- send the mail to all recipients
|
||||
for _, recipient in pairs(recipients) do
|
||||
local messages = mail.getMessages(recipient)
|
||||
table.insert(messages, 1, msg)
|
||||
mail.setMessages(recipient, messages)
|
||||
end
|
||||
|
||||
-- notify recipients that happen to be online
|
||||
for _, player in ipairs(minetest.get_connected_players()) do
|
||||
local name = player:get_player_name()
|
||||
if name == m.dst then
|
||||
if recipients[string.lower(name)] ~= nil then
|
||||
if m.subject == "" then m.subject = "(No subject)" end
|
||||
if string.len(m.subject) > 30 then
|
||||
m.subject = string.sub(m.subject,1,27) .. "..."
|
||||
end
|
||||
minetest.chat_send_player(m.dst,
|
||||
string.format(mail.receive_mail_message, m.src, m.subject))
|
||||
minetest.chat_send_player(name,
|
||||
string.format(mail.receive_mail_message, m.from, m.subject))
|
||||
end
|
||||
end
|
||||
|
||||
|
25
api.md
25
api.md
@ -2,6 +2,25 @@
|
||||
# Mail format
|
||||
The mail format in the api hooks
|
||||
|
||||
```lua
|
||||
mail = {
|
||||
from = "sender name",
|
||||
to = "players, which, are, addressed",
|
||||
cc = "carbon copy",
|
||||
bcc = "players, which, get, a, copy, but, are, not, visible, to, others",
|
||||
subject = "subject line",
|
||||
body = "mail body",
|
||||
-- 8 attachments max
|
||||
attachments = {"default:stone 99", "default:gold_ingot 99"}
|
||||
}
|
||||
```
|
||||
|
||||
The fields `to`, `cc` and `bcc` can contain a player, multiple player names separated by commas, or be empty. Players in `to` are the recipiants, who are addressed directly. `cc` specifies players that get the mail to get notified, but are not immediate part of the conversation. There is no technical difference between `to` and `cc`, it just implies meaning for the players. Players can see all fields making up the mail except `bcc`, which is the only difference to `cc`.
|
||||
|
||||
Attachments need to be provided for each player getting the mail. Until this is implemented, trying to send a mail to multiple players will fail.
|
||||
|
||||
The `from` and `to` fields were renamed from the previous format:
|
||||
|
||||
```lua
|
||||
mail = {
|
||||
src = "source name",
|
||||
@ -22,8 +41,10 @@ mail.send("source name", "destination name", "subject line", "mail body")
|
||||
New variant (1.1+)
|
||||
```lua
|
||||
mail.send({
|
||||
src = "source name",
|
||||
dst = "destination name",
|
||||
from = "sender name",
|
||||
to = "destination name",
|
||||
cc = "carbon copy",
|
||||
bcc = "blind carbon copy",
|
||||
subject = "subject line",
|
||||
body = "mail body"
|
||||
})
|
||||
|
20
gui.lua
20
gui.lua
@ -89,18 +89,20 @@ function mail.show_message(name, msgnumber)
|
||||
button[5,6.7;2,1;delete;Delete]
|
||||
]] .. theme
|
||||
|
||||
local sender = minetest.formspec_escape(message.sender)
|
||||
local from = minetest.formspec_escape(message.from)
|
||||
local subject = minetest.formspec_escape(message.subject)
|
||||
local body = minetest.formspec_escape(message.body)
|
||||
formspec = string.format(formspec, sender, subject, body)
|
||||
formspec = string.format(formspec, from, subject, body)
|
||||
|
||||
minetest.show_formspec(name,"mail:message",formspec)
|
||||
end
|
||||
|
||||
function mail.show_compose(name, defaulttgt, defaultsubj, defaultbody)
|
||||
function mail.show_compose(name, defaultto, defaultsubj, defaultbody, defaultcc, defaultbcc)
|
||||
local formspec = [[
|
||||
size[8,7.2]
|
||||
field[0.25,0.5;4,1;to;To:;%s]
|
||||
field[0.25,0.5;4,1;to;CC:;%s]
|
||||
field[0.25,0.5;4,1;to;BCC:;%s]
|
||||
field[0.25,1.7;8,1;subject;Subject:;%s]
|
||||
textarea[0.25,2.4;8,5;body;;%s]
|
||||
button[0.5,6.7;3,1;cancel;Cancel]
|
||||
@ -111,7 +113,9 @@ function mail.show_compose(name, defaulttgt, defaultsubj, defaultbody)
|
||||
formspec = string.format(formspec,
|
||||
minetest.formspec_escape(defaulttgt),
|
||||
minetest.formspec_escape(defaultsubj),
|
||||
minetest.formspec_escape(defaultbody))
|
||||
minetest.formspec_escape(defaultbody),
|
||||
minetest.formspec_escape(defaultcc),
|
||||
minetest.formspec_escape(defaultbcc))
|
||||
|
||||
minetest.show_formspec(name, "mail:compose", formspec)
|
||||
end
|
||||
@ -155,7 +159,7 @@ function mail.handle_receivefields(player, formname, fields)
|
||||
elseif fields.reply and messages[selected_message_idxs[name]] then
|
||||
local message = messages[selected_message_idxs[name]]
|
||||
local replyfooter = "Type your reply here.\n\n--Original message follows--\n" ..message.body
|
||||
mail.show_compose(name, message.sender, "Re: "..message.subject,replyfooter)
|
||||
mail.show_compose(name, message.from, "Re: "..message.subject,replyfooter)
|
||||
|
||||
elseif fields.forward and messages[selected_message_idxs[name]] then
|
||||
local message = messages[selected_message_idxs[name]]
|
||||
@ -215,8 +219,10 @@ function mail.handle_receivefields(player, formname, fields)
|
||||
elseif formname == "mail:compose" then
|
||||
if fields.send then
|
||||
mail.send({
|
||||
src = player:get_player_name(),
|
||||
dst = fields.to,
|
||||
from = player:get_player_name(),
|
||||
to = fields.to,
|
||||
cc = "",
|
||||
bcc = ""
|
||||
subject = fields.subject,
|
||||
body = fields.body
|
||||
})
|
||||
|
1
init.lua
1
init.lua
@ -26,6 +26,7 @@ mail = {
|
||||
|
||||
|
||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||
dofile(MP .. "/util/normalize.lua")
|
||||
dofile(MP .. "/chatcommands.lua")
|
||||
dofile(MP .. "/migrate.lua")
|
||||
dofile(MP .. "/attachment.lua")
|
||||
|
26
util/normalize.lua
Normal file
26
util/normalize.lua
Normal file
@ -0,0 +1,26 @@
|
||||
--[[
|
||||
return the field normalized (comma separated, single space)
|
||||
and add individual player names to recipient list
|
||||
--]]
|
||||
function normalize_players_and_add_recipients(field, recipients)
|
||||
local separator = ", "
|
||||
local pattern = "([^" .. separator .. "]+)"
|
||||
|
||||
-- get individual players
|
||||
local player_set = {}
|
||||
local order = {}
|
||||
field:gsub(pattern, function(c)
|
||||
if player_set[string.lower(c)] ~= nil then
|
||||
player_set[string.lower(c)] = c
|
||||
order[#order+1] = c
|
||||
|
||||
-- also sort into recipients
|
||||
if recipients[string.lower(c)] ~= nil then
|
||||
recipients[string.lower(c)] = c
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- turn list of players back into normalized string
|
||||
return table.concat(order, ", ")
|
||||
end
|
Loading…
Reference in New Issue
Block a user