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.os.meta:set_string('laptop_ram','') self.ram_disk = nil 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 data.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 drop_pos = table.copy(self.bdev.os.pos) drop_pos = { x=drop_pos.x+math.random()*2-1, y=drop_pos.y,z=drop_pos.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 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 -- 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 = table.copy(bdev) bdevobj.os = mtos return bdevobj end