· 6 years ago · Apr 11, 2020, 09:16 PM
1--[[
2- SRN v1.1.0
3- By TheQWERTYCoder
4- Modified by legomaster616
5-
6- Licensed under the GNU GPL.
7- You may copy this API as long as you...
8-
9- 1. License the copy under the GNU GPL
10- 2. Modify it in a way that changes the functionality (You can't make a copy that does the exact same thing)
11- 3. Tell the user that it is modified
12-
13- Thank you for reading!
14]]
15
16
17local localhost
18version = "1.1.0"
19
20function init(side, host)
21 api_path = settings.get("api.path")
22 if not api_path then
23 api_path = "."
24 end
25 rsa_path = api_path.."/rsa.lua"
26
27 if not fs.exists(rsa_path) then
28 error("rsa.lua not found! "..
29 "Please install to \""..api_path..
30 "\" or set api.path to correct path")
31 end
32 if not rsa then
33 os.loadAPI(rsa_path)
34 end
35 rednet.open(side) -- Make sure modem is open
36 localhost = host
37 rednet.host(
38 "SRNv"..version,
39 (
40 host or
41 os.computerLabel() or
42 tostring(os.computerID())
43 )
44 ) -- Enables srn connections
45end
46
47local function srnGetMsg(msg, com, timeout)
48 local id, data
49 local endtime = timeout and (
50 os.clock() + timeout
51 )
52
53 repeat
54 id, data = rednet.recieve("SRNv"..version, 1)
55 until (
56 (
57 (data.host == hostname(com)) or
58 (id == com) or
59 true -- why? @aa
60 ) and (
61 data.msg == msg
62 )
63 ) or (
64 timeout and os.clock() == endtime
65 )
66 return id,data
67end
68
69local function srnSendMsg(com, msg, data)
70 local ID = rednet.lookup("SRNv"..version, host)
71 rednet.send(ID, {
72 msg = msg,
73 host = localhost,
74 data = data
75 }, "SRNv"..version)
76end
77
78local srncon = {}
79function connect(host)
80 local key = rsa.new()
81 srnSendMsg(host, "CONNECT", nil)
82 srnSendMsg(host, "PUBKEY", key.public)
83 local id,data = srnGetMsg("PUBKEY",host)
84 key.public=data.data
85 srncon[host] = {
86 id = id,
87 rsa = key,
88 send = function(msg)
89 srnSendMsg(
90 self.id,
91 "DATA",
92 self.rsa.encrypt(msg)
93 )
94 end
95 }
96end
97
98local function resolveCon(host)
99 local id,data = srnGetMsg("CONNECT",host)
100 srncon[data.host] = {
101 id = host,
102 rsa = rsa.new(),
103 send = function(msg)
104 srnSendMsg(
105 self.id,
106 "DATA",
107 self.rsa.encrypt(msg)
108 )
109 end
110 }
111 rednet.send(
112 id, {
113 msg="PUBKEY",
114 host=localhost,
115 data=key.public
116 },
117 "SRNv"..version
118 )
119 local id, data = srnGetMsg("PUBKEY",id)
120 srncon[data.host].rsa.public = data.data
121end
122
123function listen(host, timeout)
124 parallel.waitForAny(
125 function()
126 resolveCon(host)
127 end,
128 function()
129 local endtime = (
130 timeout and os.clock() + timeout
131 )
132 repeat
133 until (endtime and os.clock() >= endtime)
134 end
135 )
136end
137
138local function hostname(ID)
139 for k,v in srncon do
140 if v.id == ID then
141 return k
142 end
143 end
144 return id
145end
146
147function send(host,msg)
148 if not srncon[host] then
149 connect(host)
150 end
151 srncon[host].send(msg)
152end
153
154function recieve(timeout)
155 listen(nil,timeout)
156 local id,data = srnGetMsg("DATA")
157 return srncon[data.host].rsa.decrypt(data.data)
158end