Skip to content

Commit

Permalink
Magic pen (#57)
Browse files Browse the repository at this point in the history
* (#54) Magic pen, nodedefs wip

* (#54) Magic pen, more nodedefs wip

* (#54) Allow defining only copy or paste through API, do not require both

* (#54) Add digiterms, digistuff. Fix lcd, textline

* (#54) Check if copy/paste is defined now that those are optional

* (#54) Fix digistuff panel/touchscreen

* (#54) Fix luacheck. Add default signs. Cleanup digiterm content

* (#54) Travelnet simple implementation

* (#54) Geocache fix wrong infotext

* (#54) Geocache allow owner to copy exact coordinates

* Fix crash if signs not available

* (#54) Allow tool specific storage limits, Magic pen truncate content for signs

* (#54) Add content parsers, fix travelnet reading

* (#54) Fix luac comment parser line matcher

* (#54) Allow "title" comment in addition to "Desc.*"

* (#54) Actually use title grabbed from lcd contents

* (#54) Limit get_content_title to max 40 bytes

* (#62) Magic pen migration to API v2

Co-authored-by: SX <sx@minetest>
  • Loading branch information
S-S-X and SX authored Nov 24, 2020
1 parent 34f3c9e commit fbc3e37
Show file tree
Hide file tree
Showing 19 changed files with 724 additions and 8 deletions.
4 changes: 4 additions & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ read_globals = {
"default",
"pipeworks",
"technic",
"signs",
"signs_api",
"signs_lib",
"display_api",
}
41 changes: 41 additions & 0 deletions magic_pen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## Magic pen basics

Magic pen is made available for copying text content from one node to another.
For example it can be used to copy text from one book to another.

#### Copy content from compatible nodes

Hold tool in your hand and point node that you want to copy content from, hold special or sneak button and left click on node to copy content.
Chat will display confirmation message when content is copied into tool memory.

#### Apply copied content to compatible nodes

Hold tool containing desired content in you hand and point node that you want apply content to.
Left click with tool to apply new settings, chat will display confirmation message when content is applied to pointed node.

## Nodes compatible with Magic pen

r = ability to read
w = ability to write

* mesecons_luacontroller:luacontroller (r/w)
* mesecons_microcontroller:microcontroller (r)
* pipeworks:lua_tube (r/w)
* homedecor:book (r/w)
* travelnet:elevator (r)
* travelnet:travelnet (r)
* travelnet:travelnet_private (r)
* locked_travelnet:travelnet (r)

## Minetest protection checks (default settings)

Protection checks are done automatically for all tool uses, node registration does not need any protection checks.
Tool can be used to read content from protected nodes but it cannot be used to write content to protected nodes.

## Configuration

Magic pen configuration keys with default values (where * is any magic_pen node):

```
metatool:magic_pen:nodes:*:protection_bypass_read = interact
```
55 changes: 55 additions & 0 deletions magic_pen/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
--
-- metatool:magic_pen is in game tool that allows copying text
--

local has_feather = not not minetest.registered_items['mobs:chicken_feather']
local texture = has_feather and 'magic_pen_feather.png' or 'magic_pen_graphite.png'
local ingredient = has_feather and 'mobs:chicken_feather' or 'group:stick'

local recipe = {
{ '', '', 'default:mese_crystal' },
{ '', ingredient, '' },
{ 'default:coal_lump', '', '' }
}

local tool = metatool:register_tool('magic_pen', {
description = 'Magic pen',
name = 'MagicPen',
texture = texture,
recipe = recipe,
settings = {
machine_use_priv = 'server',
storage_size = 1024 * 16,
},
})

tool:ns({
truncate = function(value, length)
if type(value) == 'string' and type(length) == 'number' and #value > length then
value = value:sub(1, length)
end
return value
end,
get_content_title = function(content)
local title = content and content:gmatch("[\t ]*([^\r\n]+)[\r\n]")()
if type(title) == 'string' and #title > 40 then
title = title:sub(1, 40)
end
return title
end,
})

-- nodes
local modpath = minetest.get_modpath('magic_pen')
tool:load_node_definition(dofile(modpath .. '/nodes/lcd.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/book.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/geocache.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/textline.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/digiterms.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/travelnet.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/basic_signs.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/luacontroller.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/microcontroller.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/display_modpack.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/digistuff_panel.lua'))
tool:load_node_definition(dofile(modpath .. '/nodes/digistuff_touchscreen.lua'))
19 changes: 19 additions & 0 deletions magic_pen/mod.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name=magic_pen
description=Provides metatool:magic_pen to copy/paste text content
depends=metatool

# Optional dependencies grouped by modpack
optional_depends="""
mobs_animal,
default,
digistuff,
digiterms,
signs_api, display_api, boards, signs, signs_road,
signs_lib, basic_signs,
geocache,
homedecor_books,
mesecons_luacontroller, mesecons_microcontroller,
pipeworks,
textline,
travelnet,
"""
65 changes: 65 additions & 0 deletions magic_pen/nodes/basic_signs.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
--
-- Register basic_signs for Magic pen
-- https://gitlab.com/VanessaE/basic_signs
--

local nodes = {}

for nodename,_ in pairs(minetest.registered_nodes) do
if nodename:find('^basic_signs:') then
-- Match found, add to registration list
table.insert(nodes, nodename)
end
end
if minetest.registered_nodes["default:sign_wall_wood"] then
table.insert(nodes, "default:sign_wall_wood")
end
if minetest.registered_nodes["default:sign_wall_steel"] then
table.insert(nodes, "default:sign_wall_steel")
end

local truncate = metatool.ns('magic_pen').truncate
local get_content_title = metatool.ns('magic_pen').get_content_title

local paste
if signs_lib then
paste = function(self, node, pos, player, data)
if data.content then
signs_lib.update_sign(pos, { text = truncate(data.content, 512) })
end
end
else
paste = function(self, node, pos, player, data)
if data.content then
local meta = minetest.get_meta(pos)
meta:set_string("text", truncate(data.content, 512))
meta:set_string("infotext", data.content)
end
end
end

local definition = {
name = 'basic_signs',
nodes = nodes,
group = 'text',
protection_bypass_read = "interact",
paste = paste
}

function definition:before_write(pos, player)
return signs_lib.can_modify(pos, player)
end

function definition:copy(node, pos, player)
local meta = minetest.get_meta(pos)
local content = meta:get("text")
local nicename = minetest.registered_nodes[node.name].description or node.name
return {
description = ("%s at %s"):format(nicename, minetest.pos_to_string(pos)),
content = content,
title = get_content_title(content),
source = meta:get("owner"),
}
end

return definition
53 changes: 53 additions & 0 deletions magic_pen/nodes/book.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
--
-- Register books for Magic pen
-- https://gitlab.com/VanessaE/homedecor_modpack/-/tree/master/homedecor_books
--

-- books
local nodes = {}

local bookcolors = {
"red",
"green",
"blue",
"violet",
"grey",
"brown"
}

for _, color in ipairs(bookcolors) do
table.insert(nodes, string.format("homedecor:book_%s", color))
table.insert(nodes, string.format("homedecor:book_open_%s", color))
end
table.insert(nodes, "homedecor:book")
table.insert(nodes, "homedecor:book_open")

local definition = {
name = 'book',
nodes = nodes,
group = 'text',
protection_bypass_read = "interact",
}

function definition:copy(node, pos, player)
local meta = minetest.get_meta(pos)
return {
description = ("%s at %s"):format(node.name, minetest.pos_to_string(pos)),
source = meta:get("owner"),
title = meta:get("title"),
content = meta:get("text"),
}
end

function definition:paste(node, pos, player, data)
local meta = minetest.get_meta(pos)
if data.title then
meta:set_string("title", data.title)
meta:set_string("infotext", data.title)
end
if data.content then
meta:set_string("text", data.content)
end
end

return definition
27 changes: 27 additions & 0 deletions magic_pen/nodes/digistuff_panel.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--
-- Register Digistuff panel for Magic pen
--

local get_content_title = metatool.ns('magic_pen').get_content_title

local definition = {
name = 'digistuff_panel',
nodes = "digistuff:panel",
group = 'text',
protection_bypass_read = "interact",
}

function definition:copy(node, pos, player)
local meta = minetest.get_meta(pos)
local content = meta:get("text")
local title = get_content_title(content)
local nicename = minetest.registered_nodes[node.name].description or node.name
return {
description = ("%s at %s"):format(nicename, minetest.pos_to_string(pos)),
content = content,
title = title,
source = meta:get("owner"),
}
end

return definition
38 changes: 38 additions & 0 deletions magic_pen/nodes/digistuff_touchscreen.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--
-- Register Digistuff Touchscreen for Magic pen
--

local function add_field(t, f)
for k,v in pairs(f) do
if type(v) == "table" then
add_field(t, v)
else
table.insert(t, tostring(k).."="..tostring(v))
end
end
end

local definition = {
name = 'touchscreen',
nodes = "digistuff:touchscreen",
group = 'text',
}

function definition:copy(node, pos, player)
local meta = minetest.get_meta(pos)
local data = minetest.deserialize(meta:get_string("data"))
local content = {}
if type(data) == "table" then
for _,field in ipairs(data) do
add_field(content, field)
end
end
local nicename = minetest.registered_nodes[node.name].description or node.name
return {
description = ("%s at %s"):format(nicename, minetest.pos_to_string(pos)),
content = table.concat(content, "\n"),
source = meta:get("owner"),
}
end

return definition
40 changes: 40 additions & 0 deletions magic_pen/nodes/digiterms.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--
-- Register digiterms nodes for Magic pen
-- https://github.com/pyrollo/digiterms
--

local nodes = {}

for nodename, nodedef in pairs(minetest.registered_nodes) do
if nodename:find('^digiterms:') and nodedef.groups and nodedef.groups.display_api then
-- Match found, add to registration list
table.insert(nodes, nodename)
end
end

local get_content_title = metatool.ns('magic_pen').get_content_title

local definition = {
name = 'digiterms',
nodes = nodes,
group = 'text',
protection_bypass_read = "interact",
}

function definition:copy(node, pos, player)
local meta = minetest.get_meta(pos)
local content = meta:get("display_text")
if type(content) == "string" then
content = content:gsub("(\r?\n)%s+\r?\n","%1")
end
local title = get_content_title(content)
local nicename = minetest.registered_nodes[node.name].description or node.name
return {
description = ("%s at %s"):format(nicename, minetest.pos_to_string(pos)),
content = content,
title = title,
source = meta:get("owner"),
}
end

return definition
Loading

0 comments on commit fbc3e37

Please sign in to comment.