local function new_config(name) local path = "/etc/" .. name local function read_key_in_line(line, key) local prefix = key .. ":" local prefix_len = string.len(prefix) local actual = string.sub(line, 0, prefix_len) if not (prefix == actual) then return nil end local value = string.sub(line, prefix_len + 1) return value end local function get(key, default) local file = fs.open(path, "r") if file == nil then return default end while true do local line = file.readLine() if line == nil then return default end local value = read_key_in_line(line, key) if not (value == nil) then return value end end end local function get_num(key, default) local str = get(key, nil) if str == nil then return default end local result = tonumber(str) if result == nil then error("Tried to parse conf '" .. path .. "'\nkey \"" .. key .. "\": \"" .. str .. "\" as number.") end return result end return { get = get, get_num = get_num } end local function item_list_to_map(item_list) local result_ = {} for _, item in pairs(item_list) do local name = item.name result_[name] = item.amount end return result_ end local function diff_items(prev_item_map, item_map) local diff = {} for name, amount in pairs(item_map) do local prev_amount = prev_item_map[name] if prev_amount == nil then diff[#diff + 1] = { name = name, amount = amount } else local item_diff = amount - prev_amount if not (item_diff == 0) then diff[#diff + 1] = { name = name, amount = item_diff } end end end return diff end local function add_frame_item_pos(frame, max) for _, item in pairs(frame) do item.pos = math.random(max) end end local function display_name(complete) local index = string.find(complete, ":") local name = string.sub(complete, index + 1) local initials = string.sub(name, 1, 2) local last_found = 1 while true do local index_ = string.find(name, "_", last_found) if index_ == nil then break end last_found = index_ + 1 initials = initials .. "_" .. string.sub(name, last_found, last_found + 1) end return initials end local function main() local ae = peripheral.find("meBridge") if ae == nil then print("ME bridge not found") return end local monitor = peripheral.find("monitor") if monitor == nil then print("Monitor not found") return end monitor.setTextScale(0.5) local width, height = monitor.getSize() local delay = new_config("me-matrix").get_num("delay", 0.1) print("Running with: res (", width, ",", height, "), delay ", delay, "s") local prev_item_map = item_list_to_map(ae.listItems()) local frames = {} local iteration = 0 while true do local item_map = item_list_to_map(ae.listItems()) local frame = diff_items(prev_item_map, item_map) prev_item_map = item_map add_frame_item_pos(frame, width) table.insert(frames, 1, frame) table.remove(frames, height + 1) monitor.clear() for frame_index, frame_ in ipairs(frames) do for _, item in ipairs(frame_) do monitor.setCursorPos(item.pos, frame_index) if item.amount > 0 then monitor.setTextColour(colors.lightBlue) else monitor.setTextColour(colors.purple) end monitor.write(display_name(item.name)) end end iteration = iteration + 1 if iteration % 10 == 0 then print("Iteration", iteration) end os.sleep(delay) end end main()