start anew
This commit is contained in:
commit
118ed9f2e6
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.idea*
|
8
.luacheckrc
Normal file
8
.luacheckrc
Normal file
@ -0,0 +1,8 @@
|
||||
-- based on https://gitea.your-land.de/your-land/bugtracker/wiki/luacheck%2C-stylua%2C-pre-commit
|
||||
|
||||
std = "lua51+chat_formspec"
|
||||
|
||||
stds.chat_formspec = {
|
||||
read_globals = {"minetest"},
|
||||
globals = {"chat_formspec"}
|
||||
}
|
26
chatcommands.lua
Normal file
26
chatcommands.lua
Normal file
@ -0,0 +1,26 @@
|
||||
minetest.register_chatcommand("chat_formspec", {
|
||||
params = "[<playername>[,<predefined>]]",
|
||||
description = [[send a player who refuses communication attemps via public chat a predefined formspec to chat
|
||||
playername (optional): will prefill the field of the player to whom the formspec shall be shown
|
||||
predefined (optional): if valid, it will skip the selection formspec and directly jump to the editor for the preset formspec]],
|
||||
privs = {[chat_formspec.priv] = true},
|
||||
func = function(name, paramstr)
|
||||
local context = chat_formspec.get_context(name)
|
||||
local params = string.split(paramstr, ",", true)
|
||||
context.sender = name
|
||||
if params[1] then
|
||||
context.target = minetest.formspec_escape(params[1])
|
||||
end
|
||||
if params[2] then
|
||||
if chat_formspec.preset[params[2]] then
|
||||
context.easy_syntax = chat_formspec.preset[params[2]]
|
||||
else
|
||||
context.easy_syntax = params[2]
|
||||
end
|
||||
else
|
||||
context.easy_syntax = " "
|
||||
end
|
||||
chat_formspec.show_sender_fs(name)
|
||||
return true
|
||||
end
|
||||
})
|
15
context.lua
Normal file
15
context.lua
Normal file
@ -0,0 +1,15 @@
|
||||
-- https://rubenwardy.com/minetest_modding_book/en/players/formspecs.html#contexts
|
||||
local _contexts = {}
|
||||
function chat_formspec.get_context(name)
|
||||
local context = _contexts[name] or {}
|
||||
_contexts[name] = context
|
||||
return context
|
||||
end
|
||||
|
||||
function chat_formspec.delete_context(name)
|
||||
_contexts[name] = nil
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
clear_context(player:get_player_name())
|
||||
end)
|
18
init.lua
Normal file
18
init.lua
Normal file
@ -0,0 +1,18 @@
|
||||
chat_formspec = {}
|
||||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
chat_formspec.priv = minetest.settings:get("chat_formspec.priv") or "server"
|
||||
|
||||
dofile(modpath .. "/context.lua")
|
||||
dofile(modpath .. "/preset_formspecs.lua")
|
||||
dofile(modpath .. "/specs.lua")
|
||||
dofile(modpath .. "/show_receive.lua")
|
||||
dofile(modpath .. "/chatcommands.lua")
|
||||
|
||||
function chat_formspec.update()
|
||||
chat_formspec.sender_template = chat_formspec.create_sender_template()
|
||||
end
|
||||
|
||||
-- update the predefined formspecs (bc I am lazy and use the easy syntax to create the predefined formspecs too)
|
||||
chat_formspec.update()
|
165
license.txt
Normal file
165
license.txt
Normal file
@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
2
mod.conf
Normal file
2
mod.conf
Normal file
@ -0,0 +1,2 @@
|
||||
name = chat_formspec
|
||||
description = allows to send formspecs (predefined or created on the fly) to players
|
11
preset_formspecs.lua
Normal file
11
preset_formspecs.lua
Normal file
@ -0,0 +1,11 @@
|
||||
chat_formspec.preset = {
|
||||
replant_farm = "The public farm is meant for all players. Therefore it is needed that everyone replants " ..
|
||||
"what he takes. Please do so too! Otherwise we will unfortunately have to resort to other means." ..
|
||||
"#I will do" ..
|
||||
"#I won't do" ..
|
||||
"#How to replant?",
|
||||
|
||||
default = "You have shown behavior about which we have some questions for reasons of moderation. " ..
|
||||
"It would be nice if you could answer them. Otherwise we will unfortunately have to resort to other means.#",
|
||||
test = "test :-) #OK"
|
||||
}
|
1
settingtypes.txt
Normal file
1
settingtypes.txt
Normal file
@ -0,0 +1 @@
|
||||
chat_formspec.priv (priv to allow the use of all prefedined formspecs) string bailiff
|
134
show_receive.lua
Normal file
134
show_receive.lua
Normal file
@ -0,0 +1,134 @@
|
||||
local function chat_escape(text) -- remove all control characters to prevent malformed chat messages
|
||||
return string.gsub(text, "%c", "")
|
||||
end
|
||||
|
||||
|
||||
-- show a chat_formspec to a player
|
||||
function chat_formspec.show_to_target(sendername, fs)
|
||||
local sendercontext = chat_formspec.get_context(sendername)
|
||||
local targetname = sendercontext.target
|
||||
if not targetname then
|
||||
minetest.chat_send_player(sendername, "please provide a playername to whom the formspec shall be shown")
|
||||
end
|
||||
local target = minetest.get_player_by_name(targetname)
|
||||
if not target then
|
||||
minetest.chat_send_player(sendername, chat_escape(targetname .. " is not online"))
|
||||
return
|
||||
end
|
||||
if target:get_hp() == 0 then
|
||||
minetest.chat_send_player(sendername, chat_escape(targetname ..
|
||||
" is dead. We cannot send them a formspec without removing their respawn-formspec. Please try again later"))
|
||||
return
|
||||
end
|
||||
minetest.show_formspec(targetname, "chat_formspec:target_fs", fs)
|
||||
local targetcontext = chat_formspec.get_context(targetname)
|
||||
targetcontext.sender = sendername
|
||||
targetcontext.fs = fs
|
||||
minetest.chat_send_player(sendername, chat_escape("formspec send to " .. targetname))
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "chat_formspec:target_fs" then return false end
|
||||
local name = player:get_player_name()
|
||||
local context = chat_formspec.get_context(name)
|
||||
local sendername = context.sender
|
||||
if fields.chat_help then
|
||||
chat_formspec.show_misc(name, "chat_help")
|
||||
elseif fields.replant_help then
|
||||
chat_formspec.show_misc(name, "replant_help")
|
||||
elseif minetest.get_player_by_name(sendername) then
|
||||
local answer = fields.answer or ""
|
||||
minetest.chat_send_player(sendername, minetest.colorize("orange",
|
||||
chat_escape("chat formspec: " .. name .. " answered:")))
|
||||
local msg_func = minetest.registered_chatcommands["msg"].func
|
||||
msg_func(name, sendername .. " " .. answer)
|
||||
end
|
||||
if fields.quit then
|
||||
chat_formspec.delete_context(name)
|
||||
end
|
||||
return true
|
||||
end)
|
||||
|
||||
|
||||
-- show the player a formspec to create a chat_formspec
|
||||
function chat_formspec.show_sender_fs(name)
|
||||
local context = chat_formspec.get_context(name)
|
||||
local fs = chat_formspec.create_sender_fs(context)
|
||||
minetest.show_formspec(name, "chat_formspec:sender_fs", fs)
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "chat_formspec:sender_fs" then return false end
|
||||
local name = player:get_player_name()
|
||||
local context = chat_formspec.get_context(name)
|
||||
|
||||
context.target = fields.target or ""
|
||||
if fields.send then
|
||||
local target_fs = chat_formspec.create_target_fs(context)
|
||||
chat_formspec.show_to_target(name, target_fs)
|
||||
elseif fields.update then
|
||||
context.easy_syntax = fields.easy_syntax or ""
|
||||
chat_formspec.show_sender_fs(name)
|
||||
elseif fields.select and not(fields.key_enter and fields.key_enter_field) then
|
||||
context.easy_syntax = chat_formspec.preset[fields.select] or ""
|
||||
chat_formspec.show_sender_fs(name)
|
||||
end
|
||||
|
||||
if fields.quit then
|
||||
chat_formspec.delete_context(name)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
-- show formspec where you can still customise the text
|
||||
function chat_formspec.show_custom(name)
|
||||
local context = chat_formspec.get_context(name)
|
||||
minetest.show_formspec(name, "chat_formspec:custom", chat_formspec.create_custom_fs(context))
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "chat_formspec:custom" then return false end
|
||||
local name = player:get_player_name()
|
||||
local context = chat_formspec.get_context(name)
|
||||
if fields.target then
|
||||
context.target = fields.target
|
||||
end
|
||||
if fields.back then
|
||||
context.fs = nil
|
||||
context.replacement = nil
|
||||
chat_formspec.show_select(name)
|
||||
elseif fields.change_text then
|
||||
context.replacement = minetest.formspec_escape(fields.change_text_field or "")
|
||||
minetest.show_formspec(name, "chat_formspec:custom", chat_formspec.create_custom_fs(context))
|
||||
elseif fields.send then
|
||||
if not minetest.check_player_privs(name, chat_formspec.priv) then return true end
|
||||
local fs = chat_formspec.create_target_fs(context)
|
||||
chat_formspec.show_to_target(name, fs)
|
||||
end
|
||||
if fields.quit then
|
||||
chat_formspec.delete_context(name)
|
||||
end
|
||||
return true
|
||||
end)
|
||||
|
||||
|
||||
-- help formspecs (how to chat / replant)
|
||||
function chat_formspec.show_misc(name, id)
|
||||
minetest.show_formspec(name, "chat_formspec:misc", chat_formspec.misc_fs[id])
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "chat_formspec:misc" then return end
|
||||
local name = player:get_player_name()
|
||||
local context = chat_formspec.get_context(name)
|
||||
if fields.quit then -- for whatever reason it doesn't work to send another formspec (maybe side effect of quit?)
|
||||
minetest.after(1, function() -- for whatever reason it doesn't work to use 0 (or 0.1)
|
||||
if minetest.get_player_by_name(name) then
|
||||
minetest.show_formspec(name, "chat_formspec:target_fs", context.fs)
|
||||
end
|
||||
end)
|
||||
else
|
||||
minetest.show_formspec(name, "chat_formspec:target_fs", context.fs)
|
||||
end
|
||||
return true
|
||||
end)
|
111
specs.lua
Normal file
111
specs.lua
Normal file
@ -0,0 +1,111 @@
|
||||
function chat_formspec.easy_syntax_to_formspec(context)
|
||||
local fs_def = string.split(context.easy_syntax, "#", false, -1, false)
|
||||
|
||||
local target_template = [[button[11.3,0.3;3,0.8;chat_help;How to chat?]
|
||||
label[0.4,0.7;I (%s) tried to contact you via chat already\, but you did not respond]
|
||||
textarea[0.4,1.6;13.8,4.2;;;%s]
|
||||
]]
|
||||
local fs = string.format(target_template, context.sender, fs_def[1])
|
||||
|
||||
if #fs_def == 1 then -- there were no answer-options provided, so we will create a input field
|
||||
fs = fs .. [[
|
||||
field[0.3,6.4;10.7,0.8;answer;Your answer;]
|
||||
button_exit[11.3,6.4;3,0.8;submit;submit]
|
||||
]]
|
||||
elseif #fs_def == 2 then
|
||||
fs = fs .. string.format("button_exit[5.5,6.4;3,0.8;answer;%s]", fs_def[2])
|
||||
else
|
||||
for i = 2, #fs_def do
|
||||
fs = fs .. string.format("button_exit[%f,6.4;3,0.8;answer;%s]",
|
||||
0.3 + (i-2) * 11 / (#fs_def - 2), fs_def[i])
|
||||
end
|
||||
end
|
||||
return fs
|
||||
end
|
||||
|
||||
|
||||
function chat_formspec.create_sender_template()
|
||||
local dropdown_items = ""
|
||||
for name, _ in pairs(chat_formspec.preset) do
|
||||
dropdown_items = dropdown_items .. name .. ","
|
||||
end
|
||||
dropdown_items = string.sub(dropdown_items, 0, -2)
|
||||
local template = [[
|
||||
formspec_version[6]
|
||||
size[16,12]
|
||||
box[0.8,0.4;14.6,7.7;gray]
|
||||
container[0.8,0.4]
|
||||
%s
|
||||
container_end[]
|
||||
set_focus[target]
|
||||
dropdown[1,10.8;3;select;]] .. dropdown_items .. [[;1;false]
|
||||
button[12.4,10.7;3,0.9;send;Send]
|
||||
textarea[0.8,8.6;14.6,1.8;easy_syntax;change formspec;%s]
|
||||
button[4.7,10.8;3,0.8;update;update]
|
||||
field[8.8,10.9;3,0.8;target;send to player;%s]
|
||||
field_close_on_enter[target;false]
|
||||
]]
|
||||
return template
|
||||
end
|
||||
|
||||
chat_formspec.sender_template = chat_formspec.create_sender_template()
|
||||
|
||||
function chat_formspec.create_sender_fs(context)
|
||||
local target_fs = chat_formspec.easy_syntax_to_formspec(context)
|
||||
local fs = string.format(chat_formspec.sender_template, target_fs, context.easy_syntax, context.target)
|
||||
return fs
|
||||
end
|
||||
|
||||
|
||||
function chat_formspec.create_target_fs(context)
|
||||
local fs = [[formspec_version[2]
|
||||
size[14.6,7.7]
|
||||
set_focus[answer]
|
||||
]]
|
||||
fs = fs .. chat_formspec.easy_syntax_to_formspec(context)
|
||||
return fs
|
||||
end
|
||||
|
||||
chat_formspec.misc_fs = {}
|
||||
chat_formspec.misc_fs.chat_help = [[
|
||||
formspec_version[2]
|
||||
size[15,10]
|
||||
label[6,0.8;How to chat?]
|
||||
label[6,0.8;___________]
|
||||
label[0.3,1.5;On a computer:]
|
||||
label[0.3,1.6;____________]
|
||||
|
||||
textarea[3,1.35;15,4;;;1) close all pop-ups inside minetest by pressing 'ESC'
|
||||
2) Press your 'T' or 'F10' key
|
||||
3) Write the text you want to send to the public chat
|
||||
in case you do not want everyone to see you text, add a '/m playername' in front of you text.
|
||||
only the player with the name you specified will see your text then
|
||||
4) send your Text by pressing 'Enter'
|
||||
|
||||
In case you can't see the chat, try pressing 'F2' to show / hide the chat]
|
||||
|
||||
label[0.3,4.5;On mobile / tablet:]
|
||||
label[0.3,4.6;______________]
|
||||
|
||||
textarea[3,4.345;15,7;;;1) Close all pop-ups inside Minetest by tapping outside of them
|
||||
2) Press the following buttons:
|
||||
|
||||
=>
|
||||
|
||||
4) Write the text you want to send to the public chat
|
||||
in case you do not want everyone to see you text, add a '/m playername' in front of you text.
|
||||
only the player with the name you specified will see your text then
|
||||
5) send your Text by pressing 'Enter'
|
||||
|
||||
In case you can't see chat, try pressing the following buttons
|
||||
|
||||
=>]
|
||||
|
||||
image[3,5.05;0.5,0.75;rare_controls.png]
|
||||
image[4,5;1,1;chat_btn.png]
|
||||
|
||||
image[3,8.05;1,1;gear_icon.png]
|
||||
image[4.5,8.05;1,1;chat_show_btn.png]
|
||||
|
||||
button[6,9;3,0.8;ok;OK]
|
||||
]]
|
Loading…
Reference in New Issue
Block a user