local dlg = Dialog() dlg:entry{ id="url", label="Server:", text="http://127.0.0.1:8797" } dlg:button{ id="yes", text="Connect" } dlg:button{ id="no", text="Cancel" } dlg:show() local data = dlg.data local connected = false local images = {} local function getimage(image) img = {} for x=0,image.width do tmp = {} for y=0,image.height do tmp[y] = image:getPixel(x, y) end img[x] = tmp end return img end local function send(data) if connected then ws:sendText(json.encode(data)) end end local function handleMessage(mt, datain) if mt == WebSocketMessageType.OPEN then send({ event = "connect", version = tostring(app.version), image = getimage(app.image) }) connected = true elseif mt == WebSocketMessageType.TEXT then local data = json.decode(datain) if data.event == "imagesetbytes" then app.image.bytes = data.image elseif data.event == "imagesetarray" then for x,column in ipairs(data.image) do for y,pixel in ipairs(column) do app.image:drawPixel(x, y, pixel) end end elseif data.event == "setpixel" then app.image:drawPixel(data.x, data.y, data.value) end elseif mt == WebSocketMessageType.CLOSE then connected = false ws:connect() end end local function wsinit() ws = WebSocket{ onreceive = handleMessage, url = data.url, deflate = true } end app.events:on('sitechange', function() send({ event = "sitechange" }) end) app.events:on('fgcolorchange', function() send({ event = "fgcolorchange", color = app.fgColor.rgbaPixel }) end) app.events:on('bgcolorchange', function() send({ event = "bgcolorchange", color = app.bgColor.rgbaPixel }) end) app.events:on('beforecommand', function(ev) send({ event = "beforecommand", name = ev.name, params = ev.params }) end) app.events:on('aftercommand', function(ev) send({ event = "aftercommand", name = ev.name, params = ev.params }) end) local function filenamechanged(ev) send({ event = "filenamechange", filename = app.sprite.filename }) end local function spritechanged(ev) if images[app.image.id] == nil then images[app.image.id] = { version = app.image.version, bytes = app.image.bytes, data = getimage(app.image), width = app.image.width, height = app.image.height, colormode = app.image.colorMode, rowstride = app.image.rowStride } elseif images[app.image.id].version ~= app.image.version then out["version"] = app.image.version images[app.image.id] = app.image.version elseif images[app.image.id].bytes ~= app.image.bytes and images[app.image.id].width == app.image.width and images[app.image.id].height == app.image.height then local currentImage = getimage(app.image) local changes = {} for x,column in ipairs(currentImage.data) do for y,pixel in ipairs(column) do if images[app.image.id].data[x][y] ~= pixel then table.insert(changes, { x = x, y = y, value = pixel }) end end end send({ event = "change", changes = changes, id = app.image.id }) elseif images[app.image.id].width ~= app.image.width or images[app.image.id].height ~= app.image.height then send({ event = "sizechange", width = app.image.width, height = app.image.height, image = getimage(app.image), id = app.image.id }) elseif images[app.image.id].colorMode ~= app.image.colorMode then images[app.image.id].colorMode = app.image.colorMode send({ event = "colormodechange", colormode = app.image.colorMode, id = app.image.id }) elseif images[app.image.id].rowStride ~= app.image.rowStride then images[app.image.id].rowStride = app.image.rowStride send({ event = "rowstridechange", rowstride = app.image.rowStride, id = app.image.id }) end end local function registerspriteevents(sprite) sprite.events:on("filenamechange", filenamechanged) sprite.events:on("change", spritechanged) end if data.yes then wsinit() ws:connect() end