Advertisement
blunty666

remoteMap_server

Dec 23rd, 2015
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.98 KB | None | 0 0
  1. local args = {...}
  2.  
  3. --===== OPEN REDNET =====--
  4. for _, side in ipairs(redstone.getSides()) do
  5.     if peripheral.getType(side) == "modem" then
  6.         rednet.open(side)
  7.     end
  8. end
  9.  
  10. if not rednet.isOpen() then
  11.     printError("could not open rednet")
  12.     return
  13. end
  14.  
  15. --===== LOAD MAP =====--
  16. if not compactMap then
  17.     if not os.loadAPI("compactMap") then
  18.         error("could not load API: compactMap")
  19.     end
  20. end
  21. local map = compactMap.new(args[1])
  22.  
  23. --===== SET REDNET PROTOCOL =====--
  24. local MAP_SHARE_PROTOCOL
  25. if args[2] and type(args[2]) == "string" then
  26.     MAP_SHARE_PROTOCOL = "map_share:"..args[2]
  27. else
  28.     MAP_SHARE_PROTOCOL = "map_share:"..fs.getName(args[1])
  29. end
  30.  
  31. --===== HOST AS SERVER =====--
  32. do
  33.     local host = rednet.lookup(MAP_SHARE_PROTOCOL, "SERVER")
  34.     if host and host ~= os.computerID() then
  35.         printError("server already running for this map share")
  36.         return
  37.     end
  38. end
  39. rednet.host(MAP_SHARE_PROTOCOL, "SERVER")
  40.  
  41. --===== UTILS =====--
  42. local MESSAGE_TYPE = {
  43.     GET = 0,
  44.     SET = 1,
  45. }
  46. local receivedMessages = {}
  47. local receivedMessageTimeouts = {}
  48.  
  49. local function isValidCoord(coord)
  50.     return type(coord) == "number" and coord % 1 == 0 and coord >= 0 and coord <= 15
  51. end
  52.  
  53. local function updateCoord(x, y, z, value)
  54.     local coord = vector.new(x, y, z)
  55.     local currValue = map:get(coord)
  56.     if value == 1 then
  57.         if currValue then
  58.             map:set(coord, math.min(7, currValue + 1))
  59.         else
  60.             map:set(coord, 0)
  61.         end
  62.     elseif value == -1 then
  63.         if currValue then
  64.             if currValue == 0 then
  65.                 map:set(coord, nil)
  66.             else
  67.                 map:set(coord, currValue - 1)
  68.             end
  69.         end
  70.     end
  71. end
  72.  
  73. local function updateMap(newData, gX, gY, gZ)
  74.     if type(newData) == "table" then
  75.         local currX, currY
  76.         for x, gridYZ in pairs(newData) do
  77.             if isValidCoord(x) and type(gridYZ) == "table" then
  78.                 currX = gX*16 + x
  79.                 for y, gridZ in pairs(gridYZ) do
  80.                     if isValidCoord(y) and type(gridZ) == "table" then
  81.                         currY = gY*16 + y
  82.                         for z, value in pairs(gridZ) do
  83.                             if isValidCoord(z) then
  84.                                 updateCoord(currX, currY, gZ*16 + z, value)
  85.                             end
  86.                         end
  87.                     end
  88.                 end
  89.             end
  90.         end
  91.         map:save(gX, gY, gZ)
  92.     end
  93. end
  94.  
  95. local function checkGridCoordFormat(gridCoord)
  96.     if type(gridCoord) == "table" and #gridCoord == 3 then
  97.         for i = 1, 3 do
  98.             local coord = gridCoord[i]
  99.             if type(coord) ~= "number" or coord % 1 ~= 0 then
  100.                 return false
  101.             end
  102.         end
  103.         return true
  104.     end
  105.     return false
  106. end
  107.  
  108. local function newMessage(messageType, messageID, grid, data)
  109.     return {
  110.         type = messageType,
  111.         ID = messageID,
  112.         grid = grid,
  113.         data = data,
  114.     }
  115. end
  116.  
  117. --===== REPEATED MESSAGE HANDLING =====--
  118. local function clearOldMessages()
  119.     while true do
  120.         local event, timer = os.pullEvent("timer")
  121.         local messageID = receivedMessageTimeouts[timer]
  122.         if messageID then
  123.             receivedMessageTimeouts[timer] = nil
  124.             receivedMessages[messageID] = nil
  125.         end
  126.     end
  127. end
  128.  
  129. --===== MAIN =====--
  130. local function main()
  131.     while true do
  132.         local senderID, message = rednet.receive(MAP_SHARE_PROTOCOL)
  133.         if type(message) == "table" and checkGridCoordFormat(message.grid) then
  134.             if message.type == MESSAGE_TYPE.GET then
  135.                 local gridData = map:getGrid(unpack(message.grid))
  136.                 local replyMessage = newMessage(MESSAGE_TYPE.GET, message.ID, message.grid, gridData)
  137.                 rednet.send(senderID, replyMessage, MAP_SHARE_PROTOCOL)
  138.             elseif message.type == MESSAGE_TYPE.SET then
  139.                 if not receivedMessages[message.ID] then
  140.                     updateMap(message.data, unpack(message.grid))
  141.                     receivedMessages[message.ID] = true
  142.                     receivedMessageTimeouts[os.startTimer(15)] = message.ID
  143.                 end
  144.                 local replyMessage = newMessage(MESSAGE_TYPE.SET, message.ID, message.grid, true)
  145.                 rednet.send(senderID, replyMessage, MAP_SHARE_PROTOCOL)
  146.             end
  147.         end
  148.     end
  149. end
  150.  
  151. --===== USER INTERFACE =====--
  152. local function control()
  153.     while true do
  154.         local event, key = os.pullEvent("key")
  155.         if key == keys.backspace then
  156.             break
  157.         end
  158.     end
  159. end
  160.  
  161. parallel.waitForAny(main, clearOldMessages, control)
  162.  
  163. rednet.unhost(MAP_SHARE_PROTOCOL)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement