computers/os.lua

257 lines
9.5 KiB
Lua
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- This code is distributed under GN GPL v2 license. Copyright© Jimy-Byerley
local opened_laptop = "computers:laptop_open"
local closed_laptop = "computers:laptop_close"
local connected_laptop = "computers:laptop_connect"
local welcome_message = "/* welcome to cybertronic OS v2.2 */"
local default_laptop = opened_laptop
computers.register_oscommand("help", "get help about a function", "help [COMMAND]",
function(cmdline, pos, player)
local command = string.match(cmdline, "help *(.+)")
local message = ""
if command == nil then
for i=1,#computers.registered_command_names do
local name = computers.registered_command_names[i]
local short_desc = computers.registered_commands[name].short_description
message = message..name.." "..short_desc.."\n"
end
message = message.."\ntype \"help COMMAND\" to get usage"
elseif command ~= nil and computers.registered_commands[command] ~= nil then
message = command..":\t"..computers.registered_commands[command].short_description .. "\nusage:\n" .. computers.registered_commands[command].long_description
end
if message == "" then
message = "help: no help for command: "..command
end
return message, true
end)
computers.register_oscommand("time", "get the time of day", "time", function(cmdline, pos, player)
local message = "local time : "..(minetest.env:get_timeofday()*24)
return message, true
end)
computers.register_oscommand("gps", "localize a player", "gps [-l get local coordinates] [-c PLAYER get coordinates]\n [-d PLAYER get distance between computer and player]\n [-r PLAYER get relative coordinates]",
function(cmdline, pos, player)
local command, opt =string.match(cmdline, "^([^ ]+) *([^ ]+)")
local message = ""
if opt == nil then
return "gps: usage error: see usage in help", true
end
if opt == "-l" then
message = "* * * local coordinates * * *\nlatitude "..pos.x.." \nlongitude "..pos.z.." m\naltitude "..pos.y.." m"
elseif opt == '-c' then
local playername
command, opt, playername = string.match(cmdline, "^([^ ]+) *([^ ]+) *([^ ]+)")
local player = minetest.get_player_by_name(playername)
-- positioning error if player not found
if player == nil then
message = "gps: positioning error: unable to find player \""..playername.."\""
return message, true
end
-- output message
local p = player:getpos()
message = "* * * local coordinates * * *\nlatitude "..p.x.." \nlongitude "..p.z.." m\naltitude "..p.y.." m"
elseif opt == "-r" then
local playername
command, opt, playername = string.match(cmdline, "^([^ ]+) *([^ ]+) *([^ ]+)")
local player = minetest.get_player_by_name(playername)
-- positioning error if player not found
if player == nil then
message = "gps: positioning error: unable to find player \""..playername.."\""
return message, true
end
-- output message
local p = player:getpos()
message = "* * * local coordinates * * *\nlatitude "..p.x-pos.x.." \nlongitude "..p.z-pos.z.." m\naltitude "..p.y-pos.y.." m"
elseif opt == "-d" then
local playername
command, opt, playername = string.match(cmdline, "^([^ ]+) *([^ ]+) *([^ ]+)")
local player = minetest.get_player_by_name(playername)
-- positioning error if player not found
if player == nil then
message = "gps: positioning error: unable to find player \""..playername.."\""
return message, true
end
-- output message
local p = player:getpos()
message = "* * * distance to player * * *\ndistance to "..playername.." is "..math.sqrt(
math.pow(p.x-pos.x,2) + math.pow(p.y-pos.y,2) + math.pow(p.z-pos.z,2)
)
end
return message, true
end)
computers.register_oscommand("mat", "get the material name of a bloc next to the computer", "mat [z+1] [z-1] [y+1] [y-1] [x+1] [x-1]",
function(cmdline, pos, player)
local message = "mat: error: incompatible driver (in devel program)"
return message, false
end)
computers.register_oscommand("com", "create a connexion between two computers", "com [-c COODINATES make a connexion between this computer and an other at coordinates]\n [-p PLAYERNAME make a connexion between this computer and the closest computer to the player]\nWhen connected, type EOL to disconnect",
function(cmdline, pos, player)
local command, opt = string.match(cmdline, "^([^ ]+) *([^ ]+)")
local node, remote_pos
local self = minetest.get_node(pos)
if opt == "-c" then
remote_pos = {}
command, opt, remote_pos.x, remote_pos.y, remote_pos.z = string.match(cmdline, "^([^ ]+) *([^ ]+) *(%d+)[, ] *(%d+)[, ] *(%d+)")
--node = minetest.get_node(remote_pos)
elseif opt == "-p" then
local command, opt, playername = string.match(cmdline, "^([^ ]+) *([^ ]+) *([^ ]+)")
local player = minetest.get_player_by_name(playername)
if player == nil then
return "com: network error: unable to find player  \""..playername.."\"", true
end
local p = player:getpos()
local zone = 3
if self.name ~= opened_laptop then
return "com: connection error: incompatible client", true
end
for X = p.x-zone, p.x+zone do
for Y = p.y-zone, p.y+zone do
for Z = p.z-zone, p.z+zone do
node = minetest.get_node({x=X,y=Y,z=Z})
if node.name == opened_laptop or node.name == closed_laptop then
remote_pos = {x=X, y=Y, z=Z}
break
end
end
end
end
else
return "com: usage error: see $ help com", false
end
node = minetest.get_node(remote_pos)
print(remote_pos.x..","..remote_pos.y..","..remote_pos.z)
print(node.name)
if (node.name == opened_laptop or node.name == closed_laptop) and self.name == opened_laptop then
-- set remote machine
node.name = connected_laptop
minetest.add_node(remote_pos, node)
-- and remote meta
local rmeta = minetest.get_meta(remote_pos)
rmeta:set_string("destination", pos.x..", "..pos.y..", "..pos.z)
rmeta:set_string("formspec", "field[text;;${text}]")
rmeta:set_string("infotext", "INCOMING CONNECTION * * *")
-- set local machine
self.name = connected_laptop
minetest.add_node(pos, self)
-- and local meta
local lmeta = minetest.get_meta(pos)
lmeta:set_string("destination", remote_pos.x..", "..remote_pos.y..", "..remote_pos.z)
lmeta:set_string("formspec", "field[text;;${text}]")
message = "CONNECTION ETABLISHED * * *"
print("[computers]: connection etablished between ("..pos.x..","..pos.y..","..pos.z..") and ("..remote_pos.x..","..remote_pos.y..","..remote_pos.z..")")
else
return "com: connection error: unable to create a tunnel", false
end
return message, true
end)
-- funtion called when a "computers:laptop_connect" receive a field
computers.oscommand_com_main = function(pos, formname, fields, sender)
--get remote coordinates
local meta = minetest.get_meta(pos)
local remote_pos = {}
remote_pos.x, remote_pos.y, remote_pos.z = string.match(meta:get_string("destination"), "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
local self = minetest.get_node(pos)
local node = minetest.get_node(remote_pos)
if fields.text == nil then
return
elseif fields.text == "EOL" then
print("[computers]: "..sender:get_player_name().." break connection from host at ("..pos.x..","..pos.y..","..pos.z..") with host at ("..remote_pos.x..","..remote_pos.y..","..remote_pos.z..")")
self.name = opened_laptop
minetest.add_node(pos, self)
--set local metadata
meta:set_string("formspec", "field[text;;${text}]")
meta:set_string("infotext", "END OF LINE\n* * * connection closed by local host\n\n"..welcome_message)
node.name = opened_laptop
minetest.add_node(remote_pos, node)
--set remote metadata
meta = minetest.get_meta(remote_pos)
meta:set_string("formspec", "field[text;;${text}]")
meta:set_string("infotext", "END OF LINE\n* * * connection closed by remote host\n\n"..welcome_message)
else
--verify host activity
if node.name ~= "computers:laptop_connect" then
minetest.chat_send_player(sender:get_player_name(), "[connection failed]")
--set metadata
meta:set_string("formspec", "field[text;;${text}]")
meta:set_string("infotext", "")
end
if remote_pos.x and remote_pos.y and remote_pos.z then
print(sender:get_player_name().." send packet to "..remote_pos.x..","..remote_pos.y..","..remote_pos.z)
--transfer message
local recievers = minetest.env:get_objects_inside_radius(remote_pos, 3)
local i=1
while recievers[i] ~= nil do
local name = recievers[i]:get_player_name()
minetest.chat_send_player(name, "</mechanic voice/> "..fields.text.." <//mechanic voice/>")
i = i+1
end
else
minetest.chat_send_player(sender:get_player_name(), "[bad address]")
end
end
end
computers.register_oscommand("restart", "reload all laptops system's", "restart",
function (cmdline, pos, player)
print("[computers]: "..player:get_player_name().." has initialized a global computers system restarting. Minetest will redo file os.lua")
local meta = minetest.get_meta(pos)
meta:set_string("infotext", "** SYSTEM : "..player:get_player_name().." has initialized a global restart")
dofile(minetest.get_modpath("computers").."/os.lua")
print("[computers]: all computers restarted")
return welcome_message, true
end)
if technology ~= nil then
computers.register_oscommand("design", "generates a plan for the asked machine", "design [machin name]",
function (cmdline, pos, player)
local command, asked_name = string.match(cmdline, "^([^ ]+) *([^ ]+)")
local plan = technology.registered_plans[asked_name]
if plan then
local inventory = player:get_inventory()
inventory:add_item("main", plan[1])
return asked_name.." successfully computed.", true
else
return asked_name..": file not found.", false
end
end)
end