/ bjvxlx_computers / mineos.lua
mineos.lua
1 local mod = bjvxlx.computers 2 local S = mod.translate 3 4 bjvxlx.text_shell.register_shell( 5 'bjvxlx_computers:mineos', 6 'bjvxlx_lua_access:sandboxed_console', 7 { 8 initialize = function (self, ...) 9 bjvxlx.text_shell.super( 10 'bjvxlx_computers:mineos', 11 'initialize' 12 )(self, ...) 13 mod.make_mineos_env(self) 14 end, 15 get_key = function (self) 16 return tostring(self.context.pos) 17 end, 18 on_activate = function (self) 19 self:print(S("MineOS")) 20 self:print(S("Powered by @1", _VERSION)) 21 end, 22 make_formspec = function (self) 23 if not self:is_booted() then 24 return table.concat({ 25 "formspec_version[7]", 26 "size[12,9]", 27 "background9[0,0;12,9;bjvxlx_text_shell_bg.png;true;5]", 28 "style_type[label;textcolor=#ffff00;font=mono,bold]", 29 "label[1,1;no bootdisk]" 30 }, '') 31 elseif self.editing then 32 return table.concat({ 33 "formspec_version[7]", 34 "size[12,9]", 35 "background9[0,0;12,9;bjvxlx_text_shell_bg.png;true;5]", 36 "style_type[textarea;textcolor=#ffffff;font=mono,bold]", 37 "style_type[button;font=mono,bold]", 38 "set_focus[command;true]", 39 "textarea[0.5,0.5;11,7;command;;", 40 minetest.formspec_escape(self.editing.initdata), 41 "]", 42 "button[4.5,8;3.5,0.5;done;Done]" 43 }, '') 44 else 45 return bjvxlx.text_shell.super( 46 'bjvxlx_computers:mineos', 47 'make_formspec' 48 )(self) 49 end 50 end, 51 run_command = function (self, command) 52 if not self:is_booted() then 53 self.history_discard = true 54 elseif self.editing then 55 self.editing.callback(command) 56 self.editing = false 57 self.history_discard = true 58 else 59 return bjvxlx.text_shell.super( 60 'bjvxlx_computers:mineos', 61 'run_command' 62 )(self, command) 63 end 64 end, 65 is_booted = function (self) 66 local inv = minetest.get_meta(self.context.pos):get_inventory() 67 local bootdisk = inv:get_stack('bootdisk', 1) 68 return not ( 69 bootdisk:is_empty() or 70 bootdisk:get_name() ~= 'bjvxlx_computers:mineos_floppy' 71 ) 72 end 73 } 74 ) 75 76 function mod.datadisk_error(code, n) 77 if code == 'empty' then 78 error(S("datadisk slot #@1 is empty", tostring(n))) 79 elseif code == 'bootdisk' then 80 error(S("datadisk #@1 is a bootdisk", tostring(n))) 81 elseif code == 'jammed' then 82 error(S("datadisk slot #@1 is jammed", tostring(n))) 83 elseif code == 'blank' then 84 error(S("datadisk #@1 is not formatted", tostring(n))) 85 end 86 end 87 88 function mod.make_mineos_env(session) 89 local env = session.env 90 env.os = {} 91 92 function env.os.disk(n) 93 local inv = minetest.get_meta(session.context.pos):get_inventory() 94 local stack = inv:get_stack('datadisks', n) 95 local itemname = stack:get_name() 96 local diskidno = stack:get_meta():get_int('diskidno') 97 if itemname == '' then 98 mod.datadisk_error('empty', n) 99 elseif itemname == 'bjvxlx_computers:mineos_floppy' then 100 mod.datadisk_error('bootdisk', n) 101 elseif itemname ~= 'bjvxlx_computers:floppy' then 102 mod.datadisk_error('jammed', n) 103 elseif diskidno == 0 then 104 mod.datadisk_error('blank', n) 105 else 106 return bjvxlx.util.storage_proxy( 107 mod.storage, 108 ("disk%d"):format(diskidno) 109 ) 110 end 111 end 112 113 function env.os.format_disk(n) 114 local inv = minetest.get_meta(session.context.pos):get_inventory() 115 local stack = inv:get_stack('datadisks', n) 116 local itemname = stack:get_name() 117 local diskidno = stack:get_meta():get_int('diskidno') 118 if itemname == '' then 119 mod.datadisk_error('blank', n) 120 elseif itemname == 'bjvxlx_computers:mineos_floppy' then 121 diskidno = mod.storage:get_int('nextdiskidno') 122 if diskidno == 0 then diskidno = 1 end 123 mod.storage:set_int('nextdiskidno', diskidno + 1) 124 bjvxlx.util.create_storage_proxy_keyspace( 125 mod.storage, 126 ("disk%d"):format(diskidno) 127 ) 128 stack = ItemStack('bjvxlx_computers:floppy') 129 stack:get_meta():set_int('diskidno', diskidno) 130 inv:set_stack('datadisks', n, stack) 131 elseif itemname ~= 'bjvxlx_computers:floppy' then 132 mod.datadisk_error('jammed', n) 133 elseif diskidno == 0 then 134 diskidno = mod.storage:get_int('nextdiskidno') 135 if diskidno == 0 then diskidno = 1 end 136 mod.storage:set_int('nextdiskidno', diskidno + 1) 137 bjvxlx.util.create_storage_proxy_keyspace( 138 mod.storage, 139 ("disk%d"):format(diskidno) 140 ) 141 stack:get_meta():set_int('diskidno', diskidno) 142 inv:set_stack('datadisks', n, stack) 143 else 144 local disk = bjvxlx.util.storage_proxy( 145 mod.storage, 146 ("disk%d"):format(diskidno) 147 ) 148 for key in bjvxlx.util.storage_proxy_pairs(disk) do 149 disk[key] = nil 150 end 151 end 152 end 153 154 function env.os.open(tab, key) 155 if tab[key] == nil then 156 session.editing = { 157 initdata = "", 158 callback = function (data) 159 tab[key] = data 160 end 161 } 162 elseif type(tab[key]) == 'string' then 163 session.editing = { 164 initdata = tab[key], 165 callback = function (data) 166 tab[key] = data 167 end 168 } 169 else 170 error("data to edit is not a string") 171 end 172 end 173 174 function env.os.list(tab) 175 local results = {} 176 for key in bjvxlx.util.storage_proxy_pairs(tab) do 177 table.insert(results, key) 178 end 179 return unpack(results) 180 end 181 182 function env.os.run(script, ...) 183 setfenv(loadstring(script), session.env)(...) 184 end 185 186 function env.getmetatable(x) 187 local mt = getmetatable(x) 188 if mt.is_bjvxlx_util_storage_proxy_metatable then 189 return 'storage_proxy' 190 else 191 return mt 192 end 193 end 194 end