blarghargh
This commit is contained in:
parent
c4abd7288c
commit
fd89fce7a3
269
init.lua
269
init.lua
@ -1,267 +1,8 @@
|
||||
|
||||
local WP = minetest.get_worldpath().."/wiki"
|
||||
local MODPATH = minetest.get_modpath("wiki")
|
||||
|
||||
local internal_pages = {
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".Intro"] = [[
|
||||
Thank you for using the Wiki Mod.
|
||||
wikilib = { }
|
||||
|
||||
This is a mod that allows one to edit pages via a block. You
|
||||
can use it to document interesting places in a server, to provide
|
||||
a place to post griefing reports, or any kind of text you want.
|
||||
|
||||
To create a new page, enter the name in the field at the top of the
|
||||
form, then click "Go". If the page already exists, it's contents will
|
||||
be displayed. Edit the page as you see fit, then click on "Save" to
|
||||
write the changes to disk.
|
||||
|
||||
Please note that page names starting with a dot ('.') are reserved
|
||||
for internal topics such as this one. Users cannot edit/create such
|
||||
pages from the mod interface.
|
||||
|
||||
See also:
|
||||
* [.Tags]
|
||||
* [.License]
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".Tags"] = [[
|
||||
The wiki supports some special tags.
|
||||
|
||||
You can place hyperlinks to other pages in the Wiki, by surrounding
|
||||
text in square brackets (for example, [.Intro]). Such links will
|
||||
appear at the bottom of the form.
|
||||
|
||||
See also:
|
||||
* [.Intro]
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".License"] = [[
|
||||
Wiki Mod for Minetest - License
|
||||
-------------------------------
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
|
||||
See also:
|
||||
* [.Intro]
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".NotFound"] = [[
|
||||
The specified internal page cannot be found. You may want to:
|
||||
|
||||
* Go back to [Main].
|
||||
* Go to [.Intro].
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
}
|
||||
|
||||
local WIKI_FORMNAME = "wiki:wiki"
|
||||
|
||||
local f = io.open(WP.."/.dummy")
|
||||
if f then
|
||||
f:close()
|
||||
else
|
||||
os.execute("mkdir \""..WP.."\"")
|
||||
local f = io.open(WP.."/.dummy", "w")
|
||||
if f then
|
||||
f:write("DO NOT DELETE!!!\n")
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
f = nil
|
||||
|
||||
local function name_to_filename(name)
|
||||
|
||||
name = name:gsub("[^A-Za-z0-9-]", function(c)
|
||||
if c == " " then
|
||||
return "_"
|
||||
else
|
||||
return ("%%%02X"):format(c:byte(1))
|
||||
end
|
||||
end)
|
||||
return name:lower()
|
||||
|
||||
end
|
||||
|
||||
local function filename_to_name(filename)
|
||||
|
||||
filename = name:gsub("_", " "):gsub("%%[0-9a-fA-F][0-9a-fA-F]", function(c)
|
||||
return string.char(tonumber(c:sub(2, 3), 16))
|
||||
end)
|
||||
return filename
|
||||
|
||||
end
|
||||
|
||||
local function find_links(text)
|
||||
local links = { }
|
||||
for link in text:gmatch("%[(.-)%]") do
|
||||
links[#links + 1] = link
|
||||
end
|
||||
return links
|
||||
end
|
||||
|
||||
local function parse_wiki_file(f)
|
||||
local text = ""
|
||||
local links_n = 0
|
||||
for line in f:lines() do
|
||||
text = text..line.."\n"
|
||||
end
|
||||
return text, find_links(text)
|
||||
end
|
||||
|
||||
local function create_wiki_page(name, text)
|
||||
|
||||
if name == "" then return end
|
||||
|
||||
if name:sub(1, 1) == "." then return end
|
||||
|
||||
local fn = WP.."/"..name_to_filename(name)
|
||||
|
||||
local f = io.open(fn, "w")
|
||||
if not f then return end
|
||||
|
||||
local nl = ""
|
||||
|
||||
if text:sub(-1) ~= "\n" then nl = "\n" end
|
||||
|
||||
f:write(text..nl)
|
||||
|
||||
f:close()
|
||||
|
||||
end
|
||||
|
||||
local function get_wiki_page(name, player)
|
||||
|
||||
if name == "" then name = "Main" end
|
||||
|
||||
local text, links
|
||||
|
||||
if name:sub(1, 1) == "." then
|
||||
|
||||
text = internal_pages[name] or internal_pages[".NotFound"]
|
||||
links = find_links(text)
|
||||
|
||||
else
|
||||
|
||||
local fn = WP.."/"..name_to_filename(name)
|
||||
|
||||
local f = io.open(fn)
|
||||
|
||||
if f then
|
||||
text, links = parse_wiki_file(f)
|
||||
f:close()
|
||||
else
|
||||
if name == "Main" then
|
||||
text = internal_pages[".Intro"]
|
||||
links = find_links(text)
|
||||
else
|
||||
text = "This page does not exist yet."
|
||||
links = { }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local buttons = ""
|
||||
local bx = 0
|
||||
local by = 7.5
|
||||
|
||||
local esc = minetest.formspec_escape
|
||||
|
||||
for i, link in ipairs(links) do
|
||||
if (i % 5) == 0 then
|
||||
bx = 0
|
||||
by = by + 0.3
|
||||
end
|
||||
link = esc(link)
|
||||
buttons = buttons..(("button[%f,%f;2.4,0.3;page_%s;%s]"):format(bx, by, link, link))
|
||||
bx = bx + 2.4
|
||||
end
|
||||
|
||||
local toolbar
|
||||
|
||||
if minetest.check_player_privs(player, {wiki=true}) then
|
||||
toolbar = "button[0,9;2.4,1;save;Save]"
|
||||
else
|
||||
toolbar = "label[0,9;You are not authorized to edit the wiki.]"
|
||||
end
|
||||
|
||||
return ("size[12,10]"
|
||||
.. "field[0,1;11,1;page;Page;"..esc(name).."]"
|
||||
.. "button[11,1;1,0.5;go;Go]"
|
||||
.. "textarea[0,2;12,6;text;"..esc(name)..";"..esc(text).."]"
|
||||
.. buttons
|
||||
.. toolbar
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
local function show_wiki_page(player, name)
|
||||
local formspec = get_wiki_page(name, player)
|
||||
minetest.show_formspec(player, WIKI_FORMNAME, formspec)
|
||||
end
|
||||
|
||||
minetest.register_node("wiki:wiki", {
|
||||
description = "Wiki",
|
||||
tiles = { "default_wood.png", "default_wood.png", "default_bookshelf.png" },
|
||||
groups = { choppy=3, oddly_breakable_by_hand=2, flammable=3 },
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", "Wiki")
|
||||
end,
|
||||
on_rightclick = function(pos, node, clicker, itemstack)
|
||||
if clicker then
|
||||
show_wiki_page(clicker:get_player_name(), "Main")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_privilege("wiki", {
|
||||
description = "Allow editing wiki pages",
|
||||
give_to_singleplayer = true,
|
||||
})
|
||||
|
||||
local BS = "default:bookshelf"
|
||||
local BSL = { BS, BS, BS }
|
||||
minetest.register_craft({
|
||||
output = "wiki:wiki",
|
||||
recipe = { BSL, BSL, BSL },
|
||||
})
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if (not formname) or (formname ~= WIKI_FORMNAME) then return end
|
||||
local plname = player:get_player_name()
|
||||
if fields.save then
|
||||
create_wiki_page(fields.page, fields.text)
|
||||
show_wiki_page(plname, fields.page)
|
||||
elseif fields.go then
|
||||
show_wiki_page(plname, fields.page)
|
||||
elseif fields.back then
|
||||
show_wiki_page(plname, prev)
|
||||
else
|
||||
for k in pairs(fields) do
|
||||
if type(k) == "string" then
|
||||
local name = k:match("^page_(.*)")
|
||||
if name then
|
||||
show_wiki_page(plname, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
dofile(MODPATH.."/strfile.lua")
|
||||
dofile(MODPATH.."/wikilib.lua")
|
||||
dofile(MODPATH.."/internal.lua")
|
||||
|
130
internal.lua
Normal file
130
internal.lua
Normal file
@ -0,0 +1,130 @@
|
||||
|
||||
wikilib.internal_pages = {
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".Intro"] = [[
|
||||
Thank you for using the Wiki Mod.
|
||||
|
||||
This is a mod that allows one to edit pages via a block. You
|
||||
can use it to document interesting places in a server, to provide
|
||||
a place to post griefing reports, or any kind of text you want.
|
||||
|
||||
To create a new page, enter the name in the field at the top of the
|
||||
form, then click "Go". If the page already exists, it's contents will
|
||||
be displayed. Edit the page as you see fit, then click on "Save" to
|
||||
write the changes to disk.
|
||||
|
||||
Please note that page names starting with a dot ('.') are reserved
|
||||
for internal topics such as this one. Users cannot edit/create such
|
||||
pages from the mod interface.
|
||||
|
||||
See also:
|
||||
* [.Tags]
|
||||
* [.License]
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".Tags"] = [[
|
||||
The wiki supports some special tags.
|
||||
|
||||
You can place hyperlinks to other pages in the Wiki, by surrounding
|
||||
text in square brackets (for example, [.Intro]). Such links will
|
||||
appear at the bottom of the form.
|
||||
|
||||
See also:
|
||||
* [.Intro]
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".License"] = [[
|
||||
|
||||
Copyright (c) 2013, Diego Martínez
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
* Go to [.Intro].
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".NotFound_Internal"] = [[
|
||||
The specified internal page cannot be found. You may want to:
|
||||
|
||||
* Back to [Main].
|
||||
* Go to [.Intro].
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".NotFound"] = [[
|
||||
This page does not exist yet.
|
||||
|
||||
* Back to [Main].
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".BadPageName"] = [[
|
||||
The page name you entered is wrong. See [.Page Names] for more info.
|
||||
|
||||
* Back to [Main].
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".Help Index"] = [[
|
||||
* [.Page Names]
|
||||
* [.User Pages]
|
||||
|
||||
* Back to [Main].
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".Page Names"] = [[
|
||||
Page names must be in any of the following formats:
|
||||
<pagename>
|
||||
Display global page <pagename>.
|
||||
:<n>
|
||||
Display page <n> from your user space. <n> must be a number between
|
||||
0 and 9. See [.User Pages] for more info.
|
||||
:
|
||||
This is equivalent to ":0" (shows your private page).
|
||||
:<user>:<n>
|
||||
Display page "Page Name" from the specified user's space. Note that page
|
||||
number 0 is never accessible this way, even if you specify yourself as
|
||||
<user>.
|
||||
|
||||
* Back to [.Help Index].
|
||||
* Back to [Main].
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
[".User Pages"] = [[
|
||||
Users can have up to 10 pages in their "user space", numbered 0-9. These pages
|
||||
are accessed through the special page names ":<n>", and ":<user>:<n>". Page 0
|
||||
is your private page. This page is not accessible to anyone but you. You can
|
||||
use it to write down secret locations, etc.
|
||||
|
||||
* Back to [.Help Index].
|
||||
* Back to [Main].
|
||||
]],
|
||||
----------------------------------------------------------------
|
||||
----------------------------------------------------------------
|
||||
}
|
28
strfile.lua
Normal file
28
strfile.lua
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
strfile = { }
|
||||
|
||||
function strfile.open(s)
|
||||
return {
|
||||
_buf = s,
|
||||
_pos = 1,
|
||||
_readline = function(self)
|
||||
if self._pos == nil then
|
||||
return nil
|
||||
end
|
||||
local nl = self._buf:find("\n", self._pos, true)
|
||||
local line
|
||||
if nl then
|
||||
line = self._buf:sub(self._pos, nl - 1)
|
||||
nl = nl + 1
|
||||
else
|
||||
line = self._buf:sub(self._pos)
|
||||
end
|
||||
self._pos = nl
|
||||
return line
|
||||
end,
|
||||
lines = function(self)
|
||||
return self._readline, self, true
|
||||
end,
|
||||
close = function(self) end,
|
||||
}
|
||||
end
|
212
wikilib.lua
Normal file
212
wikilib.lua
Normal file
@ -0,0 +1,212 @@
|
||||
|
||||
local WP = minetest.get_worldpath().."/wiki"
|
||||
|
||||
local WIKI_FORMNAME = "wiki:wiki"
|
||||
|
||||
local WIN32, DIR_SEP
|
||||
|
||||
if os.getenv("WINDIR") then
|
||||
WIN32 = true
|
||||
DIR_SEP = "\\"
|
||||
else
|
||||
WIN32 = false
|
||||
DIR_SEP = "/"
|
||||
end
|
||||
|
||||
local function mkdir(dir)
|
||||
local f = io.open(dir..DIR_SEP..".dummy")
|
||||
if f then
|
||||
f:close()
|
||||
else
|
||||
if WIN32 then
|
||||
dir = dir:gsub("/", "\\")
|
||||
else
|
||||
dir = dir:gsub("\\", "/")
|
||||
end
|
||||
os.execute("mkdir \""..dir.."\"")
|
||||
local f = io.open(dir..DIR_SEP..".dummy", "w")
|
||||
if f then
|
||||
f:write("DO NOT DELETE!!!\n")
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mkdir(WP)
|
||||
mkdir(WP.."/users")
|
||||
|
||||
local function name_to_filename(name)
|
||||
|
||||
name = name:gsub("[^A-Za-z0-9-]", function(c)
|
||||
if c == " " then
|
||||
return "_"
|
||||
else
|
||||
return ("%%%02X"):format(c:byte(1))
|
||||
end
|
||||
end)
|
||||
return name:lower()
|
||||
|
||||
end
|
||||
|
||||
local function get_page_path(name, player) --> path, is_file
|
||||
|
||||
if name:sub(1, 1) == "." then
|
||||
local text = wikilib.internal_pages[name] or wikilib.internal_pages[".NotFound_Internal"]
|
||||
return text, false
|
||||
elseif name:sub(1, 1) == ":" then
|
||||
if name:match("^:[0-9]?$") then
|
||||
local n = tonumber(name:sub(2,2)) or 0
|
||||
path = "users/"..player.."/page"..n
|
||||
mkdir(WP.."/users/"..player)
|
||||
elseif name:match("^:.-:[1-9]$") then
|
||||
local user, n = name:match("^:(.-):([1-9])$")
|
||||
path = "users/"..user.."/page"..n
|
||||
mkdir(WP.."/users/"..user)
|
||||
else
|
||||
return wikilib.internal_pages[".BadPageName"], false
|
||||
end
|
||||
else
|
||||
path = name_to_filename(name)
|
||||
end
|
||||
|
||||
return WP.."/"..path, true
|
||||
|
||||
end
|
||||
|
||||
local function find_links(lines) --> links
|
||||
local links = { }
|
||||
local links_n = 0
|
||||
for _,line in ipairs(lines) do
|
||||
for link in line:gmatch("%[(.-)%]") do
|
||||
links_n = links_n + 1
|
||||
links[links_n] = link
|
||||
end
|
||||
end
|
||||
return links
|
||||
end
|
||||
|
||||
local function load_page(name, player) --> text, links
|
||||
local path, is_file = get_page_path(name, player)
|
||||
local f
|
||||
if is_file then
|
||||
f = io.open(path)
|
||||
if not f then
|
||||
f = strfile.open(wikilib.internal_pages[".NotFound"])
|
||||
end
|
||||
else
|
||||
f = strfile.open(path)
|
||||
end
|
||||
local lines = { }
|
||||
local lines_n = 0
|
||||
for line in f:lines() do
|
||||
lines_n = lines_n + 1
|
||||
lines[lines_n] = line
|
||||
end
|
||||
f:close()
|
||||
local text = table.concat(lines, "\n")
|
||||
local links = find_links(lines)
|
||||
return text, links
|
||||
end
|
||||
|
||||
local function save_page(name, player, text)
|
||||
|
||||
local path, is_file = get_page_path(name, player)
|
||||
|
||||
if not is_file then return end
|
||||
|
||||
local f = io.open(path, "w")
|
||||
if not f then return end
|
||||
|
||||
f:write(text)
|
||||
|
||||
f:close()
|
||||
|
||||
end
|
||||
|
||||
local esc = minetest.formspec_escape
|
||||
|
||||
local function show_wiki_page(player, name)
|
||||
|
||||
if name == "" then name = "Main" end
|
||||
|
||||
local text, links = load_page(name, player)
|
||||
|
||||
local buttons = ""
|
||||
local bx = 0
|
||||
local by = 7.5
|
||||
|
||||
for i, link in ipairs(links) do
|
||||
if (i % 5) == 0 then
|
||||
bx = 0
|
||||
by = by + 0.3
|
||||
end
|
||||
link = esc(link)
|
||||
buttons = buttons..(("button[%f,%f;2.4,0.3;page_%s;%s]"):format(bx, by, link, link))
|
||||
bx = bx + 2.4
|
||||
end
|
||||
|
||||
local toolbar
|
||||
|
||||
if is_user or minetest.check_player_privs(player, {wiki=true}) then
|
||||
toolbar = "button[0,9;2.4,1;save;Save]"
|
||||
else
|
||||
toolbar = "label[0,9;You are not authorized to edit this page.]"
|
||||
end
|
||||
|
||||
minetest.show_formspec(player, WIKI_FORMNAME, ("size[12,10]"
|
||||
.. "field[0,1;11,1;page;Page;"..esc(name).."]"
|
||||
.. "button[11,1;1,0.5;go;Go]"
|
||||
.. "textarea[0,2;12,6;text;"..esc(name)..";"..esc(text).."]"
|
||||
.. buttons
|
||||
.. toolbar
|
||||
))
|
||||
|
||||
end
|
||||
|
||||
minetest.register_node("wiki:wiki", {
|
||||
description = "Wiki",
|
||||
tiles = { "default_wood.png", "default_wood.png", "default_bookshelf.png" },
|
||||
groups = { choppy=3, oddly_breakable_by_hand=2, flammable=3 },
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", "Wiki")
|
||||
end,
|
||||
on_rightclick = function(pos, node, clicker, itemstack)
|
||||
if clicker then
|
||||
show_wiki_page(clicker:get_player_name(), "Main")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_privilege("wiki", {
|
||||
description = "Allow editing wiki pages",
|
||||
give_to_singleplayer = true,
|
||||
})
|
||||
|
||||
local BS = "default:bookshelf"
|
||||
local BSL = { BS, BS, BS }
|
||||
minetest.register_craft({
|
||||
output = "wiki:wiki",
|
||||
recipe = { BSL, BSL, BSL },
|
||||
})
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if (not formname) or (formname ~= WIKI_FORMNAME) then return end
|
||||
local plname = player:get_player_name()
|
||||
if fields.save then
|
||||
save_page(fields.page, plname, fields.text)
|
||||
show_wiki_page(plname, fields.page)
|
||||
elseif fields.go then
|
||||
show_wiki_page(plname, fields.page)
|
||||
else
|
||||
for k in pairs(fields) do
|
||||
if type(k) == "string" then
|
||||
local name = k:match("^page_(.*)")
|
||||
if name then
|
||||
show_wiki_page(plname, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
Loading…
x
Reference in New Issue
Block a user