mirror of
https://github.com/IgorTimofeev/MineOS.git
synced 2025-12-24 13:02:49 +01:00
Новая либа для графонистой работы с модемами
This commit is contained in:
parent
aac9884dd0
commit
d7ae5cd2e4
293
Applications/modemConnection.lua
Normal file
293
Applications/modemConnection.lua
Normal file
@ -0,0 +1,293 @@
|
||||
|
||||
local event = require("event")
|
||||
local computer = require("computer")
|
||||
local component = require("component")
|
||||
local serialization = require("serialization")
|
||||
local unicode = require("unicode")
|
||||
local ecs, image
|
||||
local modem = component.modem
|
||||
local gpu = component.gpu
|
||||
local wirelessConnection = {}
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
local infoMessages = {
|
||||
userTriesToConnectNoGUI = "Пользователь %s желает установить с вами соединение. Разрешить?",
|
||||
noModem = "Этой библиотеке требуется сетевая карта для работы",
|
||||
}
|
||||
|
||||
wirelessConnection.port = 322
|
||||
wirelessConnection.sendingDataDelay = 1.0
|
||||
wirelessConnection.receiveMessagesFromRobots = true
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
local xSize, ySize = gpu.getResolution()
|
||||
local computerIcon
|
||||
if not component.isAvailable("robot") then
|
||||
image = require("image")
|
||||
ecs = require("ECSAPI")
|
||||
computerIcon = image.load("MineOS/System/OS/Icons/Script.pic")
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
local obj = {}
|
||||
local function newObj(class, name, ...)
|
||||
obj[class] = obj[class] or {}
|
||||
obj[class][name] = {...}
|
||||
end
|
||||
|
||||
local function askForConnection(userData)
|
||||
local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
|
||||
{"EmptyLine"},
|
||||
{"CenterText", ecs.colors.orange, "WirelessConnection"},
|
||||
{"EmptyLine"},
|
||||
{"CenterText", 0xffffff, "Пользователь " .. ecs.stringLimit("end", userData.address, 6) .. " желает" },
|
||||
{"CenterText", 0xffffff, "установить с вами беспроводное соединение." },
|
||||
{"EmptyLine"},
|
||||
{"CenterText", 0xffffff, "Разрешить подключение?" },
|
||||
{"EmptyLine"},
|
||||
{"Button", {ecs.colors.orange, 0x262626, "Да"}, {0x999999, 0xffffff, "Нет"}}
|
||||
)
|
||||
end
|
||||
|
||||
local function modemMessageHandler(_, localAddress, remoteAddress, port, distance, ...)
|
||||
local messages = {...}
|
||||
if #messages > 0 then
|
||||
if port == wirelessConnection.port then
|
||||
if messages[1] == "requestingPermissionToConnect" then
|
||||
askForConnection(messages[2])
|
||||
elseif messages[1] == "iAmHereAddMePlease" then
|
||||
if not wirelessConnection.availableUsers[remoteAddress] then
|
||||
local userData = serialization.unserialize(messages[2])
|
||||
if not userData.isRobot or (userData.isRobot and wirelessConnection.receiveMessagesFromRobots) then
|
||||
wirelessConnection.availableUsers[userData.address] = userData
|
||||
modem.send(remoteAddress, wirelessConnection.port, "iAmHereAddMePlease", wirelessConnection.dataToSend)
|
||||
computer.pushSignal("userlistChanged")
|
||||
end
|
||||
end
|
||||
elseif messages[1] == "iAmDisconnecting" then
|
||||
if wirelessConnection.availableUsers[remoteAddress] then
|
||||
wirelessConnection.availableUsers[remoteAddress] = nil
|
||||
computer.pushSignal("userlistChanged")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function createSendingArray()
|
||||
wirelessConnection.dataToSend = {}
|
||||
wirelessConnection.dataToSend.address = wirelessConnection.localAddress
|
||||
wirelessConnection.dataToSend.name = component.filesystem.getLabel()
|
||||
if component.isAvailable("robot") then
|
||||
wirelessConnection.dataToSend.isRobot = true
|
||||
if component.isAvailable("inventory_controller") then
|
||||
wirelessConnection.dataToSend.inventoryController = true
|
||||
end
|
||||
if component.isAvailable("tank_controller") then
|
||||
wirelessConnection.dataToSend.tankController = true
|
||||
end
|
||||
if component.isAvailable("crafting") then
|
||||
wirelessConnection.dataToSend.crafting = true
|
||||
end
|
||||
if component.isAvailable("redstone") then
|
||||
wirelessConnection.dataToSend.redstone = true
|
||||
end
|
||||
end
|
||||
wirelessConnection.dataToSend = serialization.serialize(wirelessConnection.dataToSend)
|
||||
end
|
||||
|
||||
--Нарисовать окружность, алгоритм спизжен с вики
|
||||
local function circle(xCenter, yCenter, radius, color)
|
||||
gpu.setBackground(color)
|
||||
local function insertPoints(x, y)
|
||||
gpu.set(xCenter + x * 2, yCenter + y, " ")
|
||||
gpu.set(xCenter + x * 2, yCenter - y, " ")
|
||||
gpu.set(xCenter - x * 2, yCenter + y, " ")
|
||||
gpu.set(xCenter - x * 2, yCenter - y, " ")
|
||||
|
||||
gpu.set(xCenter + x * 2 + 1, yCenter + y, " ")
|
||||
gpu.set(xCenter + x * 2 + 1, yCenter - y, " ")
|
||||
gpu.set(xCenter - x * 2 + 1, yCenter + y, " ")
|
||||
gpu.set(xCenter - x * 2 + 1, yCenter - y, " ")
|
||||
end
|
||||
|
||||
local x = 0
|
||||
local y = radius
|
||||
local delta = 3 - 2 * radius;
|
||||
while (x < y) do
|
||||
insertPoints(x, y);
|
||||
insertPoints(y, x);
|
||||
if (delta < 0) then
|
||||
delta = delta + (4 * x + 6)
|
||||
else
|
||||
delta = delta + (4 * (x - y) + 10)
|
||||
y = y - 1
|
||||
end
|
||||
x = x + 1
|
||||
end
|
||||
|
||||
if x == y then insertPoints(x, y) end
|
||||
end
|
||||
|
||||
local function drawCircles(xCircle, yCircle, minumumRadius, maximumRadius, step, currentRadius)
|
||||
for radius = minumumRadius, maximumRadius, step do
|
||||
if radius == currentRadius then
|
||||
circle(xCircle, yCircle, radius, 0xAAAAAA)
|
||||
else
|
||||
circle(xCircle, yCircle, radius, 0xDDDDDD)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function drawIconAndAddress(x, y, background, foreground, text)
|
||||
image.draw(x + 3, y, computerIcon)
|
||||
ecs.colorTextWithBack(x, y + 5, foreground, background, ecs.stringLimit("end", text, 14))
|
||||
return x, y, x + 13, y + 5
|
||||
end
|
||||
|
||||
local function drawHorizontalIcons()
|
||||
local height = 8
|
||||
local y = math.floor(ySize / 2 - height / 2)
|
||||
local background = 0x66A8FF
|
||||
ecs.square(1, y, xSize, height, background)
|
||||
|
||||
local iconWidth = 14
|
||||
local spaceBetween = 2
|
||||
local totalWidth = ecs.getArraySize(wirelessConnection.availableUsers) * (iconWidth + spaceBetween) - spaceBetween
|
||||
local x = math.floor(xSize / 2 - totalWidth / 2) + 1
|
||||
|
||||
obj.Users = {}
|
||||
|
||||
local counter = 0
|
||||
local limit = math.floor(xSize / (iconWidth + spaceBetween))
|
||||
y = y + 1
|
||||
for address in pairs(wirelessConnection.availableUsers) do
|
||||
if counter < limit then
|
||||
newObj("Users", address, drawIconAndAddress(x, y, background, 0xFFFFFF, address))
|
||||
end
|
||||
x = x + iconWidth + spaceBetween
|
||||
counter = counter + 1
|
||||
end
|
||||
end
|
||||
|
||||
local function drawSelectedIcon(x, y, background, foreground, text)
|
||||
local selectionWidth = 16
|
||||
local oldPixels = ecs.rememberOldPixels(x - 1, y, x + selectionWidth - 2, y + 13)
|
||||
ecs.square(x - 1, y, selectionWidth, 8, background)
|
||||
drawIconAndAddress(x, y + 1, background, foreground, text)
|
||||
obj.CykaKnopkaInfo = { ecs.drawButton(x - 1, y + 8, selectionWidth, 3, "Информация", 0xff6699, 0xFFFFFF) }
|
||||
obj.CykaKnopkaConnect = { ecs.drawButton(x - 1, y + 11, selectionWidth, 3, "Подключиться", 0xff3333, 0xFFFFFF) }
|
||||
return oldPixels
|
||||
end
|
||||
|
||||
local function connectionGUI()
|
||||
ecs.square(1, 1, xSize, ySize, 0xEEEEEE)
|
||||
|
||||
local xCircle, yCircle = math.floor(xSize / 2), ySize - 3
|
||||
local minumumRadius, maximumRadius = 7, xCircle * 0.8
|
||||
local step = 4
|
||||
local currentRadius = minumumRadius
|
||||
|
||||
drawIconAndAddress(xCircle - 6, ySize - 6, 0xEEEEEE, 0x262626, wirelessConnection.localAddress)
|
||||
|
||||
while true do
|
||||
if ecs.getArraySize(wirelessConnection.availableUsers) > 0 then
|
||||
currentRadius = 0
|
||||
drawCircles(xCircle, yCircle, minumumRadius, maximumRadius, step, currentRadius)
|
||||
|
||||
drawHorizontalIcons()
|
||||
|
||||
local oldPixels, needToUpdate
|
||||
while true do
|
||||
if not oldPixels and needToUpdate then
|
||||
if ecs.getArraySize(wirelessConnection.availableUsers) <= 0 then
|
||||
ecs.square(1, 1, xSize, ySize, 0xEEEEEE)
|
||||
drawIconAndAddress(xCircle - 6, ySize - 6, 0xEEEEEE, 0x262626, wirelessConnection.localAddress)
|
||||
currentRadius = minumumRadius
|
||||
break
|
||||
else
|
||||
drawHorizontalIcons()
|
||||
needToUpdate = false
|
||||
end
|
||||
end
|
||||
|
||||
local e = { event.pull() }
|
||||
if e[1] == "touch" then
|
||||
if oldPixels then ecs.drawOldPixels(oldPixels); oldPixels = nil end
|
||||
for address in pairs(obj.Users) do
|
||||
if ecs.clickedAtArea(e[3], e[4], obj.Users[address][1], obj.Users[address][2], obj.Users[address][3], obj.Users[address][4]) then
|
||||
oldPixels = drawSelectedIcon(obj.Users[address][1], obj.Users[address][2] - 1, 0xCCCCFF, 0x262626, address)
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif e[1] == "userlistChanged" then
|
||||
needToUpdate = true
|
||||
end
|
||||
end
|
||||
else
|
||||
drawCircles(xCircle, yCircle, minumumRadius, maximumRadius, step, currentRadius)
|
||||
currentRadius = currentRadius + step
|
||||
if currentRadius > (maximumRadius + step) then currentRadius = minumumRadius end
|
||||
os.sleep(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
function wirelessConnection.stopReceivingData()
|
||||
event.ignore("modem_message", modemMessageHandler)
|
||||
end
|
||||
|
||||
function wirelessConnection.startReceivingData()
|
||||
wirelessConnection.stopReceivingData()
|
||||
event.listen("modem_message", modemMessageHandler)
|
||||
end
|
||||
|
||||
function wirelessConnection.disconnect()
|
||||
modem.broadcast(wirelessConnection.port, "iAmDisconnecting")
|
||||
end
|
||||
|
||||
function wirelessConnection.sendPersonalData()
|
||||
wirelessConnection.disconnect()
|
||||
modem.broadcast(wirelessConnection.port, "iAmHereAddMePlease", wirelessConnection.dataToSend)
|
||||
end
|
||||
|
||||
function wirelessConnection.changePort(newPort)
|
||||
modem.close(wirelessConnection.port)
|
||||
modem.open(newPort)
|
||||
wirelessConnection.port = newPort
|
||||
wirelessConnection.remoteAddress = nil
|
||||
wirelessConnection.localAddress = component.getPrimary("modem").address
|
||||
wirelessConnection.availableUsers = {}
|
||||
createSendingArray()
|
||||
end
|
||||
|
||||
function wirelessConnection.connect()
|
||||
wirelessConnection.sendPersonalData()
|
||||
connectionGUI()
|
||||
end
|
||||
|
||||
function wirelessConnection.init()
|
||||
if component.isAvailable("modem") then
|
||||
wirelessConnection.changePort(wirelessConnection.port)
|
||||
wirelessConnection.startReceivingData()
|
||||
else
|
||||
ecs.error(infoMessages.noModem)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
wirelessConnection.init()
|
||||
wirelessConnection.sendPersonalData()
|
||||
-- wirelessConnection.connect()
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
return wirelessConnection
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user