123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- local mod_storage = minetest.get_mod_storage()
- local bdev = {}
- -- Check hardware capabilities { "hdd", "floppy", "usb", "net", "liveboot" }
- function bdev:is_hw_capability(hw_cap)
- for i, cap in ipairs(self.os.hwdef.hw_capabilities) do
- if cap == hw_cap or cap == hw_cap:sub(18, -1) then --"laptop_removable_*"then
- return cap
- end
- end
- return false
- end
- -- Get RAM
- function bdev:get_ram_disk()
- if not self.ram_disk then
- self.ram_disk = minetest.deserialize(self.os.meta:get_string('laptop_ram')) or {}
- end
- return self.ram_disk
- end
- function bdev:free_ram_disk()
- self.ram_disk = {}
- self:sync()
- end
- -- Get HDD if exists
- function bdev:get_hard_disk()
- if self.hard_disk == nil then
- if self:is_hw_capability('hdd') then
- self.hard_disk = minetest.deserialize(self.os.meta:get_string('laptop_appdata')) or {}
- else
- self.hard_disk = false
- end
- end
- return self.hard_disk
- end
- -- Get Removable disk if exists
- function bdev:get_removable_disk(removable_type)
- if self.removable_disk == nil then
- local data = { bdev = self }
- data.inv = self.os.meta:get_inventory()
- data.inv:set_size("main", 1) -- 1 disk supported
- function data:reload(stack)
- -- self.inv unchanged
- -- self.rtype unchanged (assumption
- stack = stack or self.inv:get_stack("main", 1)
- if stack then
- local def = stack:get_definition()
- if def and def.name ~= "" then
- self.stack = stack
- self.def = def
- self.meta = stack:get_meta()
- self.os_format = self.meta:get_string("os_format")
- if self.os_format == "" then
- self.os_format = "none"
- end
- self.label = self.meta:get_string("description")
- if self.label == "" then
- self.label = self.def.description
- end
- for group, _ in pairs(self.def.groups) do
- local rtype_chk = self.bdev:is_hw_capability(group)
- if not removable_type or removable_type == rtype_chk then
- self.rtype = rtype_chk
- break
- end
- end
- self.storage = minetest.deserialize(self.meta:get_string("os_storage")) or {}
- end
- end
- end
- function data:eject()
- if not self.stack then
- return false
- end
- local p = self.bdev.os.pos
- local drop_pos = { x=p.x+math.random()*2-1, y=p.y,z=p.z+math.random()*2-1 }
- minetest.item_drop(self.stack, nil, drop_pos)
- self.stack = nil
- return true
- end
- function data:format_disk(ftype, label)
- self.stack = ItemStack(self.def.name)
- self.meta = self.stack:get_meta()
- self.meta:set_string("os_format", ftype or "")
- self.os_format = ftype
- self.label = label or ""
- end
- data:reload()
- self.removable_disk = data
- end
- return self.removable_disk
- end
- -- Connect to cloud
- function bdev:get_cloud_disk(store_name)
- if self.cloud_disk == nil or (self.cloud_disk ~= false and not self.cloud_disk[store_name]) then
- if self:is_hw_capability('net') then
- self.cloud_disk = self.cloud_disk or {}
- self.cloud_disk[store_name] = minetest.deserialize(mod_storage:get_string(store_name)) or {}
- else
- self.cloud_disk = false
- return false
- end
- end
- return self.cloud_disk[store_name]
- end
- -- Get device to boot
- function bdev:get_boot_disk()
- if self:is_hw_capability('liveboot') then
- local drive = self:get_removable_disk()
- if drive.stack and drive.os_format == 'boot' then
- return 'removable'
- end
- end
- return 'hdd'
- end
- -- Get app related object from storage "disk_type"
- function bdev:get_app_storage(disk_type, store_name)
- if disk_type == 'ram' then
- local store = self:get_ram_disk()
- store[store_name] = store[store_name] or {}
- return store[store_name]
- elseif disk_type == 'hdd' then
- local store = self:get_hard_disk()
- if store then
- store[store_name] = store[store_name] or {}
- return store[store_name]
- else
- return nil
- end
- elseif disk_type == 'removable' then
- local store = self:get_removable_disk()
- if store.stack and (store.os_format == 'data' or store.os_format == 'boot') then
- store.storage[store_name] = store.storage[store_name] or {}
- return store.storage[store_name]
- else
- return nil
- end
- elseif disk_type == 'system' then
- local runtime = self:get_app_storage("ram", "os")
- runtime.booted_from = runtime.booted_from or self:get_boot_disk()
- return self:get_app_storage(runtime.booted_from, store_name)
- elseif disk_type == 'cloud' then
- return self:get_cloud_disk(store_name) or nil
- end
- end
- -- Save all data if used
- function bdev:sync()
- -- save RAM
- self.os.meta:set_string('laptop_ram', minetest.serialize(self.ram_disk))
- self.os.meta:mark_as_private('laptop_ram')
- -- save HDD
- if self.hard_disk then
- self.os.meta:set_string('laptop_appdata', minetest.serialize(self.hard_disk))
- self.os.meta:mark_as_private('laptop_appdata')
- end
- -- save removable
- if self.removable_disk then
- if self.removable_disk.stack then
- if self.removable_disk.def and self.removable_disk.label ~= self.removable_disk.def.description then
- self.removable_disk.meta:set_string("description", self.removable_disk.label)
- end
- if self.removable_disk.storage and next(self.removable_disk.storage) then
- self.removable_disk.meta:set_string("os_storage", minetest.serialize(self.removable_disk.storage))
- end
- end
- self.removable_disk.inv:set_stack("main", 1, self.removable_disk.stack)
- end
- end
- -- Save all data if used
- function bdev:sync_cloud()
- -- Modmeta (Cloud)
- if self.cloud_disk then
- for store, value in pairs(self.cloud_disk) do
- mod_storage:set_string(store, minetest.serialize(value))
- end
- end
- end
- -- Get handler
- function laptop.get_bdev_handler(mtos)
- local bdevobj = {}
- for k,v in pairs(bdev) do
- bdevobj[k] = v
- end
- bdevobj.os = mtos
- return bdevobj
- end
|