computers/os.lua

257 lines
9.5 KiB
Lua
Raw Normal View History

-- 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)
2014-06-20 09:51:45 +02:00
local command = string.match(cmdline, "help *(.+)")
local message = ""
2014-06-20 09:51:45 +02:00
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
2014-06-20 09:51:45 +02:00
end
if message == "" then
message = "help: no help for command: "..command
2014-06-20 09:51:45 +02:00
end
2014-06-20 09:51:45 +02:00
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)
2014-06-20 09:51:45 +02:00
return message, true
end)
2014-06-20 09:51:45 +02:00
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
2014-06-20 09:51:45 +02:00
return message, true
end)
2014-06-20 09:51:45 +02:00
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)
2014-06-20 09:51:45 +02:00
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
2014-06-20 09:51:45 +02:00
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