MAX_FILE_CONTENT = 160000 // limited by the game MAX_NESTED_FOLDERS = 16 // limited by the game MAX_FILES = 249 // limited by the game FOLDER_PER_BLOCK = 2 Block = {} Block.init = function(disk, folder) self.disk = disk self.folder = folder self.name = folder.name self.path = folder.path self.full_path = self.path + "/" + self.name self.depth = self.path.split("/").len - 1 self.is_at_max_depth = self.depth == MAX_NESTED_FOLDERS self.is_at_max_folders = self.folder.get_folders.len == FOLDER_PER_BLOCK if self.folder.get_files.len == 0 then self.new_file end function Block.last_file = function() return self.folder.get_files[-1] end function Block.new_file = function() blob_name = "0" if self.disk.blobs.len > 0 then blob_name = str(self.disk.blobs[-1].name.to_int + 1) self.disk.computer.touch(self.path, blob_name) self.disk.setup_blocks end function Block.is_full_of_folders = function() if self.is_at_max_depth then return true else if self.is_at_max_folders then for f in self.folder.get_folders n_block = new Block n_block.init(self.disk, f) if n_block.is_full_of_folders == false then return false end for return true end if return false end if end function Disk = {} Disk.init = function(data_folder_path = null, data_folder_name = ".disk") self.shell = get_shell self.computer = self.shell.host_computer self.data_folder_path = data_folder_path if self.data_folder_path == null then self.data_folder_path = home_dir self.data_folder_name = data_folder_name self.data_folder_full_path = self.data_folder_path + "/" + self.data_folder_name self.computer.create_folder(self.data_folder_path, self.data_folder_name) self.data_folder = self.computer.File(self.data_folder_full_path) self.setup_blocks // there is a bug in setup_blocks that when new_block.init creates a new file it will add it twice to blobs // list so im calling this shit again :) instead of fixing it self.setup_blocks self.tape = "" end function Disk.setup_blocks = function() self.blocks = [] self.blobs = [] self.computer.create_folder(self.data_folder_full_path, "blocks") first_block_folder = self.computer.File(self.data_folder_full_path + "/blocks") new_block = new Block new_block.init(self, first_block_folder) self.load_blocks(new_block) end function // this wont check for blocks already loaded and will load them again Disk.load_blocks = function(block) self.blocks.push(block) for f in block.folder.get_files self.blobs.push(f) end for for f in block.folder.get_folders new_block = new Block new_block.init(self, f) self.load_blocks(new_block) end for end function Disk.create_new_block = function(block = null) if block == null then block = self.blocks[0] count = self.blocks[-1].name.to_int + 1 if self.blocks[-1].name == "blocks" then count = 1 if block.folder.get_folders.len == 0 then self.computer.create_folder(block.path, str(count)) self.setup_blocks return 1 else for f in block.folder.get_folders n_block = new Block n_block.init(block.disk, f) if n_block.is_full_of_folders then continue self.create_new_block(n_block) self.setup_blocks return 1 end for self.computer.create_folder(block.path, str(count)) self.setup_blocks return 1 end if end function Disk.last_block = function() b = self.blocks[-1] if MAX_FILES - b.folder.get_files.len < MAX_FILES then return b end if if b.folder.get_files[-1].get_content.len == MAX_FILE_CONTENT then self.create_new_block return self.blocks[-1] end if end function Disk.last_blob = function() b = self.last_block if b.last_file.get_content.len == MAX_FILE_CONTENT then b.new_file return b.last_file else return b.last_file end if end function Disk.last_char_index = function() return (self.last_blob.get_content.len + (self.blobs.len - 1) * MAX_FILE_CONTENT) end function Disk.write = function(string) self.update(self.last_char_index, string) end function Disk.updated_blob_content = function(content, offset, string) content_to_left = content[:offset] content_in_middle = string content_to_right = content[offset + string.len:] // do not remove the "" return "" + content_to_left + content_in_middle + content_to_right end function Disk.update = function(offset, string) blob_index = floor(offset / MAX_FILE_CONTENT) inner_offset = offset % MAX_FILE_CONTENT available_chars = MAX_FILE_CONTENT - inner_offset if (self.blobs.hasIndex(blob_index) == false and inner_offset == 0 and self.blobs.len == blob_index) then if self.blobs[-1].get_content.len < MAX_FILE_CONTENT then exit("error offset out of range") self.last_block.new_file end if if (self.blobs.hasIndex(blob_index) == false) then exit("error offset out of range") blob = self.blobs[blob_index] if (blob.get_content.len < inner_offset) then exit("error offset out of range") if string.len >= available_chars then chars_to_write = string[:available_chars] chars_left = string[(string.len - available_chars) * -1:] blob.set_content(self.updated_blob_content(blob.get_content, inner_offset, chars_to_write)) new_offset = offset + chars_to_write.len self.update(new_offset, chars_left) else blob.set_content(self.updated_blob_content(blob.get_content, inner_offset, string)) end if end function // TODO: make this function load only the necessary files and finish the offset feature Disk.read_chars = function(start_offset = 0, end_offset = -1) string = "" for blob in self.blobs string = string + blob.get_content end for return string end function Disk.nuke = function() for b in self.blobs b.delete end for self.setup_blocks self.setup_blocks end function //tests ? Disk.init() // big string write test char_100 = "1" * 100 char_10000 = char_100 * 100 char_100000 = char_10000 * 10 char_100000 = char_100000 + char_10000 * 6 char_100000 = char_100000// + "yes" Disk.write(char_100000) b = Disk.update(0, "abcdefghi") b = Disk.update(4, "111") b = Disk.update(159995, "abcdefghi") // do cat 0 and cat 1 to see the results //b = Disk.update(160000, "abcdefghi")for