Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local CHANNEL_GLASS = 10033
- -- Wireless Init
- local modem = peripheral.find("modem")
- if not modem then
- printError("no modem attached")
- return
- end
- modem.open(CHANNEL_GLASS)
- local MSG_TYPE_NEW = 0x1
- local MSG_TYPE_UPDATE = 0x2
- local MSG_TYPE_INIT = 0x3
- local MSG_TYPE_LISTENER = 0x4
- local MSG_REACTOR_SETACTIVE = 0xEE0
- local MSG_TYPE_REPLY_NEW = 0xFF0
- -- Glasses Bridge
- local bridge = peripheral.find("openperipheral_bridge")
- if not bridge then
- printError("Could not find peripheral bridge!")
- return
- end
- local function CalcCenterX(x, width)
- return (width / 2) + x
- end
- local function CalcCenterY(y, height)
- return (height / 2) + y
- end
- local title_layout = {
- background = {
- type = "box";
- x = 20;
- y = 20;
- width = 100;
- height = 10;
- color = 0x333333;
- opacity = 0.7;
- };
- title = {
- type = "text";
- text = "GlassMon";
- x = CalcCenterX(20, 100);
- y = CalcCenterY(20, 10);
- z = 1;
- scale = 0.7;
- color = 0x7777FF;
- object_anchor = {"MIDDLE", "MIDDLE"};
- };
- }
- local function RenderLayout(layout)
- local objects = {}
- for i,v in pairs(layout) do
- local object
- if v.type == "box" then
- object = bridge.addBox(v.x or 0, v.y or 0, v.width or 10, v.height or 10, v.color, v.opacity)
- elseif v.type == "text" then
- object = bridge.addText(v.x or 0, v.y or 0, v.text, v.color)
- if v.scale then
- object.setScale(v.scale)
- end
- else
- return nil, "invalid object type: " .. v.type
- end
- if v.object_anchor then
- object.setObjectAnchor(v.object_anchor[1], v.object_anchor[2])
- end
- if v.z then
- object.setZ(v.z)
- end
- objects[i] = object
- end
- return objects
- end
- local cHeight = 33
- local function AllocateScreen(width, height)
- local nHeight = cHeight
- cHeight = cHeight + height + 3
- return 20, nHeight
- end
- bridge.clear()
- local success, err = RenderLayout(title_layout)
- if not success then
- pritnError(err)
- end
- bridge.sync()
- local status_msg = bridge.addText(0, 10, "")
- status_msg.setAlignment("MIDDLE", "TOP")
- status_msg.setVisible(false)
- -- Components
- local component_data = {}
- local lbase = math.log(10)
- local si_prefixes = {
- [-4] = "p";
- [-3] = "n";
- [-2] = "u";
- [-1] = "m";
- [0] = "WTF";
- [1] = "k";
- [2] = "M";
- [3] = "G";
- [4] = "T";
- [5] = "P";
- [6] = "E";
- [7] = "Z";
- [8] = "Y";
- }
- local si_low = -4
- local si_high = 8
- local function Round(number, decimals)
- return math.floor((number * 10^decimals) + 0.5) / 10^decimals
- end
- local function FormatSI(number, unit)
- local mult = 1
- if number < 0 then
- mult = -1
- number = -number
- end
- local brack = math.floor((math.log(number) / lbase) / 3)
- brack = math.min(math.max(brack, si_low), si_high)
- if brack == 0 then
- return tostring(mult * Round(number, 3)) .. " " .. unit
- end
- number = number / 10^(brack * 3)
- return tostring(Round(mult * number, 3)) .. " " .. si_prefixes[brack] .. unit
- end
- local reactors = {}
- local component_handlers = {
- ["energy_storage"] = {
- new = function(name, id, data)
- local x, y = AllocateScreen(100, 40)
- local c_layout = RenderLayout({
- title_background = {
- type = "box";
- x = x;
- y = y;
- width = 100;
- height = 10;
- color = 0x333333;
- opacity = 0.7;
- };
- title = {
- type = "text";
- text = name;
- x = CalcCenterX(x, 100);
- y = CalcCenterY(y, 10);
- z = 1;
- scale = 0.7;
- color = 0x7777FF;
- object_anchor = {"MIDDLE", "MIDDLE"};
- };
- info_background = {
- type = "box";
- x = x;
- y = y + 10;
- width = 100;
- height = 30;
- color = 0x333333;
- opacity = 0.7;
- };
- stored = {
- type = "text";
- text = "Not Available";
- x = x + 5;
- y = CalcCenterY(y + 10, 10);
- z = 1;
- scale = 0.7;
- color = 0xD3692C;
- object_anchor = {"LEFT", "MIDDLE"}
- };
- percentage = {
- type = "text";
- text = "Not Available";
- x = x + 5;
- y = CalcCenterY(y + 20, 10);
- z = 1;
- scale = 0.7;
- color = 0xD3692C;
- object_anchor = {"LEFT", "MIDDLE"}
- };
- increase = {
- type = "text";
- text = "Not Available";
- x = x + 5;
- y = CalcCenterY(y + 30, 10);
- z = 1;
- scale = 0.7;
- color = 0xD3692C;
- object_anchor = {"LEFT", "MIDDLE"}
- };
- })
- component_data[id].layout = c_layout
- end;
- update = function(id, data)
- local cdata = component_data[id]
- local layout = cdata.layout
- layout.stored.setText(FormatSI(data.stored, "RF") .. " / " .. FormatSI(data.max, "RF"))
- layout.percentage.setText(tostring(Round((data.stored / data.max) * 100, 2)) .. "% full")
- if cdata.last_update then
- local increase = (data.stored - cdata.last_stored) / (os.clock() - cdata.last_update) / 20
- layout.increase.setText("Rate: " .. FormatSI(increase, "RF/t"))
- end
- cdata.last_update = os.clock()
- cdata.last_stored = data.stored
- bridge.sync()
- end;
- };
- ["reactor"] = {
- new = function(name, id, data)
- table.insert(reactors, id)
- local x, y = AllocateScreen(100, 30)
- local c_layout = RenderLayout({
- title_background = {
- type = "box";
- x = x;
- y = y;
- width = 100;
- height = 10;
- color = 0x333333;
- opacity = 0.7;
- };
- title = {
- type = "text";
- text = name;
- x = CalcCenterX(x, 100);
- y = CalcCenterY(y, 10);
- z = 1;
- scale = 0.7;
- color = 0x7777FF;
- object_anchor = {"MIDDLE", "MIDDLE"};
- };
- info_background = {
- type = "box";
- x = x;
- y = y + 10;
- width = 100;
- height = 20;
- color = 0x333333;
- opacity = 0.7;
- };
- active = {
- type = "text";
- text = "Not Available";
- x = x + 5;
- y = CalcCenterY(y + 10, 10);
- z = 1;
- scale = 0.7;
- color = 0xD3692C;
- object_anchor = {"LEFT", "MIDDLE"};
- };
- rate = {
- type = "text";
- text = "Not Available";
- x = x + 5;
- y = CalcCenterY(y + 20, 10);
- z = 1;
- scale = 0.7;
- color = 0xD3692C;
- object_anchor = {"LEFT", "MIDDLE"};
- };
- })
- component_data[id].layout = c_layout
- end;
- update = function(id, data)
- local cdata = component_data[id]
- local layout = cdata.layout
- if data.active then
- layout.active.setColor(0x326806)
- layout.active.setText("Active")
- else
- layout.active.setColor(0x7C0404)
- layout.active.setText("Inactive")
- end
- layout.rate.setText("Rate: " .. FormatSI(data.rate, "RF/t"))
- end;
- };
- ["me_storage"] = {
- new = function(name, id, data)
- local x, y = AllocateScreen(100, 20)
- local c_layout = RenderLayout({
- title_background = {
- type = "box";
- x = x;
- y = y;
- width = 100;
- height = 10;
- color = 0x333333;
- opacity = 0.7;
- };
- title = {
- type = "text";
- text = name;
- x = CalcCenterX(x, 100);
- y = CalcCenterY(y, 10);
- z = 1;
- scale = 0.7;
- color = 0x7777FF;
- object_anchor = {"MIDDLE", "MIDDLE"};
- };
- info_background = {
- type = "box";
- x = x;
- y = y + 10;
- width = 100;
- height = 10;
- color = 0x333333;
- opacity = 0.7;
- };
- cpu_avail = {
- type = "text";
- text = "Not Available";
- x = x + 5;
- y = CalcCenterY(y + 10, 10);
- z = 1;
- scale = 0.7;
- color = 0xD3692C;
- object_anchor = {"LEFT", "MIDDLE"}
- };
- })
- component_data[id].layout = c_layout
- end;
- update = function(id, data)
- local cdata = component_data[id]
- local layout = cdata.layout
- if data.cpu_avail == 0 then
- layout.cpu_avail.setColor(0xEE0000)
- else
- layout.cpu_avail.setColor(0xD3692C)
- end
- layout.cpu_avail.setText("Crafting CPUs: " .. tostring(data.cpu_avail) .. " / " .. tostring(data.cpu_max))
- bridge.sync()
- end;
- };
- ["players"] = {
- new = function(name, id, data)
- if not component_data["players"] then
- local x, y = 123, 20
- local c_layout = RenderLayout({
- title_background = {
- type = "box";
- x = x;
- y = y;
- width = 100;
- height = 10;
- color = 0x333333;
- opacity = 0.7;
- };
- title = {
- type = "text";
- text = name;
- x = CalcCenterX(x, 100);
- y = CalcCenterY(y, 10);
- z = 1;
- scale = 0.7;
- color = 0x7777FF;
- object_anchor = {"MIDDLE", "MIDDLE"};
- };
- info_background = {
- type = "box";
- x = x;
- y = y + 10;
- width = 100;
- height = 10;
- color = 0x333333;
- opacity = 0.7;
- };
- })
- component_data["players"] = {layout = c_layout, clients = {}}
- end
- end;
- update = function(id, data)
- local cdata = component_data["players"]
- local layout = cdata.layout
- if not cdata.names then
- cdata.names = {}
- end
- cdata.clients[id] = data.players
- local all_players = {}
- for _,v in pairs(cdata.clients) do
- for __,p in pairs(v) do
- if not all_players[p] then
- table.insert(all_players, p)
- all_players[p] = true
- end
- end
- end
- layout.info_background.setHeight(#all_players * 10)
- for i,v in ipairs(all_players) do
- if not cdata.names[i] then
- cdata.names[i] = bridge.addText(128, 25 + (i * 10), v, 0xD3692C)
- cdata.names[i].setObjectAnchor("left", "middle")
- cdata.names[i].setZ(1)
- cdata.names[i].setScale(0.7)
- else
- cdata.names[i].setText(v)
- cdata.names[i].setVisible(true)
- end
- end
- for i = #all_players + 1, #cdata.names do
- cdata.names[i].setVisible(false)
- end
- end;
- };
- }
- local function Send(type, message, destination, component_id, rid)
- modem.transmit(CHANNEL_GLASS, 0, {
- protocol = "GLASS_MESSAGE";
- destination = destination;
- type = type;
- message = message;
- component_id = component_id;
- rid = rid;
- })
- end
- local function SendListener(id, component_id, ...)
- Send(MSG_TYPE_LISTENER, {id = MSG_REACTOR_SETACTIVE, args = {...}}, nil, component_id, nil)
- end
- local commands = {
- ["update"] = function(args)
- status_msg.setColor(0xFFFFFF)
- status_msg.setText("Updating...")
- status_msg.setVisible(true)
- bridge.sync()
- local request = http.get("http://pastebin.com/raw/4GZMXX3u")
- if request then
- local source = request.readAll()
- local success, err = loadstring(source)
- if not success then
- status_msg.setColor(0xEE0000)
- status_msg.setText("Could not update: " .. err)
- bridge.sync()
- else
- local file = fs.open("/startup", "w")
- file.write(source)
- file.close()
- os.reboot()
- end
- else
- status_msg.setColor(0xEE0000)
- status_msg.setText("Could not update: request failed")
- bridge.sync()
- end
- end;
- ["reboot"] = function(args)
- os.reboot()
- end;
- ["reactor"] = function(args)
- if #args ~= 0 then
- local command = args[1]:lower()
- if command == "on" then
- for i,v in pairs(reactors) do
- SendListener(MSG_REACTOR_SETACTIVE, v, true)
- end
- elseif command == "off" then
- for i,v in pairs(reactors) do
- SendListener(MSG_REACTOR_SETACTIVE, v, false)
- end
- end
- end
- end;
- }
- local function Receive(component_id)
- while true do
- local event, side, schannel, rchannel, message, dist = os.pullEvent()
- if event == "modem_message" then
- if schannel == CHANNEL_GLASS and type(message) == "table" and message.protocol == "GLASS_MESSAGE" and message.destination == -1 then
- return rchannel, message.type, message.message, message.component_id, message.rid
- end
- elseif event == "glasses_chat_command" then
- local args = {}
- for part in message:gmatch("[^ ]+") do
- table.insert(args, part)
- end
- local command = args[1]
- table.remove(args, 1)
- local callback = commands[command]
- if callback then
- callback(args)
- end
- end
- end
- end
- local function Reply(type, rchannel, rid, message)
- Send(type, message, rchannel, nil, rid)
- end
- local s_component_id = 0
- local function RegisterNew(message, reply, rid)
- if type(message) ~= "table" then
- return
- end
- local cType = message.type
- local cName = message.name
- if not cType or not cName then
- return
- end
- local component_id = s_component_id
- s_component_id = s_component_id + 1
- local handler = component_handlers[cType]
- component_data[component_id] = {update = handler and handler.update}
- if handler and handler.new then
- handler.new(cName, component_id, message.data)
- end
- print("Registered new " .. cType .. " named " .. cName .. " with id " .. component_id)
- Reply(MSG_TYPE_REPLY_NEW, reply, rid, {component_id = component_id})
- end
- Send(MSG_TYPE_INIT, nil, nil, nil, nil)
- while true do
- local rChannel, mType, message, component_id, rid = Receive()
- local success, err = pcall(function()
- if mType == MSG_TYPE_NEW then
- RegisterNew(message, rChannel, rid)
- elseif mType == MSG_TYPE_UPDATE then
- local data = component_data[component_id]
- if data and data.update then
- data.update(component_id, message)
- end
- else
- print("Unknown message type")
- end
- end)
- if not success then
- print("Error running event: " .. err)
- status_msg.setColor(0xEE0000)
- status_msg.setText("Error running event: " .. err)
- status_msg.setVisible(true)
- bridge.sync()
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement