mirror of
https://github.com/mt-mods/mail.git
synced 2025-07-06 14:40:30 -04:00
docs
This commit is contained in:
parent
8ce3dc2ecf
commit
dff068d75b
7 changed files with 91 additions and 139 deletions
43
api.lua
43
api.lua
|
@ -10,36 +10,15 @@ end
|
||||||
mail.receive_mail_message = "You have a new message from %s! Subject: %s\nTo view it, type /mail"
|
mail.receive_mail_message = "You have a new message from %s! Subject: %s\nTo view it, type /mail"
|
||||||
mail.read_later_message = "You can read your messages later by using the /mail command"
|
mail.read_later_message = "You can read your messages later by using the /mail command"
|
||||||
|
|
||||||
--[[
|
function mail.send(m)
|
||||||
mail sending function, can be invoked with one object argument (new api) or
|
if type(m.from) ~= "string" then return false, "'from' is not a string" end
|
||||||
all 4 parameters (old compat version)
|
if type(m.to) ~= "string" then return false, "'to' is not a string" end
|
||||||
see: "Mail format" api.md
|
if type(m.body) ~= "string" then return false, "'body' is not a string" end
|
||||||
|
|
||||||
TODO: refactor this garbage code!
|
-- defaults
|
||||||
--]]
|
m.subject = m.subject or "(No subject)"
|
||||||
function mail.send(...)
|
|
||||||
-- figure out format
|
|
||||||
local m
|
|
||||||
if #{...} == 1 then
|
|
||||||
-- new format (one table param)
|
|
||||||
m = ...
|
|
||||||
-- populate "to" field
|
|
||||||
m.to = m.to or m.dst
|
|
||||||
-- populate "from" field
|
|
||||||
m.from = m.from or m.src
|
|
||||||
else
|
|
||||||
-- old format
|
|
||||||
m = {}
|
|
||||||
m.from, m.to, m.subject, m.body = ...
|
|
||||||
end
|
|
||||||
|
|
||||||
-- sane default values
|
-- limit subject line
|
||||||
m.subject = m.subject or ""
|
|
||||||
m.body = m.body or ""
|
|
||||||
|
|
||||||
if m.subject == "" then
|
|
||||||
m.subject = "(No subject)"
|
|
||||||
end
|
|
||||||
if string.len(m.subject) > 30 then
|
if string.len(m.subject) > 30 then
|
||||||
m.subject = string.sub(m.subject,1,27) .. "..."
|
m.subject = string.sub(m.subject,1,27) .. "..."
|
||||||
end
|
end
|
||||||
|
@ -63,9 +42,7 @@ function mail.send(...)
|
||||||
for name in pairs(undeliverable) do
|
for name in pairs(undeliverable) do
|
||||||
undeliverable_names[#undeliverable_names + 1] = '"' .. name .. '"'
|
undeliverable_names[#undeliverable_names + 1] = '"' .. name .. '"'
|
||||||
end
|
end
|
||||||
return f("recipients %s don't exist; cannot send mail.",
|
return false, f("recipients %s don't exist; cannot send mail.", table.concat(undeliverable_names, ", "))
|
||||||
table.concat(undeliverable_names, ", ")
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local extra = {}
|
local extra = {}
|
||||||
|
@ -89,7 +66,7 @@ function mail.send(...)
|
||||||
-- form the actual mail
|
-- form the actual mail
|
||||||
local msg = {
|
local msg = {
|
||||||
id = mail.new_uuid(),
|
id = mail.new_uuid(),
|
||||||
sender = m.from,
|
from = m.from,
|
||||||
to = m.to,
|
to = m.to,
|
||||||
cc = m.cc,
|
cc = m.cc,
|
||||||
bcc = m.bcc,
|
bcc = m.bcc,
|
||||||
|
@ -124,4 +101,6 @@ function mail.send(...)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
113
api.md
113
api.md
|
@ -9,47 +9,28 @@ mail = {
|
||||||
cc = "carbon copy",
|
cc = "carbon copy",
|
||||||
bcc = "players, which, get, a, copy, but, are, not, visible, to, others",
|
bcc = "players, which, get, a, copy, but, are, not, visible, to, others",
|
||||||
subject = "subject line",
|
subject = "subject line",
|
||||||
body = "mail body",
|
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`.
|
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.
|
||||||
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.
|
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`.
|
||||||
The `from` and `to` fields were renamed from the previous format:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
mail = {
|
|
||||||
src = "source name",
|
|
||||||
dst = "destination name",
|
|
||||||
subject = "subject line",
|
|
||||||
body = "mail body",
|
|
||||||
-- 8 attachments max
|
|
||||||
attachments = {"default:stone 99", "default:gold_ingot 99"}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Sending mail
|
## Sending mail
|
||||||
Old variant (pre-1.1)
|
|
||||||
```lua
|
|
||||||
local error = mail.send("source name", "destination name", "subject line", "mail body")
|
|
||||||
-- error will contain an error message if mail couldn't be delivered, otherwise nil
|
|
||||||
```
|
|
||||||
|
|
||||||
New variant (1.1+)
|
|
||||||
```lua
|
```lua
|
||||||
local error = mail.send({
|
local success, error = mail.send({
|
||||||
from = "sender name",
|
from = "singleplayer",
|
||||||
to = "destination name",
|
to = "playername",
|
||||||
cc = "carbon copy",
|
cc = "carbon, copy",
|
||||||
bcc = "blind carbon copy",
|
bcc = "blind, carbon, copy",
|
||||||
subject = "subject line",
|
subject = "subject line",
|
||||||
body = "mail body"
|
body = "mail body"
|
||||||
})
|
})
|
||||||
-- error will contain an error message if mail couldn't be delivered, otherwise nil
|
|
||||||
|
-- if "success" is false the error parameter will contain a message
|
||||||
```
|
```
|
||||||
|
|
||||||
# Hooks
|
# Hooks
|
||||||
|
@ -61,22 +42,56 @@ mail.register_on_receive(function(m)
|
||||||
end)
|
end)
|
||||||
```
|
```
|
||||||
|
|
||||||
# internal mail format (on-disk)
|
# Internals
|
||||||
The mail format on-disk
|
|
||||||
|
|
||||||
> (worldfolder)/mails/(playername).json
|
mod-storage entry for a player (indexed by playername and serialized with json):
|
||||||
|
```lua
|
||||||
```json
|
{
|
||||||
[{
|
contacts = {
|
||||||
"unread": true,
|
{
|
||||||
"sender": "sender name",
|
-- name of the player (unique key in the list)
|
||||||
"subject": "subject name",
|
name = "",
|
||||||
"body": "main\nmultiline\nbody",
|
-- note
|
||||||
"time": 1551258349,
|
note = ""
|
||||||
"attachments": [
|
},{
|
||||||
"default:stone 99",
|
...
|
||||||
"default:gold_ingot 99"
|
}
|
||||||
]
|
},
|
||||||
}]
|
inbox = {
|
||||||
|
{
|
||||||
```
|
-- globally unique mail id
|
||||||
|
id = "d6cce35c-487a-458f-bab2-9032c2621f38",
|
||||||
|
-- sending player name
|
||||||
|
from = "",
|
||||||
|
-- receiving player name
|
||||||
|
to = "",
|
||||||
|
-- carbon copy (optional)
|
||||||
|
cc = "playername, playername2",
|
||||||
|
-- blind carbon copy (optional)
|
||||||
|
bcc = "",
|
||||||
|
-- mail subject
|
||||||
|
subject = "",
|
||||||
|
-- mail body
|
||||||
|
body = "",
|
||||||
|
-- timestamp (os.time())
|
||||||
|
time = 1234,
|
||||||
|
-- read-flag (true: player has read the mail, inbox only)
|
||||||
|
read = true
|
||||||
|
},{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
},
|
||||||
|
outbox = {
|
||||||
|
-- same format as "inbox"
|
||||||
|
},
|
||||||
|
lists = {
|
||||||
|
{
|
||||||
|
-- name of the maillist (unique key in the list)
|
||||||
|
name = "",
|
||||||
|
-- description
|
||||||
|
description = "",
|
||||||
|
-- playername list
|
||||||
|
players = {"playername", "playername2"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ function mail.migrate_v2_to_v3()
|
||||||
if msg.to then
|
if msg.to then
|
||||||
table.insert(entry.inbox, {
|
table.insert(entry.inbox, {
|
||||||
id = mail.new_uuid(),
|
id = mail.new_uuid(),
|
||||||
sender = msg.sender,
|
from = msg.sender or msg.from,
|
||||||
to = msg.to,
|
to = msg.to,
|
||||||
cc = msg.cc,
|
cc = msg.cc,
|
||||||
subject = msg.subject,
|
subject = msg.subject,
|
||||||
|
|
4
mtt.lua
4
mtt.lua
|
@ -4,7 +4,9 @@ mtt.register("send mail", function(callback)
|
||||||
auth_handler.set_password("player2", "")
|
auth_handler.set_password("player2", "")
|
||||||
|
|
||||||
-- send a mail
|
-- send a mail
|
||||||
mail.send({from = "player1", to = "player2", subject = "something", body = "blah"})
|
local success, err = mail.send({from = "player1", to = "player2", subject = "something", body = "blah"})
|
||||||
|
assert(success)
|
||||||
|
assert(not err)
|
||||||
|
|
||||||
-- check the receivers inbox
|
-- check the receivers inbox
|
||||||
local entry = mail.get_storage_entry("player2")
|
local entry = mail.get_storage_entry("player2")
|
||||||
|
|
48
storage.lua
48
storage.lua
|
@ -1,3 +1,5 @@
|
||||||
|
-- storage getter/setter
|
||||||
|
|
||||||
function mail.get_storage_entry(playername)
|
function mail.get_storage_entry(playername)
|
||||||
local str = mail.storage:get_string(playername)
|
local str = mail.storage:get_string(playername)
|
||||||
if str == "" then
|
if str == "" then
|
||||||
|
@ -14,52 +16,6 @@ function mail.get_storage_entry(playername)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[
|
|
||||||
Mail format (inbox, outbox):
|
|
||||||
|
|
||||||
table of: {
|
|
||||||
-- globally unique mail id
|
|
||||||
id = "d6cce35c-487a-458f-bab2-9032c2621f38",
|
|
||||||
-- sending player name
|
|
||||||
sender = "",
|
|
||||||
-- receiving player name
|
|
||||||
to = "",
|
|
||||||
-- carbon copy (optional)
|
|
||||||
cc = "",
|
|
||||||
-- blind carbon copy (optional)
|
|
||||||
bcc = "",
|
|
||||||
-- mail subject
|
|
||||||
subject = "",
|
|
||||||
-- mail body
|
|
||||||
body = "",
|
|
||||||
-- timestamp (os.time())
|
|
||||||
time = 1234,
|
|
||||||
-- read-flag (true: player has read the mail, inbox only)
|
|
||||||
read = true
|
|
||||||
}
|
|
||||||
|
|
||||||
Contact format:
|
|
||||||
|
|
||||||
table of: {
|
|
||||||
-- name of the player (unique key in the list)
|
|
||||||
name = "",
|
|
||||||
-- note
|
|
||||||
note = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
Mail-list format:
|
|
||||||
|
|
||||||
table of: {
|
|
||||||
-- name of the maillist (unique key in the list)
|
|
||||||
name = "",
|
|
||||||
-- description
|
|
||||||
description = "",
|
|
||||||
-- playername list
|
|
||||||
players = {"playername", "playername2"}
|
|
||||||
}
|
|
||||||
|
|
||||||
--]]
|
|
||||||
|
|
||||||
function mail.set_storage_entry(playername, entry)
|
function mail.set_storage_entry(playername, entry)
|
||||||
mail.storage:get_string(playername, minetest.write_json(entry))
|
mail.storage:get_string(playername, minetest.write_json(entry))
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,7 +42,7 @@ function mail.show_inbox(name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
formspec[#formspec + 1] = ","
|
formspec[#formspec + 1] = ","
|
||||||
formspec[#formspec + 1] = minetest.formspec_escape(message.sender)
|
formspec[#formspec + 1] = minetest.formspec_escape(message.from)
|
||||||
formspec[#formspec + 1] = ","
|
formspec[#formspec + 1] = ","
|
||||||
if message.subject ~= "" then
|
if message.subject ~= "" then
|
||||||
if string.len(message.subject) > 30 then
|
if string.len(message.subject) > 30 then
|
||||||
|
|
|
@ -24,7 +24,7 @@ function mail.show_message(name, id)
|
||||||
button[6,8.5;2,1;delete;Delete]
|
button[6,8.5;2,1;delete;Delete]
|
||||||
]] .. mail.theme
|
]] .. mail.theme
|
||||||
|
|
||||||
local from = minetest.formspec_escape(message.sender) or ""
|
local from = minetest.formspec_escape(message.from) or ""
|
||||||
local to = minetest.formspec_escape(message.to) or ""
|
local to = minetest.formspec_escape(message.to) or ""
|
||||||
local cc = minetest.formspec_escape(message.cc) or ""
|
local cc = minetest.formspec_escape(message.cc) or ""
|
||||||
local date = type(message.time) == "number"
|
local date = type(message.time) == "number"
|
||||||
|
@ -43,7 +43,7 @@ end
|
||||||
|
|
||||||
function mail.reply(name, message)
|
function mail.reply(name, message)
|
||||||
local replyfooter = "Type your reply here.\n\n--Original message follows--\n" ..message.body
|
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)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mail.replyall(name, message)
|
function mail.replyall(name, message)
|
||||||
|
@ -51,8 +51,8 @@ function mail.replyall(name, message)
|
||||||
|
|
||||||
-- new recipients are the sender plus the original recipients, minus ourselves
|
-- new recipients are the sender plus the original recipients, minus ourselves
|
||||||
local recipients = message.to or ""
|
local recipients = message.to or ""
|
||||||
if message.sender ~= nil then
|
if message.from ~= nil then
|
||||||
recipients = message.sender .. ", " .. recipients
|
recipients = message.from .. ", " .. recipients
|
||||||
end
|
end
|
||||||
recipients = mail.parse_player_list(recipients)
|
recipients = mail.parse_player_list(recipients)
|
||||||
for k,v in pairs(recipients) do
|
for k,v in pairs(recipients) do
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue