Files

setup.src
  • import_code("/home/me/h/libs/list.src")
  • import_code("/home/me/h/libs/disk.src")
  • import_code("/home/me/h/libs/passwords.src")
  • Disk.init("/home/me/h/disks", "passwords")
  • if(Disk.blobs.len > 1) then exit("password generation setup already completed")
  • PasswordGenerator.init(PASSWORDS)
  • print("generating passwords, it will take a while")
  • HASH_TABLE=PasswordGenerator.AllPasswords
  • print("done")
  • Disk.init("/home/me/h/disks", "passwords")
  • print("parsing passwords obj")
  • f = function(o)
  • return o[1]
  • end function
  • pass_list = Lst.map(Lst.to_list(HASH_TABLE), @f)
  • print("done")
  • print("writing to disk")
  • Disk.write(pass_list.join(char(10)))
  • print("done")
test.src
  • import_code("/home/me/h/libs/disk.src")
  • Disk.init("/home/me/h/disks", "passwords")
  • for blob in Disk.blobs
  • print(blob.get_content.len)
  • end for
  • end for
  • print(Disk.read_chars.len)
libs/disk.src
  • 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
  • //TODO: alias it to update(last_char_index, content)
  • 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)
  • last_blob = self.last_blob
  • available_chars = MAX_FILE_CONTENT - last_blob.get_content.len
  • if string.len <= available_chars then
  • last_blob.set_content(last_blob.get_content + string)
  • else
  • last_blob.set_content(last_blob.get_content + string[:available_chars])
  • string = string[(string.len - available_chars) * -1:]
  • self.write(string)
  • end if
  • 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
  • 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
cli.src
  • import_code("/home/me/h/libs/list.src")
  • import_code("/home/me/h/libs/disk.src")
  • import_code("/home/me/h/libs/passwords.src")
  • Disk.init("/home/me/h/disks", "passwords")
  • Vega = {}
  • Vega.vega_sig = {}
  • Vega.vega_sig["description"] = "shit cli script"
  • Vega.vega_sig["args"] = ["ip*", "port"]
  • Vega.vega_sig["options"] = [{["-v", "--verbose"]: "print more logs"}]
  • Vega.vega = function(args = [], options = {})
  • ip = args[0]
  • port = args[1]
  • has_verbose = options["-v"]
  • print(locals)
  • end function
  • import_code("/home/me/h/libs/thor.src") //requires on listlib
  • Thor.init(Vega, "vega")
libs/thor.src
  • ThorCommand = {}
  • ThorCommand.init = function(func, sig, name)
  • self.name = name
  • self.func = @func
  • if sig.hasIndex("description") then self.description = sig["description"]
  • if sig.hasIndex("args") then
  • self.args = sig["args"]
  • end if
  • if sig.hasIndex("options") then
  • f = function(obj)
  • param = {}
  • param["name"] = obj.indexes[0]
  • param["description"] = obj[obj.indexes[0]]
  • return param
  • end function
  • self.options = Lst.map(sig["options"], @f)
  • end if
  • end function
  • ThorCommand.required_args = function()
  • f = function(obj)
  • return obj[-1:] == "*"
  • end function
  • return Lst.select(self.args, @f)
  • end function
  • ThorCommand.optional_args = function()
  • f = function(obj)
  • return self.required_args.indexOf(obj) == null
  • end function
  • return Lst.select(self.args, @f)
  • end function
  • ThorCommand.options_list = function()
  • f = function(o)
  • return o.name
  • end function
  • return Lst.map(self.options, @f)
  • end function
  • ThorCommand.args_help = function()
  • out = self.name
  • for arg in self.args
  • out = out + " " + arg
  • end for
  • return out
  • end function
  • ThorCommand.options_help = function()
  • out = "options for " + self.name + ":" + char(10)
  • for i in self.options
  • n = i.name
  • if typeof(i.name) == "list" then n = i.name.join(" or ")
  • out = out + n + " : " + i.description
  • if self.options.indexOf(i) < self.options.len - 1 then out = out + char(10)
  • end for
  • return out
  • end function
  • ThorCommand.help = function()
  • out = self.args_help + char(10) + char(10)
  • out = out + self.options_help
  • return out
  • end function
  • ThorCommand.exec = function()
  • self.func(self.passed_args, self.passed_options)
  • end function
  • // class divider ---------------------------------------
  • ThorManager = {}
  • ThorManager.init = function(thor)
  • self.thor = thor
  • end function
  • ThorManager.eval_command = function(command)
  • used_args = self.thor.global_args[:command.args.len]
  • self.thor.global_args = self.thor.global_args[command.args.len:]
  • self.thor.used_options = self.thor.used_options + Lst.flat(command.options_list)
  • for i in range(command.args.len - used_args.len - 1)
  • used_args.push(null)
  • end for
  • command["passed_args"] = used_args
  • command["passed_options"] = self.options_by_key(command)
  • self.thor.global_execution_queue.push(command)
  • end function
  • ThorManager.options_by_key = function(command)
  • r = {}
  • get_value = function(o)
  • if o.indexOf("=") then
  • striped_options = self.thor.striped_global_options
  • if striped_options.indexOf(o) then
  • value = self.thor.global_options[striped_options.indexOf(o)]
  • return value[value.indexOf("=")+1:]
  • else
  • return null
  • end if
  • else
  • if self.thor.global_options.indexOf(i) != null then return true
  • return null
  • end if
  • end function
  • for o in command.options_list
  • if typeof(o) == "list" then
  • v = null
  • for i in o
  • if get_value(i) != null then v = get_value(i)
  • end for
  • for i in o
  • r[i] = v
  • end for
  • else
  • r[o] = get_value(o)
  • end if
  • end for
  • return r
  • end function
  • // class divider ---------------------------------------
  • Thor = {}
  • Thor.init = function(class, main_func_name)
  • self.class = null
  • self.global_args = []
  • self.passed_args_count = 0
  • self.global_options = []
  • self.used_options = []
  • self.global_execution_queue = []
  • self.manager = new ThorManager
  • self.manager.init(self)
  • main_command = new ThorCommand
  • main_command.init(class[main_func_name], class[main_func_name+"_sig"], main_func_name)
  • self.params_to_args_options(params)
  • self.manager.eval_command(main_command)
  • self.catch_errors
  • self.exec_queue
  • end function
  • Thor.striped_global_options = function()
  • f = function(ob)
  • if ob.indexOf("=") then
  • return ob[:ob.indexOf("=")+1]
  • end if
  • end function
  • return Lst.map(self.global_options, @f)
  • end function
  • Thor.params_to_args_options = function(params)
  • // filter for args
  • f = function(p)
  • return p[0] == "-"
  • end function
  • args = Lst.reject(params, @f)
  • options = {}
  • f = function(param)
  • return param[:1] == "-" and param.indexOf("=") == null
  • end function
  • params_options = Lst.select(params, @f)
  • f = function(param)
  • if param[:2] != "--" and param.len > 2 then
  • r = []
  • for i in param[1:].values
  • r.push("-" + i)
  • end for
  • return r
  • else
  • return param
  • end if
  • end function
  • params_options = Lst.uniq(Lst.flat(Lst.map(params_options, @f)))
  • f = function(param)
  • return param[:1] == "-" and param.indexOf("=") != null
  • end function
  • params_value_options = Lst.select(params, @f)
  • options = params_options + params_value_options
  • self.global_args = args
  • self.passed_args_count = args.len
  • self.global_options = options
  • end function
  • Thor.catch_errors = function()
  • if self.global_options.indexOf("-h") != null or self.global_options.indexOf("--help") != null then
  • print(self.global_execution_queue[-1].help)
  • exit()
  • end if
  • f = function(c)
  • return c.required_args.len
  • end function
  • required_args = Lst.map(self.global_execution_queue, @f)
  • if self.passed_args_count < required_args.sum then
  • print("error: required params not passed, check the docs")
  • exit()
  • end if
  • used_options = self.used_options + ["-h", "--help"] //cant use self inside the block
  • f = function(p)
  • return used_options.indexOf(p) == null
  • end function
  • undefined_options = Lst.select(self.striped_global_options, @f)
  • for i in undefined_options
  • print("error: " + i + " option is not defined, check the docs")
  • exit()
  • end for
  • end function
  • Thor.exec_queue = function()
  • self.global_execution_queue[-1].exec
  • end function