mirror of
https://github.com/mt-mods/home_workshop_modpack.git
synced 2024-11-15 23:20:22 +01:00
add limited network functionality
This commit is contained in:
parent
8267c4d71f
commit
aca2f138a8
|
@ -25,7 +25,7 @@ computers.sandbox.default_env = {}
|
|||
|
||||
os.clock os.difftime os.time
|
||||
|
||||
string.byte string.char string.format
|
||||
string.byte string.char
|
||||
string.len string.lower string.reverse
|
||||
string.sub string.upper
|
||||
|
||||
|
@ -130,4 +130,13 @@ function computers.api.chat_send_player(player, msg)
|
|||
local name = player
|
||||
if type(name) == "userdata" then name = player:get_player_name() end
|
||||
minetest.chat_send_player(name, msg)
|
||||
end
|
||||
|
||||
--basically for dev usage only
|
||||
function computers.api.benchmark(func, ...)
|
||||
local start_time = minetest.get_us_time()
|
||||
for i=1, 1000 do
|
||||
func(...)
|
||||
end
|
||||
minetest.chat_send_all(minetest.get_us_time()-start_time)
|
||||
end
|
7
computers/commands/net/conf.json
Normal file
7
computers/commands/net/conf.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "net",
|
||||
"license": "MIT",
|
||||
"version": 0.1,
|
||||
"engine": 0.43,
|
||||
"help": "configuration related to networking"
|
||||
}
|
64
computers/commands/net/init.lua
Normal file
64
computers/commands/net/init.lua
Normal file
|
@ -0,0 +1,64 @@
|
|||
function net(pos, input, data)
|
||||
input = input or ""
|
||||
local lookup = {
|
||||
list = function(param)
|
||||
if param == "-ids" then
|
||||
return table.concat(computers.networks.get_networks_in_area(pos), " ")
|
||||
elseif not param or param == "" then
|
||||
return table.concat(computers.networks.get_net_names_in_area(pos), " ")
|
||||
else
|
||||
return "invalid sub command"
|
||||
end
|
||||
end,
|
||||
join = function(param)
|
||||
local id = computers.networks.get_id_by_net_name(data.player, param)
|
||||
if not id then
|
||||
return "invalid network name"
|
||||
elseif minetest.get_meta(pos):get("net_id") then
|
||||
return "already joined to a network"
|
||||
else
|
||||
local _, networks = computers.networks.get_net_names_in_area(pos)
|
||||
if not networks[param] then return "network not in range" end
|
||||
minetest.get_meta(pos):set_string("net_id", id)
|
||||
local status = computers.networks.add_device(id, pos)
|
||||
if status then return "joined network " .. param else return "network join failed" end
|
||||
end
|
||||
end,
|
||||
leave = function(param)
|
||||
local id = minetest.get_meta(pos):get("net_id")
|
||||
if id then
|
||||
computers.networks.remove_device(id, pos)
|
||||
return "removed device from network " .. computers.networks.get_net_name(id)
|
||||
else
|
||||
return "not currently connected to any network"
|
||||
end
|
||||
end,
|
||||
status = function(param)
|
||||
local id = minetest.get_meta(pos):get("net_id")
|
||||
if id then
|
||||
return "connected to network " .. computers.networks.get_net_name(id)
|
||||
else
|
||||
return "not connected to any network"
|
||||
end
|
||||
end,
|
||||
dns = function(param)
|
||||
if minetest.get_item_group(minetest.get_node(pos).name, "computers_server") == 0 then
|
||||
return "command only available to servers"
|
||||
end
|
||||
if not param or param == "" then return "invalid or missing input" end
|
||||
if param:match("%W") then return "only alphanumerics allowed" end
|
||||
local id = minetest.get_meta(pos):get("net_id")
|
||||
if id then
|
||||
computers.networks.set_dns(id, pos, param)
|
||||
return "created dns record"
|
||||
else
|
||||
return "not connected to network"
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
if not lookup[input:split(" ")[1]] then return "invalid sub command" end
|
||||
return lookup[input:split(" ")[1]](input:split(" ", 1)[2])
|
||||
end
|
||||
|
||||
return net
|
|
@ -11,4 +11,211 @@ old_node = minetest.registered_nodes["computers:shefriendSOO_off"]
|
|||
old_node.groups.not_in_creative_inventory = nil
|
||||
minetest.override_item("computers:shefriendSOO_off", {
|
||||
groups = old_node.groups
|
||||
})
|
||||
|
||||
old_node = minetest.registered_nodes["computers:server_on"]
|
||||
old_node.groups.computers_server = 1
|
||||
minetest.override_item("computers:server_on", {
|
||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||
computers.load_gui(pos, node, clicker)
|
||||
end,
|
||||
groups = old_node.groups
|
||||
})
|
||||
|
||||
minetest.override_item("computers:router", {
|
||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||
local formspec = {
|
||||
formspec_version = 4,
|
||||
{
|
||||
type = "size",
|
||||
w = 10,
|
||||
h = 5,
|
||||
},
|
||||
{
|
||||
type = "no_prepend"
|
||||
},
|
||||
{
|
||||
type = "bgcolor",
|
||||
bgcolor = "black",
|
||||
fullscreen = "neither"
|
||||
},
|
||||
{
|
||||
type = "background9",
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 10,
|
||||
h = 5,
|
||||
texture_name = "kuto_button.png^[combine:16x16^[noalpha^[colorize:#ffffff70",
|
||||
auto_clip = false,
|
||||
middle_x = 4,
|
||||
middle_y = 4,
|
||||
},
|
||||
{
|
||||
type = "hypertext",
|
||||
name = "label",
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 10,
|
||||
h = 2,
|
||||
text = "<global valign=middle><center><big>Choose Option Below</big></center>",
|
||||
},
|
||||
{
|
||||
type = "button",
|
||||
x = 0.5,
|
||||
y = 3.5,
|
||||
w = 4,
|
||||
h = 1,
|
||||
name = "newnetwork_btn",
|
||||
label = "New Network",
|
||||
on_event = function(form, player, element, value, fields)
|
||||
if element.label == "New Network" then
|
||||
element.label = "Submit"
|
||||
table.remove(form, computers.formspec.get_index_by_name(form, "existingnetwork_btn"))
|
||||
form[computers.formspec.get_index_by_name(form, "label")].text = [[
|
||||
<global valign=middle><center><big>Enter New Network Name</big></center>
|
||||
]]
|
||||
table.insert(
|
||||
form,
|
||||
{
|
||||
type = "box",
|
||||
x = 3,
|
||||
y = 1.75,
|
||||
w = 4,
|
||||
h = 1,
|
||||
color = "#ffffff"
|
||||
}
|
||||
)
|
||||
table.insert(
|
||||
form,
|
||||
{
|
||||
type = "field",
|
||||
x = 3,
|
||||
y = 1.75,
|
||||
w = 4,
|
||||
h = 1,
|
||||
name = "id_field",
|
||||
close_on_enter = false,
|
||||
props = {
|
||||
border = false,
|
||||
},
|
||||
}
|
||||
)
|
||||
else
|
||||
if fields.id_field == "" and not computers.formspec.get_index_by_name(form, "warning") then
|
||||
table.insert(
|
||||
form,
|
||||
{
|
||||
type = "hypertext",
|
||||
name = "warning",
|
||||
x = 5.5,
|
||||
y = 3.5,
|
||||
w = 4,
|
||||
h = 1,
|
||||
text = [[
|
||||
<global valign=middle>
|
||||
<center><style color=red>empty or invalid network name</style></center>
|
||||
]]
|
||||
}
|
||||
)
|
||||
elseif fields.id_field ~= "" then
|
||||
local status, id = computers.networks.create(player, fields.id_field)
|
||||
if status then
|
||||
form = nil
|
||||
minetest.get_meta(pos):set_string("net_id", id)
|
||||
computers.networks.add_device(id, pos)
|
||||
computers.api.chat_send_player(player, "network " .. fields.id_field .. " created")
|
||||
computers.formspec.close_formspec(player)
|
||||
elseif not computers.formspec.get_index_by_name(form, "warning") then
|
||||
table.insert(
|
||||
form,
|
||||
{
|
||||
type = "hypertext",
|
||||
name = "warning",
|
||||
x = 5.5,
|
||||
y = 3.5,
|
||||
w = 4,
|
||||
h = 1,
|
||||
text = [[
|
||||
<global valign=middle>
|
||||
<center><style color=red>empty or invalid network name</style></center>
|
||||
]]
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
--minetest.chat_send_all("test")
|
||||
|
||||
if form then return form end
|
||||
end,
|
||||
props = {
|
||||
border = false,
|
||||
bgimg = "kuto_button.png^[combine:16x16^[noalpha^[colorize:#ffffff70",
|
||||
bgimg_hovered = "kuto_button.png^[combine:16x16^[noalpha^[colorize:#ffffff90",
|
||||
bgimg_middle = "4,4",
|
||||
}
|
||||
},
|
||||
{
|
||||
type = "button",
|
||||
x = 5.5,
|
||||
y = 3.5,
|
||||
w = 4,
|
||||
h = 1,
|
||||
name = "existingnetwork_btn",
|
||||
label = "Existing Network",
|
||||
on_event = function(form, player, element, value, fields)
|
||||
if element.label == "Existing Network" then
|
||||
element.label = "Submit"
|
||||
table.remove(form, computers.formspec.get_index_by_name(form, "newnetwork_btn"))
|
||||
form[computers.formspec.get_index_by_name(form, "label")].text = [[
|
||||
<global valign=middle><center>Enter Network</center>
|
||||
]]
|
||||
table.insert(
|
||||
form,
|
||||
{
|
||||
type = "box",
|
||||
x = 3,
|
||||
y = 1.75,
|
||||
w = 4,
|
||||
h = 1,
|
||||
color = "#ffffff"
|
||||
}
|
||||
)
|
||||
table.insert(
|
||||
form,
|
||||
{
|
||||
type = "field",
|
||||
x = 3,
|
||||
y = 1.75,
|
||||
w = 4,
|
||||
h = 1,
|
||||
name = "id_field",
|
||||
close_on_enter = false,
|
||||
props = {
|
||||
border = false,
|
||||
},
|
||||
}
|
||||
)
|
||||
else
|
||||
minetest.chat_send_all("submitted")
|
||||
end
|
||||
|
||||
return form
|
||||
end,
|
||||
props = {
|
||||
border = false,
|
||||
bgimg = "kuto_button.png^[combine:16x16^[noalpha^[colorize:#ffffff70",
|
||||
bgimg_hovered = "kuto_button.png^[combine:16x16^[noalpha^[colorize:#ffffff90",
|
||||
bgimg_middle = "4,4",
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
if minetest.get_meta(pos):get("net_id") then
|
||||
local net_name = computers.networks.get_net_name(minetest.get_meta(pos):get("net_id"))
|
||||
computers.api.chat_send_player(clicker, "router attached to network: " .. net_name)
|
||||
else
|
||||
computers.formspec.show_formspec(clicker, "computers:router", formspec)
|
||||
end
|
||||
end
|
||||
})
|
|
@ -75,6 +75,8 @@ function computers.formspec.convert_to_ast(form)
|
|||
return fs
|
||||
end
|
||||
|
||||
local forms = {}
|
||||
|
||||
function computers.formspec.show_formspec(player, formname, fs)
|
||||
local playername = player
|
||||
local formspec = fs
|
||||
|
@ -87,11 +89,21 @@ function computers.formspec.show_formspec(player, formname, fs)
|
|||
formspec = formspec_ast.unparse(computers.formspec.convert_to_ast(fs))
|
||||
end
|
||||
|
||||
forms[formname] = true
|
||||
|
||||
minetest.show_formspec(playername, formname, formspec)
|
||||
end
|
||||
|
||||
function computers.formspec.close_formspec(player, formname)
|
||||
local name = player
|
||||
if type(name) == "userdata" then name = player:get_player_name() end
|
||||
|
||||
minetest.close_formspec(name, formname or "")
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "computers:gui" then return end
|
||||
--if formname ~= "computers:gui" then return end
|
||||
if not forms[formname] then return end
|
||||
local pname = player:get_player_name()
|
||||
|
||||
if fields.quit then computers.formspec.registered_kast[pname] = nil return end
|
||||
|
@ -117,7 +129,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
btn_override or keys[1]
|
||||
)
|
||||
|
||||
--minetest.chat_send_all(keys[1])
|
||||
--minetest.chat_send_all(btn_override or keys[1])
|
||||
--minetest.chat_send_all(fields[keys[1]])
|
||||
|
||||
if element and element.on_event then
|
||||
|
|
|
@ -243,8 +243,17 @@ function computers.gui.load(pos, node, clicker)
|
|||
border = false,
|
||||
},
|
||||
on_event = function(form, player, element, value, fields)
|
||||
--minetest.chat_send_all("url entered")
|
||||
computers.api.chat_send_player(player, "[computers]: networking not currently supported")
|
||||
local id = minetest.get_meta(pos):get("net_id")
|
||||
if id then
|
||||
local status, data = computers.networks.resolve_url(id, pos, value)
|
||||
if status and data then
|
||||
local cindex = futil.get_index_by_name(form, "browser_ctn")
|
||||
local eindex = futil.get_index_by_name(form[cindex], "browser_content")
|
||||
form[cindex][eindex].text = data
|
||||
end
|
||||
else
|
||||
computers.api.chat_send_player(player, "[computers]: not attached to a network")
|
||||
end
|
||||
|
||||
return form
|
||||
end,
|
||||
|
|
|
@ -8,7 +8,7 @@ minetest.mkdir(computers.devicepath) --make sure it exists
|
|||
minetest.mkdir(computers.networkpath) --make sure it exists
|
||||
|
||||
computers.os = {
|
||||
version = 0.42,
|
||||
version = 0.43,
|
||||
name = "kuto",
|
||||
authors = {"wsor", "luk3yx"},
|
||||
license = "MIT",
|
||||
|
@ -17,6 +17,7 @@ computers.os = {
|
|||
dofile(computers.modpath .. "/old_stuff/init.lua")
|
||||
|
||||
dofile(computers.modpath .. "/api.lua")
|
||||
dofile(computers.modpath .. "/networks.lua")
|
||||
dofile(computers.modpath .. "/formspec.lua")
|
||||
dofile(computers.modpath .. "/commands.lua")
|
||||
dofile(computers.modpath .. "/gui.lua")
|
||||
|
|
152
computers/networks.lua
Normal file
152
computers/networks.lua
Normal file
|
@ -0,0 +1,152 @@
|
|||
local networks = {}
|
||||
local network_lookup = {}
|
||||
computers.networks = {}
|
||||
|
||||
local function init_networks()
|
||||
local path = computers.networkpath
|
||||
local files = minetest.get_dir_list(computers.networkpath, false)
|
||||
for _, file in pairs(files) do
|
||||
local id = file:sub(1,-6)
|
||||
local f = io.open(path .. "/" .. file)
|
||||
networks[id] = minetest.parse_json(f:read("*all"))
|
||||
f:close()
|
||||
|
||||
if not network_lookup[networks[id].pname] then network_lookup[networks[id].pname] = {} end
|
||||
network_lookup[networks[id].pname][networks[id].net_name] = id
|
||||
end
|
||||
end
|
||||
|
||||
init_networks()
|
||||
|
||||
local function update_file(id)
|
||||
local data = networks[id]
|
||||
local path = computers.networkpath .. "/" .. id .. ".json"
|
||||
minetest.safe_file_write(path, minetest.write_json(data))
|
||||
end
|
||||
|
||||
function computers.networks.create(player, net_name)
|
||||
local pname = player
|
||||
if type(player) == "userdata" then pname = player:get_player_name() end
|
||||
local id = pname .. "_" .. minetest.get_us_time()
|
||||
|
||||
if net_name:match("%W") then return false end --pnly accept alphanumerics
|
||||
if not network_lookup[pname] then network_lookup[pname] = {} end
|
||||
if network_lookup[pname][net_name] then return false end
|
||||
if networks[id] then return false end
|
||||
|
||||
--create storage on disk
|
||||
local path = computers.networkpath .. "/" .. id .. ".json"
|
||||
local data = {
|
||||
pname = pname,
|
||||
net_name = net_name,
|
||||
devices = {},
|
||||
dns = {
|
||||
}
|
||||
}
|
||||
minetest.safe_file_write(path, minetest.write_json(data))
|
||||
|
||||
--store data in memory
|
||||
networks[id] = data
|
||||
network_lookup[pname][net_name] = id
|
||||
|
||||
return true, id
|
||||
end
|
||||
|
||||
function computers.networks.verify_network(id)
|
||||
if networks[id] then return true else return false end
|
||||
end
|
||||
|
||||
function computers.networks.get_net_name(id)
|
||||
return networks[id].net_name
|
||||
end
|
||||
|
||||
function computers.networks.get_network_devices(id)
|
||||
return table.copy(networks[id].devices)
|
||||
end
|
||||
|
||||
function computers.networks.get_network_dns(id)
|
||||
return table.copy(networks[id].dns)
|
||||
end
|
||||
|
||||
function computers.networks.get_id_by_net_name(player, net_name)
|
||||
local pname = player
|
||||
if type(player) == "userdata" then pname = player:get_player_name() end
|
||||
if not network_lookup[pname] then network_lookup[pname] = {} end
|
||||
return network_lookup[pname][net_name]
|
||||
end
|
||||
|
||||
function computers.networks.get_networks_in_area(pos, rad)
|
||||
rad = rad or 10
|
||||
local locations = {}
|
||||
local keyed_locations = {}
|
||||
local meta_nodes = minetest.find_nodes_with_meta(
|
||||
vector.new(pos.x+rad, pos.y+rad, pos.z+rad),
|
||||
vector.new(pos.x-rad, pos.y-rad, pos.z-rad)
|
||||
)
|
||||
for _, location in pairs(meta_nodes) do
|
||||
local status = minetest.get_meta(location):get("net_id")
|
||||
if status and networks[status] then
|
||||
table.insert(locations, status)
|
||||
keyed_locations[status] = true
|
||||
end
|
||||
end
|
||||
return locations, keyed_locations
|
||||
end
|
||||
|
||||
function computers.networks.get_net_names_in_area(pos, rad)
|
||||
rad = rad or 10
|
||||
local locations = {}
|
||||
local keyed_locations = {}
|
||||
local meta_nodes = minetest.find_nodes_with_meta(
|
||||
vector.new(pos.x+rad, pos.y+rad, pos.z+rad),
|
||||
vector.new(pos.x-rad, pos.y-rad, pos.z-rad)
|
||||
)
|
||||
for _, location in pairs(meta_nodes) do
|
||||
local status = minetest.get_meta(location):get("net_id")
|
||||
if status and networks[status] and not keyed_locations[networks[status].net_name] then
|
||||
table.insert(locations, networks[status].net_name)
|
||||
keyed_locations[networks[status].net_name] = true
|
||||
end
|
||||
end
|
||||
return locations, keyed_locations
|
||||
end
|
||||
|
||||
function computers.networks.add_device(id, pos)
|
||||
if type(pos) ~= "table" or not networks[id] then return false end
|
||||
networks[id].devices[minetest.pos_to_string(pos)] = minetest.get_node(pos).name
|
||||
minetest.get_meta(pos):set_string("net_id", id)
|
||||
update_file(id)
|
||||
return true
|
||||
end
|
||||
|
||||
function computers.networks.remove_device(id, pos)
|
||||
if type(pos) ~= "table" or not networks[id] then return false end
|
||||
networks[id].devices[minetest.pos_to_string(pos)] = nil
|
||||
minetest.get_meta(pos):set_string("net_id", "")
|
||||
update_file(id)
|
||||
return true
|
||||
end
|
||||
|
||||
function computers.networks.set_dns(id, pos, url)
|
||||
if type(pos) ~= "table" or not networks[id] then return false end
|
||||
if url:match("%W") then return false end
|
||||
networks[id].dns = networks[id].dns or {}
|
||||
networks[id].dns[url] = minetest.hash_node_position(pos) .. "/public_pages"
|
||||
|
||||
update_file(id)
|
||||
return true
|
||||
end
|
||||
|
||||
function computers.networks.resolve_url(id, pos, url)
|
||||
if type(pos) ~= "table" or not networks[id] then return false end
|
||||
if networks[id].dns[url:split("/")[1]] then
|
||||
local path = computers.devicepath .. "/" .. networks[id].dns[url:split("/")[1]].."/index.page"
|
||||
local f = io.open(path)
|
||||
if not f then return false end
|
||||
local data = f:read("*all")
|
||||
f:close()
|
||||
if data then return true, data else return false end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user