restructuring
0
webmail/.gitignore → .gitignore
vendored
23
.luacheckrc
@ -1,23 +0,0 @@
|
|||||||
unused_args = false
|
|
||||||
allow_defined_top = true
|
|
||||||
|
|
||||||
globals = {
|
|
||||||
"mail",
|
|
||||||
}
|
|
||||||
|
|
||||||
read_globals = {
|
|
||||||
-- Stdlib
|
|
||||||
string = {fields = {"split"}},
|
|
||||||
table = {fields = {"copy", "getn"}},
|
|
||||||
|
|
||||||
-- Minetest
|
|
||||||
"minetest",
|
|
||||||
"vector", "ItemStack",
|
|
||||||
"dump",
|
|
||||||
|
|
||||||
-- Deps
|
|
||||||
"unified_inventory", "default",
|
|
||||||
|
|
||||||
-- optional mods
|
|
||||||
"xban"
|
|
||||||
}
|
|
12
.travis.yml
@ -1,12 +0,0 @@
|
|||||||
language: generic
|
|
||||||
sudo: false
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- luarocks
|
|
||||||
before_install:
|
|
||||||
- luarocks install --local luacheck
|
|
||||||
script:
|
|
||||||
- $HOME/.luarocks/bin/luacheck --no-color .
|
|
||||||
notifications:
|
|
||||||
email: false
|
|
41
README.md
@ -1,15 +1,9 @@
|
|||||||
Mail mod for Minetest
|
Mail mod for Minetest (webmail component)
|
||||||
======
|
======
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/thomasrudin-mt/mail.svg?branch=master)](https://travis-ci.org/thomasrudin-mt/mail)
|
This is the webmail component for the minetest mail mod
|
||||||
|
|
||||||
This is a fork of cheapies mail mod
|
The ingame mod lives here: https://github.com/thomasrudin-mt/mail_mod
|
||||||
|
|
||||||
It adds a mail-system that allows players to send each other messages in-game and via webmail (optional)
|
|
||||||
|
|
||||||
# Docs
|
|
||||||
|
|
||||||
* [Api](./api.md)
|
|
||||||
|
|
||||||
# Screenshots
|
# Screenshots
|
||||||
|
|
||||||
@ -22,12 +16,6 @@ Webmail
|
|||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
## In-game mail mod
|
|
||||||
|
|
||||||
Install it like any other mod: copy the directory to your "worldmods" folder
|
|
||||||
|
|
||||||
## Webmail
|
|
||||||
|
|
||||||
The webmail component runs as webservice and provides the api for the minetest server
|
The webmail component runs as webservice and provides the api for the minetest server
|
||||||
and the website for the webmail componentc
|
and the website for the webmail componentc
|
||||||
|
|
||||||
@ -55,17 +43,9 @@ webmail.key = myserverkey
|
|||||||
webmail.disallow_banned_players = true
|
webmail.disallow_banned_players = true
|
||||||
```
|
```
|
||||||
|
|
||||||
# Commands/Howto
|
|
||||||
|
|
||||||
To access your mail click on the inventory mail button or use the "/mail" command
|
|
||||||
Mails can be deleted, marked as read or unread, replied to and forwarded to another player
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
* None
|
|
||||||
|
|
||||||
# Roadmap
|
# Roadmap
|
||||||
|
|
||||||
My current roadmap:
|
The current roadmap:
|
||||||
* Enhance ingame UI
|
* Enhance ingame UI
|
||||||
* Better ingame notification
|
* Better ingame notification
|
||||||
* Enhance webmail component
|
* Enhance webmail component
|
||||||
@ -78,16 +58,3 @@ Let me know if there are any (there are for sure:)
|
|||||||
# License
|
# License
|
||||||
|
|
||||||
See the "LICENSE" file
|
See the "LICENSE" file
|
||||||
|
|
||||||
# Textures
|
|
||||||
* textures/email_mail.png (https://github.com/rubenwardy/email.git WTFPL)
|
|
||||||
|
|
||||||
# Contributors
|
|
||||||
|
|
||||||
* Cheapie (initial idea/project)
|
|
||||||
* Rubenwardy (lua/ui improvements)
|
|
||||||
|
|
||||||
# Old/Historic stuff
|
|
||||||
* Old forum topic: https://forum.minetest.net/viewtopic.php?t=14464
|
|
||||||
* Old mod: https://cheapiesystems.com/git/mail/
|
|
||||||
|
|
||||||
|
62
api.lua
@ -1,62 +0,0 @@
|
|||||||
-- see: mail.md
|
|
||||||
|
|
||||||
mail.registered_on_receives = {}
|
|
||||||
function mail.register_on_receive(func)
|
|
||||||
mail.registered_on_receives[#mail.registered_on_receives + 1] = func
|
|
||||||
end
|
|
||||||
|
|
||||||
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 sending function, can be invoked with one object argument (new api) or
|
|
||||||
all 4 parameters (old compat version)
|
|
||||||
see: "Mail format" api.md
|
|
||||||
--]]
|
|
||||||
function mail.send(src, dst, subject, body)
|
|
||||||
local m
|
|
||||||
if dst == nil and subject == nil and body == nil then
|
|
||||||
-- new format (one object param)
|
|
||||||
m = src
|
|
||||||
else
|
|
||||||
-- old format
|
|
||||||
m = {}
|
|
||||||
m.src = src
|
|
||||||
m.dst = dst
|
|
||||||
m.subject = subject
|
|
||||||
m.body = body
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
table.insert(messages, 1, {
|
|
||||||
unread = true,
|
|
||||||
sender = m.src,
|
|
||||||
subject = m.subject,
|
|
||||||
body = m.body,
|
|
||||||
time = os.time(),
|
|
||||||
})
|
|
||||||
mail.setMessages(m.dst, messages)
|
|
||||||
|
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
|
||||||
local name = player:get_player_name()
|
|
||||||
if name == m.dst 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))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for i=1, #mail.registered_on_receives do
|
|
||||||
if mail.registered_on_receives[i](m) then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
59
api.md
@ -1,59 +0,0 @@
|
|||||||
|
|
||||||
# Mail format
|
|
||||||
The mail format in the api hooks
|
|
||||||
|
|
||||||
```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
|
|
||||||
Old variant (pre-1.1)
|
|
||||||
```lua
|
|
||||||
mail.send("source name", "destination name", "subject line", "mail body")
|
|
||||||
```
|
|
||||||
|
|
||||||
New variant (1.1+)
|
|
||||||
```lua
|
|
||||||
mail.send({
|
|
||||||
src = "source name",
|
|
||||||
dst = "destination name",
|
|
||||||
subject = "subject line",
|
|
||||||
body = "mail body"
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
# Hooks
|
|
||||||
On-receive mail hook:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
mail.register_on_receive(function(m)
|
|
||||||
-- "m" is an object in the form: "Mail format"
|
|
||||||
end)
|
|
||||||
```
|
|
||||||
|
|
||||||
# internal mail format (on-disk)
|
|
||||||
The mail format on-disk
|
|
||||||
|
|
||||||
> (worldfolder)/mails/(playername).json
|
|
||||||
|
|
||||||
```json
|
|
||||||
[{
|
|
||||||
"unread": true,
|
|
||||||
"sender": "sender name",
|
|
||||||
"subject": "subject name",
|
|
||||||
"body": "main\nmultiline\nbody",
|
|
||||||
"time": 1551258349,
|
|
||||||
"attachments": [
|
|
||||||
"default:stone 99",
|
|
||||||
"default:gold_ingot 99"
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
|
|
||||||
```
|
|
@ -1,27 +0,0 @@
|
|||||||
|
|
||||||
local invmap = {}
|
|
||||||
|
|
||||||
|
|
||||||
mail.getAttachmentInventory = function(playername)
|
|
||||||
return invmap[playername]
|
|
||||||
end
|
|
||||||
|
|
||||||
mail.getAttachmentInventoryName = function(playername)
|
|
||||||
return "mail:" .. playername
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
|
||||||
local name = player:get_player_name()
|
|
||||||
local inv = minetest.create_detached_inventory(mail.getAttachmentInventoryName(name), {})
|
|
||||||
|
|
||||||
invmap[name] = inv
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.register_on_leaveplayer(function(player)
|
|
||||||
local name = player:get_player_name()
|
|
||||||
invmap[name] = nil
|
|
||||||
if minetest.remove_detached_inventory then
|
|
||||||
minetest.remove_detached_inventory(mail.getAttachmentInventoryName(name))
|
|
||||||
end
|
|
||||||
end)
|
|
@ -1,6 +0,0 @@
|
|||||||
minetest.register_chatcommand("mail",{
|
|
||||||
description = "Open the mail interface",
|
|
||||||
func = function(name)
|
|
||||||
mail.show_inbox(name)
|
|
||||||
end
|
|
||||||
})
|
|
@ -1,3 +0,0 @@
|
|||||||
unified_inventory?
|
|
||||||
default?
|
|
||||||
xban2?
|
|
250
gui.lua
@ -1,250 +0,0 @@
|
|||||||
selected_message_idxs = {}
|
|
||||||
|
|
||||||
local theme
|
|
||||||
if minetest.get_modpath("default") then
|
|
||||||
theme = default.gui_bg .. default.gui_bg_img
|
|
||||||
else
|
|
||||||
theme = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
mail.inbox_formspec = "size[8,9;]" .. theme .. [[
|
|
||||||
button_exit[7.5,0;0.5,0.5;quit;X]
|
|
||||||
button[6,1;2,0.5;new;New Message]
|
|
||||||
button[6,2;2,0.5;read;Read]
|
|
||||||
button[6,3;2,0.5;reply;Reply]
|
|
||||||
button[6,4;2,0.5;forward;Forward]
|
|
||||||
button[6,5;2,0.5;delete;Delete]
|
|
||||||
button[6,6;2,0.5;markread;Mark Read]
|
|
||||||
button[6,7;2,0.5;markunread;Mark Unread]
|
|
||||||
button[6,8;2,0.5;about;About]
|
|
||||||
tablecolumns[color;text;text]
|
|
||||||
table[0,0;5.75,9;messages;#999,From,Subject]]
|
|
||||||
|
|
||||||
|
|
||||||
function mail.show_about(name)
|
|
||||||
local formspec = [[
|
|
||||||
size[8,5;]
|
|
||||||
button[7.5,0;0.5,0.5;back;X]
|
|
||||||
label[0,0;Mail]
|
|
||||||
label[0,0.5;By cheapie]
|
|
||||||
label[0,1;http://github.com/cheapie/mail]
|
|
||||||
label[0,1.5;See LICENSE file for license information]
|
|
||||||
label[0,2.5;NOTE: Communication using this system]
|
|
||||||
label[0,3;is NOT guaranteed to be private!]
|
|
||||||
label[0,3.5;Admins are able to view the messages]
|
|
||||||
label[0,4;of any player.]
|
|
||||||
]] .. theme
|
|
||||||
|
|
||||||
minetest.show_formspec(name, "mail:about", formspec)
|
|
||||||
end
|
|
||||||
|
|
||||||
function mail.show_inbox(name)
|
|
||||||
local formspec = { mail.inbox_formspec }
|
|
||||||
local messages = mail.getMessages(name)
|
|
||||||
|
|
||||||
if messages[1] then
|
|
||||||
for idx, message in ipairs(messages) do
|
|
||||||
if message.unread then
|
|
||||||
formspec[#formspec + 1] = ",#FFD700"
|
|
||||||
else
|
|
||||||
formspec[#formspec + 1] = ","
|
|
||||||
end
|
|
||||||
formspec[#formspec + 1] = ","
|
|
||||||
formspec[#formspec + 1] = minetest.formspec_escape(message.sender)
|
|
||||||
formspec[#formspec + 1] = ","
|
|
||||||
if message.subject ~= "" then
|
|
||||||
if string.len(message.subject) > 30 then
|
|
||||||
formspec[#formspec + 1] =
|
|
||||||
minetest.formspec_escape(string.sub(message.subject, 1, 27))
|
|
||||||
formspec[#formspec + 1] = "..."
|
|
||||||
else
|
|
||||||
formspec[#formspec + 1] = minetest.formspec_escape(message.subject)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
formspec[#formspec + 1] = "(No subject)"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if selected_message_idxs[name] then
|
|
||||||
formspec[#formspec + 1] = ";"
|
|
||||||
formspec[#formspec + 1] = tostring(selected_message_idxs[name] + 1)
|
|
||||||
end
|
|
||||||
formspec[#formspec + 1] = "]"
|
|
||||||
else
|
|
||||||
formspec[#formspec + 1] = "]label[2,4.5;No mail]"
|
|
||||||
end
|
|
||||||
minetest.show_formspec(name, "mail:inbox", table.concat(formspec, ""))
|
|
||||||
end
|
|
||||||
|
|
||||||
function mail.show_message(name, msgnumber)
|
|
||||||
local messages = mail.getMessages(name)
|
|
||||||
local message = messages[msgnumber]
|
|
||||||
local formspec = [[
|
|
||||||
size[8,7.2]
|
|
||||||
button[7,0;1,0.5;back;X]
|
|
||||||
label[0,0;From: %s]
|
|
||||||
label[0,0.5;Subject: %s]
|
|
||||||
textarea[0.25,1.25;8,6.25;body;;%s]
|
|
||||||
button[1,6.7;2,1;reply;Reply]
|
|
||||||
button[3,6.7;2,1;forward;Forward]
|
|
||||||
button[5,6.7;2,1;delete;Delete]
|
|
||||||
]] .. theme
|
|
||||||
|
|
||||||
local sender = minetest.formspec_escape(message.sender)
|
|
||||||
local subject = minetest.formspec_escape(message.subject)
|
|
||||||
local body = minetest.formspec_escape(message.body)
|
|
||||||
formspec = string.format(formspec, sender, subject, body)
|
|
||||||
|
|
||||||
minetest.show_formspec(name,"mail:message",formspec)
|
|
||||||
end
|
|
||||||
|
|
||||||
function mail.show_compose(name, defaulttgt, defaultsubj, defaultbody)
|
|
||||||
local formspec = [[
|
|
||||||
size[8,7.2]
|
|
||||||
field[0.25,0.5;4,1;to;To:;%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]
|
|
||||||
button[7,0;1,0.5;cancel;X]
|
|
||||||
button[4.5,6.7;3,1;send;Send]
|
|
||||||
]] .. theme
|
|
||||||
|
|
||||||
formspec = string.format(formspec,
|
|
||||||
minetest.formspec_escape(defaulttgt),
|
|
||||||
minetest.formspec_escape(defaultsubj),
|
|
||||||
minetest.formspec_escape(defaultbody))
|
|
||||||
|
|
||||||
minetest.show_formspec(name, "mail:compose", formspec)
|
|
||||||
end
|
|
||||||
|
|
||||||
function mail.handle_receivefields(player, formname, fields)
|
|
||||||
if formname == "" and fields and fields.quit and minetest.get_modpath("unified_inventory") then
|
|
||||||
unified_inventory.set_inventory_formspec(player, "craft")
|
|
||||||
end
|
|
||||||
|
|
||||||
if formname == "mail:about" then
|
|
||||||
minetest.after(0.5, function()
|
|
||||||
mail.show_inbox(player:get_player_name())
|
|
||||||
end)
|
|
||||||
|
|
||||||
elseif formname == "mail:inbox" then
|
|
||||||
local name = player:get_player_name()
|
|
||||||
local messages = mail.getMessages(name)
|
|
||||||
|
|
||||||
if fields.messages then
|
|
||||||
local evt = minetest.explode_table_event(fields.messages)
|
|
||||||
selected_message_idxs[name] = evt.row - 1
|
|
||||||
if evt.type == "DCL" and messages[selected_message_idxs[name]] then
|
|
||||||
messages[selected_message_idxs[name]].unread = false
|
|
||||||
mail.show_message(name, selected_message_idxs[name])
|
|
||||||
end
|
|
||||||
mail.setMessages(name, messages)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
if fields.read then
|
|
||||||
if messages[selected_message_idxs[name]] then
|
|
||||||
messages[selected_message_idxs[name]].unread = false
|
|
||||||
mail.show_message(name, selected_message_idxs[name])
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif fields.delete then
|
|
||||||
if messages[selected_message_idxs[name]] then
|
|
||||||
table.remove(messages, selected_message_idxs[name])
|
|
||||||
end
|
|
||||||
|
|
||||||
mail.show_inbox(name)
|
|
||||||
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)
|
|
||||||
|
|
||||||
elseif fields.forward and messages[selected_message_idxs[name]] then
|
|
||||||
local message = messages[selected_message_idxs[name]]
|
|
||||||
local fwfooter = "Type your message here.\n\n--Original message follows--\n" ..message.body
|
|
||||||
mail.show_compose(name, "", "Fw: "..message.subject, fwfooter)
|
|
||||||
|
|
||||||
elseif fields.markread then
|
|
||||||
if messages[selected_message_idxs[name]] then
|
|
||||||
messages[selected_message_idxs[name]].unread = false
|
|
||||||
end
|
|
||||||
mail.show_inbox(name)
|
|
||||||
|
|
||||||
elseif fields.markunread then
|
|
||||||
if messages[selected_message_idxs[name]] then
|
|
||||||
messages[selected_message_idxs[name]].unread = true
|
|
||||||
end
|
|
||||||
mail.show_inbox(name)
|
|
||||||
|
|
||||||
elseif fields.new then
|
|
||||||
mail.show_compose(name,"","","Type your message here.")
|
|
||||||
|
|
||||||
elseif fields.quit then
|
|
||||||
if minetest.get_modpath("unified_inventory") then
|
|
||||||
unified_inventory.set_inventory_formspec(player, "craft")
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif fields.about then
|
|
||||||
mail.show_about(name)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
mail.setMessages(name, messages)
|
|
||||||
return true
|
|
||||||
elseif formname == "mail:message" then
|
|
||||||
local name = player:get_player_name()
|
|
||||||
local messages = mail.getMessages(name)
|
|
||||||
|
|
||||||
if fields.back then
|
|
||||||
mail.show_inbox(name)
|
|
||||||
elseif fields.reply 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)
|
|
||||||
elseif fields.forward then
|
|
||||||
local message = messages[selected_message_idxs[name]]
|
|
||||||
local fwfooter = "Type your message here.\n\n--Original message follows--\n" ..message.body
|
|
||||||
mail.show_compose(name, "", "Fw: "..message.subject, fwfooter)
|
|
||||||
elseif fields.delete then
|
|
||||||
if messages[selected_message_idxs[name]] then
|
|
||||||
table.remove(messages,selected_message_idxs[name])
|
|
||||||
end
|
|
||||||
mail.show_inbox(name)
|
|
||||||
end
|
|
||||||
|
|
||||||
mail.setMessages(name, messages)
|
|
||||||
return true
|
|
||||||
elseif formname == "mail:compose" then
|
|
||||||
if fields.send then
|
|
||||||
mail.send({
|
|
||||||
src = player:get_player_name(),
|
|
||||||
dst = fields.to,
|
|
||||||
subject = fields.subject,
|
|
||||||
body = fields.body
|
|
||||||
})
|
|
||||||
end
|
|
||||||
minetest.after(0.5, function()
|
|
||||||
mail.show_inbox(player:get_player_name())
|
|
||||||
end)
|
|
||||||
return true
|
|
||||||
|
|
||||||
elseif fields.mail then
|
|
||||||
mail.show_inbox(player:get_player_name())
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(mail.handle_receivefields)
|
|
||||||
|
|
||||||
|
|
||||||
if minetest.get_modpath("unified_inventory") then
|
|
||||||
mail.receive_mail_message = mail.receive_mail_message ..
|
|
||||||
" or use the mail button in the inventory"
|
|
||||||
mail.read_later_message = mail.read_later_message ..
|
|
||||||
" or by using the mail button in the inventory"
|
|
||||||
|
|
||||||
unified_inventory.register_button("mail", {
|
|
||||||
type = "image",
|
|
||||||
image = "mail_button.png",
|
|
||||||
tooltip = "Mail"
|
|
||||||
})
|
|
||||||
end
|
|
59
hud.lua
@ -1,59 +0,0 @@
|
|||||||
|
|
||||||
local huddata = {}
|
|
||||||
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
|
||||||
local name = player:get_player_name()
|
|
||||||
local data = {}
|
|
||||||
|
|
||||||
data.imageid = player:hud_add({
|
|
||||||
hud_elem_type = "image",
|
|
||||||
name = "MailIcon",
|
|
||||||
position = {x=0.52, y=0.52},
|
|
||||||
text="",
|
|
||||||
scale = {x=1,y=1},
|
|
||||||
alignment = {x=0.5, y=0.5},
|
|
||||||
})
|
|
||||||
|
|
||||||
data.textid = player:hud_add({
|
|
||||||
hud_elem_type = "text",
|
|
||||||
name = "MailText",
|
|
||||||
position = {x=0.55, y=0.52},
|
|
||||||
text= "",
|
|
||||||
scale = {x=1,y=1},
|
|
||||||
alignment = {x=0.5, y=0.5},
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
huddata[name] = data
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.register_on_leaveplayer(function(player)
|
|
||||||
local name = player:get_player_name()
|
|
||||||
huddata[name] = nil
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
|
||||||
mail.hud_update = function(playername, messages)
|
|
||||||
local data = huddata[playername]
|
|
||||||
local player = minetest.get_player_by_name(playername)
|
|
||||||
|
|
||||||
if not data or not player then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local unreadcount = 0
|
|
||||||
for _, message in ipairs(messages) do
|
|
||||||
if message.unread then
|
|
||||||
unreadcount = unreadcount + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if unreadcount == 0 then
|
|
||||||
player:hud_change(data.imageid, "text", "")
|
|
||||||
player:hud_change(data.textid, "text", "")
|
|
||||||
else
|
|
||||||
player:hud_change(data.imageid, "text", "email_mail.png")
|
|
||||||
player:hud_change(data.textid, "text", unreadcount .. " /mail")
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
62
init.lua
@ -1,62 +0,0 @@
|
|||||||
mail = {
|
|
||||||
|
|
||||||
-- mark webmail fork for other mods
|
|
||||||
fork = "webmail",
|
|
||||||
|
|
||||||
-- api version
|
|
||||||
apiversion = 1.1,
|
|
||||||
|
|
||||||
-- mail directory
|
|
||||||
maildir = minetest.get_worldpath().."/mails",
|
|
||||||
|
|
||||||
-- allow item/node attachments
|
|
||||||
allow_attachments = minetest.settings:get("mail.allow_attachments") == "true",
|
|
||||||
|
|
||||||
webmail = {
|
|
||||||
-- disallow banned players in the webmail interface
|
|
||||||
disallow_banned_players = minetest.settings:get("webmail.disallow_banned_players") == "true",
|
|
||||||
|
|
||||||
-- url and key to the webmail server
|
|
||||||
url = minetest.settings:get("webmail.url"),
|
|
||||||
key = minetest.settings:get("webmail.key")
|
|
||||||
},
|
|
||||||
|
|
||||||
tan = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
dofile(MP .. "/chatcommands.lua")
|
|
||||||
dofile(MP .. "/migrate.lua")
|
|
||||||
dofile(MP .. "/attachment.lua")
|
|
||||||
dofile(MP .. "/hud.lua")
|
|
||||||
dofile(MP .. "/storage.lua")
|
|
||||||
dofile(MP .. "/api.lua")
|
|
||||||
dofile(MP .. "/gui.lua")
|
|
||||||
dofile(MP .. "/onjoin.lua")
|
|
||||||
|
|
||||||
-- optional webmail stuff below
|
|
||||||
|
|
||||||
--[[ minetest.conf
|
|
||||||
secure.http_mods = mail
|
|
||||||
webmail.url = http://127.0.0.1:8080
|
|
||||||
webmail.key = myserverkey
|
|
||||||
--]]
|
|
||||||
|
|
||||||
local http = minetest.request_http_api()
|
|
||||||
|
|
||||||
if http then
|
|
||||||
local webmail_url = mail.webmail.url
|
|
||||||
local webmail_key = mail.webmail.key
|
|
||||||
|
|
||||||
if not webmail_url then error("webmail.url is not defined") end
|
|
||||||
if not webmail_key then error("webmail.key is not defined") end
|
|
||||||
|
|
||||||
print("[mail] loading webmail-component with endpoint: " .. webmail_url)
|
|
||||||
dofile(MP .. "/tan.lua")
|
|
||||||
dofile(MP .. "/webmail.lua")
|
|
||||||
mail.webmail_init(http, webmail_url, webmail_key)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- migrate storage
|
|
||||||
mail.migrate()
|
|
24
migrate.lua
@ -1,24 +0,0 @@
|
|||||||
|
|
||||||
-- migrate from mail.db to player-file-based mailbox
|
|
||||||
|
|
||||||
mail.migrate = function()
|
|
||||||
|
|
||||||
local file = io.open(minetest.get_worldpath().."/mail.db", "r")
|
|
||||||
if file then
|
|
||||||
print("[mail] migrating to new per-player storage")
|
|
||||||
minetest.mkdir(mail.maildir)
|
|
||||||
|
|
||||||
local data = file:read("*a")
|
|
||||||
local oldmails = minetest.deserialize(data)
|
|
||||||
file:close()
|
|
||||||
|
|
||||||
for name, oldmessages in pairs(oldmails) do
|
|
||||||
mail.setMessages(name, oldmessages)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- rename file
|
|
||||||
print("[mail] migration done, renaming old mail.db")
|
|
||||||
os.rename(minetest.get_worldpath().."/mail.db", minetest.get_worldpath().."/mail.db.old")
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
19
onjoin.lua
@ -1,19 +0,0 @@
|
|||||||
minetest.register_on_joinplayer(function(player)
|
|
||||||
minetest.after(2, function(name)
|
|
||||||
local messages = mail.getMessages(name)
|
|
||||||
|
|
||||||
local unreadcount = 0
|
|
||||||
|
|
||||||
for _, message in pairs(messages) do
|
|
||||||
if message.unread then
|
|
||||||
unreadcount = unreadcount + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if unreadcount > 0 then
|
|
||||||
minetest.chat_send_player(name,
|
|
||||||
"(" .. unreadcount .. ") You have mail! Type /mail to read")
|
|
||||||
|
|
||||||
end
|
|
||||||
end, player:get_player_name())
|
|
||||||
end)
|
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 955 B After Width: | Height: | Size: 955 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 447 B After Width: | Height: | Size: 447 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 584 B After Width: | Height: | Size: 584 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 925 B After Width: | Height: | Size: 925 B |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 900 B After Width: | Height: | Size: 900 B |
Before Width: | Height: | Size: 791 B After Width: | Height: | Size: 791 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 439 B After Width: | Height: | Size: 439 B |
Before Width: | Height: | Size: 906 B After Width: | Height: | Size: 906 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 706 B After Width: | Height: | Size: 706 B |
Before Width: | Height: | Size: 944 B After Width: | Height: | Size: 944 B |
Before Width: | Height: | Size: 754 B After Width: | Height: | Size: 754 B |
Before Width: | Height: | Size: 459 B After Width: | Height: | Size: 459 B |
Before Width: | Height: | Size: 751 B After Width: | Height: | Size: 751 B |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 372 B After Width: | Height: | Size: 372 B |
Before Width: | Height: | Size: 963 B After Width: | Height: | Size: 963 B |
Before Width: | Height: | Size: 864 B After Width: | Height: | Size: 864 B |
Before Width: | Height: | Size: 665 B After Width: | Height: | Size: 665 B |
Before Width: | Height: | Size: 488 B After Width: | Height: | Size: 488 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 939 B After Width: | Height: | Size: 939 B |
Before Width: | Height: | Size: 357 B After Width: | Height: | Size: 357 B |
Before Width: | Height: | Size: 856 B After Width: | Height: | Size: 856 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 551 B After Width: | Height: | Size: 551 B |
Before Width: | Height: | Size: 550 B After Width: | Height: | Size: 550 B |
Before Width: | Height: | Size: 938 B After Width: | Height: | Size: 938 B |
Before Width: | Height: | Size: 654 B After Width: | Height: | Size: 654 B |
Before Width: | Height: | Size: 477 B After Width: | Height: | Size: 477 B |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 780 B After Width: | Height: | Size: 780 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 959 B After Width: | Height: | Size: 959 B |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 635 B After Width: | Height: | Size: 635 B |
Before Width: | Height: | Size: 757 B After Width: | Height: | Size: 757 B |
Before Width: | Height: | Size: 811 B After Width: | Height: | Size: 811 B |
Before Width: | Height: | Size: 474 B After Width: | Height: | Size: 474 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 925 B After Width: | Height: | Size: 925 B |
Before Width: | Height: | Size: 717 B After Width: | Height: | Size: 717 B |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 732 B After Width: | Height: | Size: 732 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 759 B After Width: | Height: | Size: 759 B |
Before Width: | Height: | Size: 1004 B After Width: | Height: | Size: 1004 B |
Before Width: | Height: | Size: 762 B After Width: | Height: | Size: 762 B |
Before Width: | Height: | Size: 922 B After Width: | Height: | Size: 922 B |