Compare commits
10 Commits
updated-do
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
8a992b7a29 | ||
|
1bffd98132 | ||
|
59667bd35c | ||
|
09b233b039 | ||
|
b9982f11e6 | ||
|
4f15c2fe65 | ||
|
4cd06c5f5f | ||
|
036d37695a | ||
|
5cfec3a92a | ||
|
a347a79e6a |
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
@ -9,9 +9,9 @@ jobs:
|
|||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
ENGINE_VERSION: [5.0.1, 5.1.1, 5.2.0, 5.3.0, 5.4.1, 5.5.1, 5.6.1, 5.7.0, 5.8.0, latest]
|
ENGINE_VERSION: [5.0.1, 5.1.1, 5.2.0, 5.3.0, 5.4.1, 5.5.1, 5.6.1, 5.7.0, 5.8.0, 5.9.0, latest]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: test
|
- name: test
|
||||||
run: docker-compose up --exit-code-from sut
|
run: docker compose up --exit-code-from sut
|
||||||
|
15
README.md
15
README.md
@ -11,7 +11,8 @@ It adds a mail-system that allows players to send each other messages in-game an
|
|||||||
|
|
||||||
# Screenshot
|
# Screenshot
|
||||||
|
|
||||||
![](screenshot_1.2.0.png)
|
![Main view](screenshot_1.4.0_1.png)
|
||||||
|
![Message view](screenshot_1.4.0_2.png)
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
@ -43,7 +44,8 @@ Mails can be deleted, marked as read or unread, replied to and forwarded to anot
|
|||||||
* Multiple selection (new in 1.1.0)
|
* Multiple selection (new in 1.1.0)
|
||||||
* Settings
|
* Settings
|
||||||
* Chat, on join, HUD and sound notifications
|
* Chat, on join, HUD and sound notifications
|
||||||
* Translated in : English, French, German, Chinese (both traditional and simplified), Spanish, Brazilian Portuguese.
|
* Anti-spam detection
|
||||||
|
* Translated in : English, French, German, Chinese (both traditional and simplified), Spanish, Brazilian Portuguese, Hungarian, Indonesian.
|
||||||
|
|
||||||
# Compatibility / Migration
|
# Compatibility / Migration
|
||||||
|
|
||||||
@ -51,8 +53,10 @@ Overview:
|
|||||||
* `v1` all the data is in the `<worldfolder>/mails.db` file
|
* `v1` all the data is in the `<worldfolder>/mails.db` file
|
||||||
* `v2` every player has its own (in-) mailbox in the `<worldfolder>/mails/<playername>.json` file
|
* `v2` every player has its own (in-) mailbox in the `<worldfolder>/mails/<playername>.json` file
|
||||||
* `v3` every player has an entry in the `<playername>` `mod_storage/` (inbox, outbox, drafts, contacts, mailing lists, settings)
|
* `v3` every player has an entry in the `<playername>` `mod_storage/` (inbox, outbox, drafts, contacts, mailing lists, settings)
|
||||||
|
* `v3.1` database fix after the message id mess
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|
||||||
* None
|
* None
|
||||||
|
|
||||||
# License
|
# License
|
||||||
@ -72,7 +76,7 @@ See the "LICENSE" file
|
|||||||
* fluxionary (Minor fixups)
|
* fluxionary (Minor fixups)
|
||||||
* Toby1710 (UX fixes)
|
* Toby1710 (UX fixes)
|
||||||
* Peter Nerlich (CC, BCC)
|
* Peter Nerlich (CC, BCC)
|
||||||
* Emojigit (Traditional Chinese translation)
|
* Emojigit (Performance, Traditional Chinese translation)
|
||||||
* Niklp09 (German translation)
|
* Niklp09 (German translation)
|
||||||
* Dennis Jenkins (UX fixes)
|
* Dennis Jenkins (UX fixes)
|
||||||
* Thomas Rudin (Maintenance)
|
* Thomas Rudin (Maintenance)
|
||||||
@ -84,7 +88,12 @@ See the "LICENSE" file
|
|||||||
* nyomi (Hungarian translation)
|
* nyomi (Hungarian translation)
|
||||||
* whosit (UI fixes)
|
* whosit (UI fixes)
|
||||||
* Wuzzy (German translation)
|
* Wuzzy (German translation)
|
||||||
|
* savilli (UX fixes)
|
||||||
|
* Panquesito7 (Maintenance)
|
||||||
|
* Eredin (Spanish translation)
|
||||||
* Muhammad Rifqi Priyo Susanto (Indonesian translation)
|
* Muhammad Rifqi Priyo Susanto (Indonesian translation)
|
||||||
|
* aBlueShadow (sfinv compatibility)
|
||||||
|
* Singularis (UX and storage fixes)
|
||||||
|
|
||||||
# Contribute
|
# Contribute
|
||||||
|
|
||||||
|
2
api.lua
2
api.lua
@ -1,7 +1,7 @@
|
|||||||
-- see: mail.md
|
-- see: mail.md
|
||||||
|
|
||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
local f = string.format
|
local f = string.format
|
||||||
|
|
||||||
|
17
api.md
17
api.md
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# Mail format
|
# Mail format
|
||||||
The mail format in the api hooks
|
The mail format in the api hooks
|
||||||
|
|
||||||
@ -70,6 +69,7 @@ The recipient handler should return
|
|||||||
mod-storage entry for a player (indexed by playername and serialized with json):
|
mod-storage entry for a player (indexed by playername and serialized with json):
|
||||||
```lua
|
```lua
|
||||||
{
|
{
|
||||||
|
|
||||||
contacts = {
|
contacts = {
|
||||||
{
|
{
|
||||||
-- name of the player (unique key in the list)
|
-- name of the player (unique key in the list)
|
||||||
@ -99,7 +99,9 @@ mod-storage entry for a player (indexed by playername and serialized with json):
|
|||||||
-- timestamp (os.time())
|
-- timestamp (os.time())
|
||||||
time = 1234,
|
time = 1234,
|
||||||
-- read-flag (true: player has read the mail, inbox only)
|
-- read-flag (true: player has read the mail, inbox only)
|
||||||
read = true
|
read = true,
|
||||||
|
-- spam-flag (true: that mail is noted as a spam)
|
||||||
|
spam = false
|
||||||
},{
|
},{
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
@ -107,6 +109,12 @@ mod-storage entry for a player (indexed by playername and serialized with json):
|
|||||||
outbox = {
|
outbox = {
|
||||||
-- same format as "inbox"
|
-- same format as "inbox"
|
||||||
},
|
},
|
||||||
|
drafts = {
|
||||||
|
-- same format as "inbox"
|
||||||
|
},
|
||||||
|
trash = {
|
||||||
|
-- same format as "inbox"
|
||||||
|
},
|
||||||
lists = {
|
lists = {
|
||||||
{
|
{
|
||||||
-- name of the maillist (unique key in the list)
|
-- name of the maillist (unique key in the list)
|
||||||
@ -116,5 +124,10 @@ mod-storage entry for a player (indexed by playername and serialized with json):
|
|||||||
-- playername list
|
-- playername list
|
||||||
players = {"playername", "playername2"}
|
players = {"playername", "playername2"}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
settings = {
|
||||||
|
setting1 = "value",
|
||||||
|
setting2 = true,
|
||||||
|
setting3 = 123
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
version: "3.6"
|
version: "4.1"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
sut:
|
sut:
|
||||||
|
3
init.lua
3
init.lua
@ -5,6 +5,9 @@ mail = {
|
|||||||
-- mod storage
|
-- mod storage
|
||||||
storage = minetest.get_mod_storage(),
|
storage = minetest.get_mod_storage(),
|
||||||
|
|
||||||
|
-- translation
|
||||||
|
S = minetest.get_translator(minetest.get_current_modname()),
|
||||||
|
|
||||||
-- ui theme prepend
|
-- ui theme prepend
|
||||||
theme = "",
|
theme = "",
|
||||||
|
|
||||||
|
71
migrate.lua
71
migrate.lua
@ -91,17 +91,29 @@ local function search_box(playername, box, uuid)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function search_boxes(playername, boxes, uuid)
|
||||||
|
local result
|
||||||
|
for _, b in ipairs(boxes) do
|
||||||
|
result = search_box(playername, b, uuid)
|
||||||
|
if result then return result end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function is_uuid_existing(uuid)
|
local function is_uuid_existing(uuid)
|
||||||
|
local boxes = {"inbox", "outbox", "drafts", "trash"}
|
||||||
|
if mail.storage.get_keys then
|
||||||
for _, k in ipairs(mail.storage:get_keys()) do
|
for _, k in ipairs(mail.storage:get_keys()) do
|
||||||
if string.sub(k,1,5) == "mail/" then
|
if string.sub(k,1,5) == "mail/" then
|
||||||
local p = string.sub(k, 6)
|
local p = string.sub(k, 6)
|
||||||
local result
|
local result = search_boxes(p, boxes, uuid)
|
||||||
local boxes = {"inbox", "outbox", "drafts", "trash"}
|
|
||||||
for _, b in ipairs(boxes) do
|
|
||||||
result = search_box(p, b, uuid)
|
|
||||||
if result then return result end
|
if result then return result end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
for p, _ in minetest.get_auth_handler().iterate() do
|
||||||
|
local result = search_boxes(p, boxes, uuid)
|
||||||
|
if result then return result end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@ -116,16 +128,7 @@ local function are_message_sames(a, b)
|
|||||||
and a.body == b.body
|
and a.body == b.body
|
||||||
end
|
end
|
||||||
|
|
||||||
local function fix_duplicate_uuids(playername, box)
|
local function replace_other_player_message_uuid(p, m, uuid, new_uuid)
|
||||||
local e = mail.get_storage_entry(playername)
|
|
||||||
for _, m in ipairs(e[box]) do
|
|
||||||
local uuid = m.id
|
|
||||||
local exists = is_uuid_existing(uuid)
|
|
||||||
if exists and not are_message_sames(exists, m) then
|
|
||||||
local new_uuid = mail.new_uuid() -- generates a new uuid to replace doublons
|
|
||||||
for _, k in ipairs(mail.storage:get_keys()) do
|
|
||||||
if string.sub(k,1,5) == "mail/" then
|
|
||||||
local p = string.sub(k, 6)
|
|
||||||
local er = mail.get_storage_entry(p)
|
local er = mail.get_storage_entry(p)
|
||||||
for _, r in ipairs(er.inbox) do
|
for _, r in ipairs(er.inbox) do
|
||||||
if r.id == uuid and not are_message_sames(m, r) then
|
if r.id == uuid and not are_message_sames(m, r) then
|
||||||
@ -149,23 +152,55 @@ local function fix_duplicate_uuids(playername, box)
|
|||||||
end
|
end
|
||||||
mail.set_storage_entry(p, er)
|
mail.set_storage_entry(p, er)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function fix_box_duplicate_uuids(playername, box)
|
||||||
|
local e = mail.get_storage_entry(playername)
|
||||||
|
for _, m in ipairs(e[box]) do
|
||||||
|
local uuid = m.id
|
||||||
|
local exists = is_uuid_existing(uuid)
|
||||||
|
if exists and not are_message_sames(exists, m) then
|
||||||
|
local new_uuid = mail.new_uuid() -- generates a new uuid to replace doublons
|
||||||
|
if mail.storage.get_keys then
|
||||||
|
for _, k in ipairs(mail.storage:get_keys()) do
|
||||||
|
if string.sub(k,1,5) == "mail/" then
|
||||||
|
local p = string.sub(k, 6)
|
||||||
|
replace_other_player_message_uuid(p, m, uuid, new_uuid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for p, _ in minetest.get_auth_handler().iterate() do
|
||||||
|
replace_other_player_message_uuid(p, m, uuid, new_uuid)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function fix_player_duplicate_uuids(playername)
|
||||||
|
fix_box_duplicate_uuids(playername, "inbox")
|
||||||
|
fix_box_duplicate_uuids(playername, "outbox")
|
||||||
|
fix_box_duplicate_uuids(playername, "drafts")
|
||||||
|
fix_box_duplicate_uuids(playername, "trash")
|
||||||
|
end
|
||||||
|
|
||||||
-- repair database for uuid doublons
|
-- repair database for uuid doublons
|
||||||
local function repair_storage()
|
local function repair_storage()
|
||||||
-- iterate through players
|
-- iterate through players
|
||||||
|
-- get_keys() was introduced in 5.7
|
||||||
|
if mail.storage.get_keys then
|
||||||
for _, k in ipairs(mail.storage:get_keys()) do
|
for _, k in ipairs(mail.storage:get_keys()) do
|
||||||
if string.sub(k,1,5) == "mail/" then
|
if string.sub(k,1,5) == "mail/" then
|
||||||
local p = string.sub(k, 6)
|
local p = string.sub(k, 6)
|
||||||
fix_duplicate_uuids(p, "inbox")
|
fix_player_duplicate_uuids(p)
|
||||||
fix_duplicate_uuids(p, "outbox")
|
|
||||||
fix_duplicate_uuids(p, "drafts")
|
|
||||||
fix_duplicate_uuids(p, "trash")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
minetest.after(0, function()
|
||||||
|
for p, _ in minetest.get_auth_handler().iterate() do
|
||||||
|
fix_player_duplicate_uuids(p)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mail.migrate()
|
function mail.migrate()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
minetest.register_on_joinplayer(function(player)
|
||||||
minetest.after(2, function(name)
|
minetest.after(2, function(name)
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
local S = minetest.get_translator("mail")
|
-- translation
|
||||||
|
local S = mail.S
|
||||||
|
|
||||||
local has_canonical_name = minetest.get_modpath("canonical_name")
|
local has_canonical_name = minetest.get_modpath("canonical_name")
|
||||||
|
|
||||||
mail.register_on_player_receive(function(name, msg)
|
mail.register_on_player_receive(function(name, msg)
|
||||||
|
BIN
screenshot_1.4.0_1.png
Normal file
BIN
screenshot_1.4.0_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 722 KiB |
BIN
screenshot_1.4.0_2.png
Normal file
BIN
screenshot_1.4.0_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 802 KiB |
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
local FORMNAME = "mail:about"
|
local FORMNAME = "mail:about"
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ local contributors = {
|
|||||||
{ name = "BuckarooBanzay", groups = {"c"} },
|
{ name = "BuckarooBanzay", groups = {"c"} },
|
||||||
{ name = "Chache", groups = {"i"} },
|
{ name = "Chache", groups = {"i"} },
|
||||||
{ name = "Dennis Jenkins", groups = {"c"} },
|
{ name = "Dennis Jenkins", groups = {"c"} },
|
||||||
{ name = "Emojigit", groups = {"i"} },
|
{ name = "Emojigit", groups = {"c", "i"} },
|
||||||
{ name = "Eredin", groups = {"i"} },
|
{ name = "Eredin", groups = {"i"} },
|
||||||
{ name = "fluxionary", groups = {"c"} },
|
{ name = "fluxionary", groups = {"c"} },
|
||||||
{ name = "imre84", groups = {"c"} },
|
{ name = "imre84", groups = {"c"} },
|
||||||
@ -55,7 +55,7 @@ function mail.show_about(name)
|
|||||||
label[0.2,0;Mail]
|
label[0.2,0;Mail]
|
||||||
|
|
||||||
label[0.2,0.5;]] .. S("Provided by mt-mods") .. [[]
|
label[0.2,0.5;]] .. S("Provided by mt-mods") .. [[]
|
||||||
label[0.2,0.9;]] .. S("Version: @1", "1.4.0-dev") .. [[]
|
label[0.2,0.9;]] .. S("Version: @1", "1.5.0-dev") .. [[]
|
||||||
|
|
||||||
box[0,1.5;3,0.45;]] .. mail.get_color("highlighted") .. [[]
|
box[0,1.5;3,0.45;]] .. mail.get_color("highlighted") .. [[]
|
||||||
label[0.2,1.5;]] .. S("Licenses") .. [[]
|
label[0.2,1.5;]] .. S("Licenses") .. [[]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
local FORMNAME = "mail:compose"
|
local FORMNAME = "mail:compose"
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
local FORMNAME = "mail:contacts"
|
local FORMNAME = "mail:contacts"
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
|
|
||||||
function mail.show_drafts(name)
|
function mail.show_drafts(name)
|
||||||
local trash_tab = ""
|
local trash_tab = ""
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
local FORMNAME = "mail:editcontact"
|
local FORMNAME = "mail:editcontact"
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
local FORMNAME = "mail:editmaillist"
|
local FORMNAME = "mail:editmaillist"
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
function mail.show_inbox(name, sortfieldindex, sortdirection, filter)
|
function mail.show_inbox(name, sortfieldindex, sortdirection, filter)
|
||||||
sortfieldindex = tonumber(sortfieldindex or mail.selected_idxs.sortfield[name])
|
sortfieldindex = tonumber(sortfieldindex or mail.selected_idxs.sortfield[name])
|
||||||
@ -77,6 +77,7 @@ function mail.show_inbox(name, sortfieldindex, sortdirection, filter)
|
|||||||
|
|
||||||
local unread_color_enable = mail.get_setting(name, "unreadcolorenable")
|
local unread_color_enable = mail.get_setting(name, "unreadcolorenable")
|
||||||
local cc_color_enable = mail.get_setting(name, "cccolorenable")
|
local cc_color_enable = mail.get_setting(name, "cccolorenable")
|
||||||
|
local mute_list = mail.get_setting(name, "mute_list")
|
||||||
|
|
||||||
if #messages > 0 then
|
if #messages > 0 then
|
||||||
for _, message in ipairs(messages) do
|
for _, message in ipairs(messages) do
|
||||||
@ -103,7 +104,7 @@ function mail.show_inbox(name, sortfieldindex, sortdirection, filter)
|
|||||||
if message.spam then
|
if message.spam then
|
||||||
table.insert(displayed_color, "warning")
|
table.insert(displayed_color, "warning")
|
||||||
end
|
end
|
||||||
if table.indexof(mail.get_setting(name, "mute_list"), message.from) >= 1 then
|
if table.indexof(mute_list, message.from) >= 1 then
|
||||||
table.insert(displayed_color, "muted")
|
table.insert(displayed_color, "muted")
|
||||||
end
|
end
|
||||||
formspec[#formspec + 1] = "," .. mail.get_color(displayed_color)
|
formspec[#formspec + 1] = "," .. mail.get_color(displayed_color)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
local FORMNAME = "mail:maillists"
|
local FORMNAME = "mail:maillists"
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
local FORMNAME = "mail:message"
|
local FORMNAME = "mail:message"
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
function mail.show_outbox(name, sortfieldindex, sortdirection, filter)
|
function mail.show_outbox(name, sortfieldindex, sortdirection, filter)
|
||||||
sortfieldindex = tonumber(sortfieldindex or mail.selected_idxs.sortfield[name])
|
sortfieldindex = tonumber(sortfieldindex or mail.selected_idxs.sortfield[name])
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
local FORMNAME = "mail:selectcontact"
|
local FORMNAME = "mail:selectcontact"
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
local FORMNAME = "mail:settings"
|
local FORMNAME = "mail:settings"
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
local trash_formspec = "size[8.5,11;]" .. mail.theme .. [[
|
local trash_formspec = "size[8.5,11;]" .. mail.theme .. [[
|
||||||
tabheader[0.3,1;boxtab;]] ..
|
tabheader[0.3,1;boxtab;]] ..
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
function mail.compile_contact_list(name, selected, playernames)
|
function mail.compile_contact_list(name, selected, playernames)
|
||||||
-- TODO: refactor this - not just compiles *a* list, but *the* list for the contacts screen (too inflexible)
|
-- TODO: refactor this - not just compiles *a* list, but *the* list for the contacts screen (too inflexible)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
local S = minetest.get_translator("mail")
|
-- translation
|
||||||
|
local S = mail.S
|
||||||
|
|
||||||
local function recursive_expand_recipient_names(sender, list, is_toplevel, recipients, undeliverable)
|
local function recursive_expand_recipient_names(sender, list, is_toplevel, recipients, undeliverable)
|
||||||
for _, name in ipairs(list) do
|
for _, name in ipairs(list) do
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
mail.settings = {
|
mail.settings = {
|
||||||
chat_notifications = {
|
chat_notifications = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
-- translation
|
-- translation
|
||||||
local S = minetest.get_translator("mail")
|
local S = mail.S
|
||||||
|
|
||||||
function mail.time_ago(t)
|
function mail.time_ago(t)
|
||||||
local elapsed = os.time() - t
|
local elapsed = os.time() - t
|
||||||
|
Loading…
x
Reference in New Issue
Block a user