spacepaste

/lib/service.lua

  1.  
  2. local c = require('component')
  3. local text = require('text')
  4. local event = require('event')
  5. local process = require('process')
  6. local unicode = require('unicode')
  7. local computer = require('computer')
  8. local serialization = require('serialization')
  9. local service = {}
  10. local log_gpu
  11. local cursorX, cursorY = 1, 1
  12. do
  13. local config_file = io.open('/etc/service-log.cfg')
  14. if config_file then
  15. local data = serialization.unserialize(config_file:read('*a'))
  16. log_gpu = c.proxy(c.get(data.gpu))
  17. local success, msg = log_gpu.bind(c.get(data.screen))
  18. if not success then
  19. error(msg)
  20. end
  21. if data.resolution then
  22. log_gpu.setResolution(table.unpack(data.resolution))
  23. end
  24. config_file:close()
  25. end
  26. end
  27. function service.log(msg, ...)
  28. local value = string.format('[%08.0f] ' .. msg .. '\n',
  29. computer.uptime(), ...)
  30. if not log_gpu then
  31. return
  32. end
  33. value = text.detab(value)
  34. local w, h = log_gpu.getResolution()
  35. if not w then
  36. return -- gpu lost its screen but the signal wasn't processed yet.
  37. end
  38. local line, nl
  39. repeat
  40. local wrapAfter, margin = math.huge, math.huge
  41. wrapAfter, margin = w - (cursorX - 1), w
  42. line, value, nl = text.wrap(value, wrapAfter, margin)
  43. log_gpu.set(cursorX, cursorY, line)
  44. cursorX = cursorX + unicode.wlen(line)
  45. if nl or cursorX > w then
  46. cursorX = 1
  47. cursorY = cursorY + 1
  48. end
  49. if cursorY > h then
  50. log_gpu.copy(1, 1, w, h, 0, -1)
  51. log_gpu.fill(1, h, w, 1, " ")
  52. cursorY = h
  53. end
  54. until not value
  55. end
  56. local function step_coroutine(c, return_on_error)
  57. local status = coroutine.status(c)
  58. if status == 'dead' then
  59. return false
  60. elseif status ~= 'suspended' then
  61. return true
  62. end
  63. local t = {coroutine.resume(c)}
  64. if not t[1] then
  65. service.log('problem in %s: %s', c, t[2])
  66. service.log('%s', debug.traceback(c))
  67. if return_on_error then
  68. return false
  69. else
  70. error('coroutine failure')
  71. end
  72. else
  73. return true
  74. end
  75. end
  76. function service.periodic(name, period, f, env)
  77. local t
  78. local want_up = false
  79. local function service_coroutine()
  80. while true do
  81. local c = coroutine.create(f)
  82. while true do
  83. if not step_coroutine(c) then
  84. break
  85. end
  86. coroutine.yield()
  87. end
  88. end
  89. end
  90. function start_service()
  91. if t then
  92. return
  93. end
  94. local c = process.spawn(service_coroutine)
  95. local function step()
  96. if not step_coroutine(c, true) then
  97. stop_service()
  98. end
  99. end
  100. t = event.timer(period, step, math.huge)
  101. service.log('Started %s', name)
  102. end
  103. local function stop_service()
  104. if not t then
  105. return
  106. end
  107. event.cancel(t)
  108. t = nil
  109. service.log('Stopped %s', name)
  110. if want_up then
  111. start_service()
  112. end
  113. end
  114. function env.start()
  115. want_up = true
  116. start_service()
  117. end
  118. function env.stop()
  119. want_up = false
  120. stop_service()
  121. end
  122. function env.status()
  123. if t then
  124. print('running')
  125. else
  126. print('stopped')
  127. end
  128. end
  129. end
  130. return service
  131.  

an extra bit in /lib/process.lua

  1.  
  2. function process.spawn(f, env, name, path)
  3. checkArg(1, f, "function")
  4. checkArg(2, env, "table", "nil")
  5. checkArg(3, name, "string", "nil")
  6. checkArg(4, path, "string", "nil")
  7. local process = findProcess()
  8. if process then
  9. env = env or process.env
  10. end
  11. if not path then
  12. path = '<function>'
  13. end
  14. env = setmetatable({}, {__index=env or _G})
  15. local thread = coroutine_create(f)
  16. running[thread] = {
  17. path = path,
  18. command = name,
  19. env = env,
  20. data = setmetatable({}, {__index=process and process.data or nil}),
  21. parent = process,
  22. instances = setmetatable({}, {__mode="v"})
  23. }
  24. return thread
  25. end
  26.  

/etc/rc.d/autocraft.lua

  1.  
  2. local serialization = require('serialization')
  3. local sides = require('sides')
  4. local computer = require('computer')
  5. local c = require('component')
  6. local service = require('service')
  7. local log = service.log
  8. local controller = c.me_controller
  9. local required_levels = {
  10. ['Wool'] = 8,
  11. ['Transistor'] = 10,
  12. ['Microchip (Tier 1)'] = 10,
  13. ['Microchip (Tier 2)'] = 10,
  14. ['Microchip (Tier 3)'] = 10,
  15. ['Iron Nugget'] = 10,
  16. ['Gold Nugget'] = 10,
  17. ['Basic Universal Cable'] = 32,
  18. ['Ultimate Universal Cable'] = 32,
  19. ['Redstone Torch'] = 4,
  20. ['Machine Frame (Basic)'] = 2,
  21. ['Redstone Reception Coil'] = 2,
  22. ['Paper'] = {128, 256},
  23. ['Book'] = {128, 256},
  24. ['ME Glass Cable - Fluix'] = 32,
  25. ['Logic Processor'] = 4,
  26. ['Calculation Processor'] = 4,
  27. ['Engineering Processor'] = 4,
  28. ['Speed Upgrade'] = 8,
  29. ['Energy Upgrade'] = 8,
  30. ['ME Smart Cable - Fluix'] = 8,
  31. ['ME Dense Cable - Fluix'] = 8,
  32. ['ME Storage Housing'] = 2,
  33. ['Arithmetic Logic Unit (ALU)'] = 2,
  34. ['Control Unit (CU)'] = 2,
  35. ['EEPROM (Lua BIOS)'] = 2,
  36. ['EEPROM'] = 2,
  37. ['Printed Silicon'] = {128, 256},
  38. }
  39. function ensure_level(label, desired)
  40. local filter = {label = label}
  41. local items = controller.getItemsInNetwork(filter)
  42. local count = 0
  43. for i = 1, items.n do
  44. count = count + items[i].size
  45. end
  46. local lower_bound = desired
  47. if type(desired) == 'table' then
  48. lower_bound, desired = table.unpack(desired)
  49. end
  50. if count >= lower_bound then
  51. return
  52. end
  53. local crafting = controller.getCraftables(filter)[1]
  54. if not crafting then
  55. log('No crafting available for %s', label)
  56. return
  57. end
  58. local stack_size = crafting.getItemStack().size
  59. local n_jobs = math.ceil((desired - count) / stack_size)
  60. log('Crafting %s (%d → %d)',
  61. label, count, count + stack_size * n_jobs, n_jobs)
  62. local status = crafting.request(desired - count)
  63. while not (status.isCanceled() or status.isDone()) do
  64. os.sleep(1)
  65. end
  66. end
  67. function tick()
  68. for label, count in pairs(required_levels) do
  69. ensure_level(label, count)
  70. coroutine.yield()
  71. end
  72. end
  73. service.periodic('autocraft', 0.1, tick, _ENV)
  74.  

/etc/rc.d/export-damaged.lua

  1.  
  2. local serialization = require('serialization')
  3. local sides = require('sides')
  4. local computer = require('computer')
  5. local c = require('component')
  6. local service = require('service')
  7. local controller = c.me_controller
  8. local export = c.me_exportbus
  9. local db = c.database
  10. local label_patterns = {
  11. 'Boots',
  12. 'Leggings',
  13. 'Chestplate',
  14. 'Helmet',
  15. '^Bow$',
  16. 'Fishing Rod',
  17. 'Sword',
  18. 'Pickaxe',
  19. 'Shovel',
  20. 'Axe',
  21. 'Shears',
  22. }
  23. function label_ok(item)
  24. for _, pattern in pairs(label_patterns) do
  25. if item.label:find(pattern) then
  26. return true
  27. end
  28. end
  29. return false
  30. end
  31. function clear_whole_db()
  32. for i = 1, 9 do
  33. db.clear(i)
  34. end
  35. end
  36. function export_relevant_items()
  37. local items = controller.getItemsInNetwork()
  38. local n_done = 0
  39. for i = 1, items.n do
  40. local item = items[i]
  41. if label_ok(item) and item.damage > 0 and not item.enchantments then
  42. controller.store(item, db.address)
  43. n_done = n_done + 1
  44. if n_done >= 9 then
  45. break
  46. end
  47. end
  48. end
  49. for i = 1, 9 do
  50. local item = db.get(i)
  51. if not item then
  52. break
  53. end
  54. service.log('Exporting %s@%d', item.label, item.damage)
  55. export.setExportConfiguration(sides.back, i, db.address, i)
  56. end
  57. end
  58. function tick()
  59. clear_whole_db()
  60. export_relevant_items()
  61. end
  62. service.periodic('export-damaged', 10, tick, _ENV)
  63.