Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local args = {...}
- if #args > 1 then
- print("Usage: mapserver <database path>")
- return
- end
- local DAPPER_CLIENT_REQUEST_CHANNEL = 4261
- local DAPPER_CLIENT_DATA_CHANNEL = 4262
- local DAPPER_SCAN_DATA_CHANNEL = 4263
- local DAPPER_SCAN_ACKNOWLEDGE_CHANNEL = 4264
- local DAPPER_SCAN_NEXT_REQUEST_CHANNEL = 4265
- local DAPPER_SCAN_NEXT_REPLY_CHANNEL = 4266
- local DAPPER_SCAN_REQUEST_NEXT = "nextblock"
- local DAPPER_CLIENT_REQUEST_MAP = "mapdata"
- os.setComputerLabel("Dapper Mapper Server")
- print("Dapper Mapper Server by oeed")
- local modem = peripheral.find("modem")
- if not modem or not modem.isWireless() then
- error("Please connect a wireless modem and re-run the program.", 0)
- end
- print("Loading map database...")
- local database
- local databasePath = args[1] and args[1] or "/database"
- if fs.exists(databasePath) then
- local h = fs.open(databasePath, "r")
- if h then
- database = textutils.unserialize(h.readAll())
- h.close()
- end
- if not database then
- error("Failed to read database '" .. databasePath .. "', it may be corrupt.", 0)
- end
- else
- database = {
- blocks = {}
- }
- end
- local function saveDatabase()
- local h = fs.open(databasePath, "w")
- if h then
- local serialised = textutils.serialize(database)
- local availableSpace = fs.getFreeSpace("/") + fs.getSize(databasePath)
- if availableSpace < #serialised then
- printError("WARNING! Insufficient space to save database!")
- else
- print("Saved database. Size: " .. #serialised .. "B")
- h.write(serialised)
- end
- h.close()
- else
- printError("WARNING! Failed to save database (couldn't open file).")
- end
- end
- print("Downloading latest block catalogue from GitHub...")
- local catalogueHandle = http.get("https://raw.githubusercontent.com/oeed/Dapper/master/Server/catalogue?"..os.time())
- local catalogueRaw
- if not catalogueHandle then
- print("Failed to download catalogue, trying to read a local copy.")
- local h = fs.open("catalogue", "r")
- if h then
- catalogueRaw = h.readAll()
- h.close()
- end
- else
- catalogueRaw = catalogueHandle.readAll()
- local h = fs.open("catalogue", "w")
- if h then
- h.write(catalogueRaw)
- h.close()
- end
- end
- if not catalogueRaw then
- error("Couldn't access a copy of the block catalogue!", 0)
- end
- local catalogue = loadstring("return " .. catalogueRaw)()
- if not catalogue then
- error("The catalogue was corrupt, sorry! Try deleting your local copy or check GitHub.", 0)
- end
- modem.open(DAPPER_CLIENT_REQUEST_CHANNEL)
- modem.open(DAPPER_CLIENT_DATA_CHANNEL)
- modem.open(DAPPER_SCAN_DATA_CHANNEL)
- modem.open(DAPPER_SCAN_ACKNOWLEDGE_CHANNEL)
- modem.open(DAPPER_SCAN_NEXT_REQUEST_CHANNEL)
- modem.open(DAPPER_SCAN_NEXT_REPLY_CHANNEL)
- print("Awaiting requests...")
- -- Pixel = text, textColour, backgroundColour
- local function identifyBlock(block)
- local name, state = block.name, block.state
- if catalogue[name] then
- for i, catalogueItem in ipairs(catalogue[name]) do
- local catalogueState, pixel = catalogueItem[1], catalogueItem[2]
- local match = true
- for k, v in pairs(catalogueState) do
- if v ~= state[k] then
- match = false
- break
- end
- end
- if match then
- return pixel
- end
- end
- end
- return {"?", colours.lightGrey, colours.grey}
- end
- while true do
- local event, side, senderChannel, replyChannel, message, distance = os.pullEvent("modem_message")
- if senderChannel == DAPPER_SCAN_DATA_CHANNEL then
- print("Received new map data!")
- if type(message) == "table" then
- local receivedScans = {}
- local lastYield = os.clock()
- for i, scan in pairs(message) do
- if type(scan.x) == "number" and type(scan.z) == "number" and type(scan.block) == "table" then
- local xBlocks = database.blocks[scan.x]
- if not xBlocks then
- xBlocks = {}
- database.blocks[scan.x] = xBlocks
- end
- if i % 200 == 199 then
- local clock = os.clock()
- if clock - lastYield >= 5 then
- print("Yielding")
- os.queueEvent("blah")
- os.pullEvent()
- lastYield = clock
- end
- end
- xBlocks[scan.z] = scan.block
- table.insert(receivedScans, {x = scan.x, z = scan.z})
- end
- end
- modem.transmit(DAPPER_SCAN_ACKNOWLEDGE_CHANNEL, 0, receivedScans)
- print("Added " .. #receivedScans .. " new blocks!")
- end
- saveDatabase()
- elseif senderChannel == DAPPER_SCAN_NEXT_REQUEST_CHANNEL then
- if type(message) == "table" then
- if type(message.startX) == "number" and type(message.stopX) == "number" and type(message.startZ) == "number" and type(message.stopZ) == "number" then
- print("Request for next block...")
- local response = {}
- local found = false
- for x = message.startX, message.stopX, 1 do
- for z = message.startZ, message.stopZ, 1 do
- if not database.blocks[x] or not database.blocks[x][z] then
- print("Found " .. x .. ", " .. z)
- response.x = x
- response.z = z
- found = true
- break
- end
- end
- if found then
- break
- end
- end
- modem.transmit(DAPPER_SCAN_NEXT_REPLY_CHANNEL, 0, response)
- end
- end
- elseif senderChannel == DAPPER_CLIENT_REQUEST_CHANNEL then
- if message == DAPPER_CLIENT_REQUEST_MAP then
- print("A client requested map data!")
- local pixels = {}
- for x, xBlocks in pairs(database.blocks) do
- local xPixels = {}
- for y, block in pairs(xBlocks) do
- xPixels[y] = identifyBlock(block)
- end
- pixels[x] = xPixels
- end
- modem.transmit(DAPPER_CLIENT_DATA_CHANNEL, 0, pixels)
- end
- end
- end
Add Comment
Please, Sign In to add comment