-
Notifications
You must be signed in to change notification settings - Fork 0
/
MineBridge.txt
166 lines (146 loc) · 3.93 KB
/
MineBridge.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
local HOST = "bridge.computercraft.ru:1111"
local commandIdent = "+#"
local deviceCommandIdent = "+$"
local internet
local socket, connectedToBridge, connectedToDevice, KEY
local msgBuffer = {}
local BR = {}
function BR.split(source, delimiters)
local elements = {}
local pattern = '([^'..delimiters..']+)'
string.gsub(source, pattern, function(value) elements[#elements + 1] = value; end);
return elements
end
local function tableToJSON(arr)
local json = "{"
local delim = ""
for k, v in pairs(arr) do
json = json .. delim .."\"" .. tostring(k) .. "\":\"" .. tostring(v) .. "\""
delim = ","
end
json = json.."}"
return json
end
local function enqueue(array, n)
n = n or 1
for i = n, #array do
table.insert(msgBuffer, array[i])
end
end
local function sendInternal(str)
if not str or str == "" then return false end
local data = str.."\0"
local buff
local i = 0
while i < 4 do
buff = socket.write(data)
if not buff then
connectedToBridge = false
return false
elseif buff > 0 then
return true
end
-- RETRY IF BUFF IS 0
i = i + 1
end
return true
end
function BR.isBridgeConnected() return connectedToBridge end
function BR.isPairConnected() return connectedToDevice end
function BR.sendNotification(notif)
sendInternal(deviceCommandIdent .. "31 " .. tableToJSON(notif))
end
function BR.sendToast(text, duration)
duration = duration or 0
sendInternal(deviceCommandIdent .. "30 " .. tostring(duration) .. " " .. text)
end
function BR.send(str)
if not str or str == "" then return false end
return sendInternal("-"..str)
end
local function execCommand(cmd)
local cmdNum = string.sub(cmd, 3, 4)
if cmdNum == "00" then
--ping
sendInternal(string.sub(cmd, 1, 2) .. "01") --REPLY TO SENDER
elseif cmdNum == "01" then
--pong
elseif cmdNum == "02" then
connectedToBridge = false
--bridge stopped
elseif cmdNum == "10" then
connectedToDevice = false
--no pair
elseif cmdNum == "20" then
connectedToDevice = true
--pair found
elseif cmdNum == "21" then
connectedToDevice = false
end
end
local function isCommand(str)
if string.sub(str, 1, 1) == "+" then
return true
end
return false
end
function BR.receive()
local buff
if connectedToBridge then
buff = socket.read()
if buff == nil then --CONNECTION LOST
connectedToBridge = false
connectedToDevice = false
return nil, false
elseif #msgBuffer > 0 then --IF BUFFER HAS DATA
if buff ~= "" then --IF MESSAGE IS NOT EMPTY
enqueue(BR.split(buff, "\0"))
end
buff = table.remove(msgBuffer, 1) --GET FIRST MESSAGE FROM BUFFER
elseif buff == "" then
return buff, connectedToDevice
end
local m = BR.split(buff, "\0")
if #m > 1 then
enqueue(m, 2)
buff = m[1]
end
while true do
if isCommand(buff) then
execCommand(buff)
--return "", connectedToDevice
if(#msgBuffer > 0) then
buff = table.remove(msgBuffer, 1)
else
return "", connectedToDevice
end
else
buff = BR.split(buff, "\0")[1] --CUT \0
if buff == nil then return "", connectedToDevice end
return string.sub(buff, 2, #buff), connectedToDevice
end
end
end
return nil, false
end
function BR.init(key, newHost)
if not key or key == "" then return false end
KEY = key
HOST = newHost or HOST
internet = require("component").internet
socket = internet.connect(HOST)
if not socket then return false end
local i = 0
while not socket.finishConnect() do
if i >= 4 then
return false
end
i = i + 1
os.sleep(0.1)
end
sendInternal("KOC-"..key)
connectedToDevice = false
connectedToBridge = true
return true
end
return BR