mirror of
https://github.com/IgorTimofeev/MineOS.git
synced 2025-12-21 11:39:23 +01:00
294 lines
9.9 KiB
Lua
294 lines
9.9 KiB
Lua
|
||
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
|
||
|