diff --git a/init.lua b/init.lua index ca0be43..11d2e33 100644 --- a/init.lua +++ b/init.lua @@ -1,12 +1,15 @@ -- This code is distributed under GN GPL v2 license. Copyright© Jimy-Byerley -local welcome_message = "/* welcome to cybertronic OS v2.0 */" -local default_laptop = "computers:laptop_open" +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 = {} local computer_action = function(pos, formname, fields, sender) - local node = minetest.env:get_node(pos) --use shell computers.execute_oscommand(fields.text, pos, sender) end @@ -15,8 +18,14 @@ computers.registered_command_names = {} computers.registered_commands = {} computers.register_oscommand = function(name, short_description, long_description, exe) - computers.registered_command_names[#computers.registered_command_names+1] = name - computers.registered_commands[name] = {short_description=short_description, long_description=long_description, exe=exe} + if computers.registered_commands[name] == nil then + computers.registered_command_names[#computers.registered_command_names+1] = name + end + computers.registered_commands[name] = { + short_description=short_description, + long_description=long_description, + exe=exe + } end computers.execute_oscommand = function(cmdline, pos, player) @@ -58,7 +67,7 @@ minetest.register_craft({ }) minetest.register_craft({ - output = 'computers:laptop_close', + output = default_laptop, recipe = { {'technology:flat_screen_off', "technology:wire"}, {'technology:electronic_card', "technology:wire"}, @@ -91,10 +100,7 @@ minetest.register_node("computers:laptop_open", { light_source = 4, paramtype2 = "facedir", drawtype = "nodebox", - node_box = {type = "fixed", fixed = { - --{-0.45, -0.40, 0.30, 0.45, 0.30, 0.25}, - --{-0.45, -0.5, -0.45, 0.45, -0.425, 0.25}, - + node_box = {type = "fixed", fixed = { -- top part {-0.3, -0.45, 0.05, 0.3, 0.05, 0.1}, -- bottom part @@ -173,12 +179,24 @@ minetest.register_node("computers:laptop_connect", { light_source = 6, paramtype2 = "facedir", drawtype = "nodebox", - node_box = {type = "fixed", fixed = { - {-0.45, -0.40, 0.30, 0.45, 0.30, 0.25}, - {-0.45, -0.5, -0.45, 0.45, -0.425, 0.25}, + node_box = {type = "fixed", fixed = { + -- top part + {-0.3, -0.45, 0.05, 0.3, 0.05, 0.1}, + -- bottom part + {-0.3, -0.5, -0.45, 0.3, -0.45, 0.075}, }}, - selection_box = {type = "fixed", fixed = {-0.45, -0.40, 0.30, 0.45, 0.30, 0.25}}, - tiles = {"laptop_top.png", "laptop_bottom.png", "laptop_left.png", "laptop_right.png", "laptop_back.png", "laptop_front_connect.png"}, + selection_box = {type = "fixed", fixed = { + -- top part + {-0.3, -0.45, 0.05, 0.3, 0.05, 0.1}, + -- bottom part + {-0.3, -0.5, -0.45, 0.3, -0.45, 0.075}, + }}, + tiles = {"laptop_top.png", "laptop_bottom.png", "laptop_left.png", "laptop_right.png", "laptop_back.png", { + image="laptop_front_connect.png", + backface_culling=false, + animation={type="vertical_frames", aspect_w=128, aspect_h=128, length=4.5} + } + }, walkable = true, groups = {choppy=2, dig_immediate=2, not_in_creative_inventory=1}, drop = default_laptop, @@ -187,70 +205,8 @@ minetest.register_node("computers:laptop_connect", { node.name = "computers:laptop_close" minetest.env:set_node(pos, node) end, - on_receive_fields = function(pos, formname, fields, sender) - --get remote coordinates - local meta = minetest.env: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.env:get_node(pos) - local node = minetest.env:get_node(remote_pos) - - if fields.text == "disconnect" then - --change local - if math.random(1,2) == 1 then - self.name = "computers:laptop_smalltext" - else - self.name = "computers:laptop_bigtext" - end - minetest.env:set_node(pos, self) - --set local metadata - meta:set_string("formspec", "field[text;;${text}]") - meta:set_string("infotext", "") - - --change remote text - if math.random(1,2) == 1 then - node.name = "computers:laptop_smalltext" - else - node.name = "computers:laptop_bigtext" - end - minetest.env:set_node(remote_pos, node) - --set remote metadata - local meta = minetest.env:get_meta(remote_pos) - meta:set_string("formspec", "field[text;;${text}]") - meta:set_string("infotext", "") - else - - --verify host activity - if node.name ~= "computers:laptop_connect" then - minetest.chat_send_player(sender:get_player_name(), "[connection failed]") - --change text - if math.random(1,2) == 1 then - self.name = "computers:laptop_smalltext" - else - self.name = "computers:laptop_bigtext" - end - minetest.env:set_node(pos, self) - --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, "["..fields.text.."]") - i = i+1 - end - else - minetest.chat_send_player(sender:get_player_name(), "[bad address]") - end - end - end, + + on_receive_fields = computers.oscommand_com_main }) -minetest.register_alias("computers:laptop", "computers:laptop_close") +minetest.register_alias("computers:laptop", "computers:laptop_open") diff --git a/os.lua b/os.lua index 31b83b0..638912d 100644 --- a/os.lua +++ b/os.lua @@ -1,4 +1,14 @@ -computers.register_oscommand("help", "get help about a function", "help [COMMAND]", function(cmdline, pos, player) +-- 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 = "" @@ -14,7 +24,7 @@ computers.register_oscommand("help", "get help about a function", "help [COMMAND message = command..":\t"..computers.registered_commands[command].short_description .. "\nusage:\n" .. computers.registered_commands[command].long_description end if message == "" then - message = "no help for this command" + message = "help: no help for command: "..command end return message, true @@ -26,30 +36,203 @@ computers.register_oscommand("time", "get the time of day", "time", function(cmd end) -computers.register_oscommand("gps", "localize a player", "gps [-c PLAYER get coordinates]\n [-d PLAYER get distance between computer and player]\n [-r PLAYER get relative coordinates]", +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 message = "gps: error: unable to connect to satellite (in devel program)" + 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) -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]", function(cmdline, pos, player) - local command, opt = string.match(cmdline, "^([^ ]+) *(%a+)") - if opt == "-c" then - local x, y, z - command, opt,x,y,z = string.match(cmdline, "^([^ ]+) *(%a+) *(%d+)[, ] *(%d+)[, ] *(%d+)") - -- ... - return command..": unable to connect: no network available (in devel program)" +-- 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.env: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.env:get_node(pos) + local node = minetest.env: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.env: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 - local command, opt, playername = string.match(cmdline, "^([^ ]+) *(%a+) *(%a+)") - local player = minetest.get_player_by_name(playername) - local p = player.getpos() - -- ... - return command..": unable to connect: no network available (in devel program)" + + --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, " "..fields.text.." ") + i = i+1 + end + else + minetest.chat_send_player(sender:get_player_name(), "[bad address]") + end 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) \ No newline at end of file diff --git a/textures/laptop_front_connect.png b/textures/laptop_front_connect.png index 90d0bca..99d0ccd 100755 Binary files a/textures/laptop_front_connect.png and b/textures/laptop_front_connect.png differ