/ 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