· 8 years ago · Jan 14, 2018, 07:18 PM
1local tOption = { ... }
2
3if not (#tOption == 1 or #tOption == 2 and tOption[2] == "load") then
4 error("Usage: [FNAME] <lib file>")
5end
6
7--local lib
8if type(tOption[1]) == "table" then
9 lib = tOption[1]
10elseif type(tOption[1]) == "string" then
11 if fs.exists(tOption[1]) then
12 local f = loadfile(tOption[1])
13
14 if not f then
15 error("Unable to load lib")
16 end
17
18 bOk, vResult = pcall( f )
19
20 if bOk then
21 lib = vResult
22
23 if type(lib) ~= "table" then
24 error("Lib returned wrong format")
25 end
26 else
27 error(vResult)
28 end
29 else
30 error("File not found")
31 end
32else
33 error("Wrong format")
34end
35
36----------------------------------------------------------------
37
38command = { }
39local privEnv = {
40 cRoutines = { }
41}
42
43local tCoroutine = { }
44local lastCoroutineID = 0
45
46local tServer = { }
47local lastServerID = 0
48
49local nPColor, nWColor, nEColor, nSTColor
50if term.isColor() then
51 nPColor = colors.lime
52 nWColor = colors.white
53 nEColor = colors.red
54 nSTColor = colors.orange
55else
56 nPColor = colors.lightGrey
57 nWColor = colors.white
58 nEColor = colors.white
59 nSTColor = colors.lightGrey
60end
61
62local bRunning = true
63
64-- lib.sniff.run()
65
66--[[
67
68server:
69{
70
71}
72
73user:
74{
75 nID, -- Intern userID
76 nAuthID, -- Auth ID
77 sUsername, -- Username
78 nPort, -- Port
79 cRoutines -- Table of coroutine s
80]
81
82]]
83
84----------------------------------------------------------------
85-- Command list for autoComplete
86
87local commandComplete
88do
89 local allPorts = function()
90 -- local tResult = { }
91 -- for i=0, 65535 do
92 -- table.insert(tResult, tostring( i ))
93 -- end
94 -- return tResult
95 return {
96 "65535",
97 "65533"
98 }
99 end
100
101 local getServerIDs = function()
102 local tResult = { }
103 for _, server in pairs(tServer) do
104 table.insert(tResult, tostring( server.nID ))
105 end
106 return tResult
107 end
108
109 local getSides = function()
110 return {
111 "top", "bottom",
112 "left", "right",
113 "back", "front"
114 }
115 end
116
117 local getUserIDs = function(sID)
118 local tResult = { }
119 for _, user in pairs(tServer[sID].user) do
120 table.insert(tResult, tostring( user.nID ))
121 end
122 return tResult
123 end
124
125 -- For each add to table and insert to function if fself / tself
126
127 commandComplete = {
128 add = {
129 server = {
130 tself = {
131 fself = getServerIDs
132 }
133 },
134 user = {
135 tself = {
136 fself = getServerIDs,
137 tself = {
138 fself = getUserIDs
139 }
140 }
141 }
142 },
143 chat = {
144 public = {
145 tself = {
146 fself = getServerIDs,
147 tself = {
148 fself = getUserIDs
149 }
150 }
151 },
152 private = {
153 tself = {
154 fself = getServerIDs,
155 tself = {
156 fself = getUserIDs
157 }
158 }
159 }
160 },
161 check = {
162 modem = {
163 tself = {
164 fself = getSides
165 }
166 }
167 },
168 dos = {
169 server = {
170 tself = {
171 fself = getServerIDs
172 }
173 },
174 user = {
175 tself = {
176 fself = getServerIDs,
177 tself = {
178 fself = getUserIDs
179 }
180 }
181 }
182 },
183 find = {
184 server = { },
185 user = {
186 tself = {
187 fself = getServerIDs
188 }
189 }
190 },
191 flood = {
192 start = true,
193 stop = true,
194 server = {
195 tself = {
196 fself = getServerIDs
197 }
198 },
199 user = {
200 tself = {
201 fself = getServerIDs,
202 tself = {
203 fself = getUserIDs
204 }
205 }
206 }
207 },
208 forward = {
209 },
210 get = {
211 modem = true,
212 server = {
213 tself = {
214 fself = getServerIDs
215 }
216 },
217 user = {
218 tself = {
219 fself = getServerIDs,
220 tself = {
221 fself = getUserIDs
222 }
223 }
224 }
225 },
226 help = {
227 tself = {
228 fself = function()
229 local _, h = term.getSize()
230
231 local tAllc = { }
232 for sCommand in pairs(command) do
233 table.insert(tAllc, sCommand)
234 end
235
236 local tResult = { }
237 local nlPage = #tAllc / (h - 2)
238 nlPage = nlPage - (nlPage % 1) + 1
239 for nIter = 1, nlPage do
240 table.insert(tResult, nIter)
241 end
242 return tResult
243 end
244 }
245 },
246 hijack = {
247
248 },
249 interact = {
250 server = {
251 tself = {
252 fself = getServerIDs
253 }
254 },
255 user = {
256 tself = {
257 fself = getServerIDs,
258 tself = {
259 fself = getUserIDs
260 }
261 }
262 }
263 },
264 kick = {
265 tself = {
266 fself = getServerIDs,
267 tself = {
268 fself = getUserIDs
269 }
270 }
271 },
272 kill = {
273 server = {
274 tself = {
275 fself = getServerIDs
276 }
277 },
278 user = {
279 tself = {
280 fself = getServerIDs,
281 tself = {
282 fself = getUserIDs
283 }
284 }
285 }
286 },
287 list = {
288 server = true,
289 user = {
290 tself = {
291 fself = getServerIDs
292 }
293 }
294 },
295 new = {
296 croutine = {
297 userMSave = {
298 tself = {
299 fself = getServerIDs,
300 tself = {
301 fself = getUserIDs
302 }
303 }
304 },
305 userPing = {
306 tself = {
307 fself = getServerIDs,
308 tself = {
309 fself = getUserIDs
310 }
311 }
312 }
313 },
314 server = {
315
316 },
317 user = {
318 tself = {
319 fself = getServerIDs,
320 tself = {
321 fself = allPorts
322 }
323 }
324 }
325 },
326 remove = {
327 server = {
328 tself = {
329 fself = getServerIDs
330 }
331 },
332 user = {
333 tself = {
334 fself = getServerIDs,
335 tself = {
336 fself = getUserIDs
337 }
338 }
339 }
340 },
341 routines = {
342 server = {
343 tself = {
344 fself = getServerIDs
345 }
346 },
347 user = {
348 tself = {
349 fself = getServerIDs,
350 tself = {
351 fself = getUserIDs
352 }
353 }
354 }
355 },
356 scan = {
357 server = {
358 all = {
359 start = true,
360 stop = true
361 },
362 tself = {
363 fself = getServerIDs,
364 start = true,
365 stop = true
366 }
367 },
368 user = {
369 tself = {
370 all = {
371 start = true,
372 stop = true
373 },
374 fself = getServerIDs,
375 tself = {
376 fself = getUserIDs,
377 start = true,
378 stop = true
379 }
380 }
381 }
382 },
383 set = {
384 modem = {
385 tself = {
386 fself = getSides
387 }
388 },
389 server = {
390 tself = {
391 fself = getServerIDs,
392 nPort = true,
393 sHostname = true
394 }
395 },
396 user = {
397 tself = {
398 fself = getServerIDs,
399 tself = {
400 fself = getUserIDs,
401 nAuthID = true,
402 nPort = true,
403 sName = true
404 }
405 }
406 }
407 },
408 unset = {
409 server = {
410 tself = {
411 fself = getServerIDs,
412 nPort = true,
413 sHostname = true
414 }
415 },
416 user = {
417 tself = {
418 fself = getServerIDs,
419 tself = {
420 fself = getUserIDs,
421 nAuthID = true,
422 nPort = true,
423 sName = true
424 }
425 }
426 }
427 }
428 }
429end
430
431----------------------------------------------------------------
432
433command.add = function(sType, p1, p2, p3)
434 if sType == "server" then
435 local n = tonumber(p1)
436 if n == nil then
437 return "Port as number expected", true
438 end
439
440 if not (n >= 0 and n <= 65535) then
441 return "Port is not in range", true
442 end
443
444 for _, server in pairs(tServer) do
445 if server.nPort == p1 then
446 return "Server already exists", true
447 end
448 end
449
450 lastServerID = lastServerID + 1
451
452 tServer[tostring( lastServerID )] =
453 {
454 cRoutines = { },
455 lastUserID = 0,
456 nID = tostring( lastServerID ),
457 nPort = p1,
458 sHostname = "",
459 user = { },
460 wTable = { } -- write ing table
461 }
462
463 return "Server was added"
464 elseif sType == "user" then
465 if tServer[ p1 ] then
466 local n = tonumber(p2)
467 if n == nil then
468 return "Port as number expected", true
469 end
470
471 if not (n >= 0 and n <= 65535) then
472 return "Port is not in range", true
473 end
474
475 for _, user in pairs(tServer[p1].user) do
476 if user.nPort == p2 then
477 return "User already exists", true
478 end
479 end
480
481 tServer[p1].lastUserID = tServer[p1].lastUserID + 1
482
483 tServer[p1].user[ tostring( tServer[p1].lastUserID ) ] =
484 {
485 cRoutines = { },
486 nAuthID = -1,
487 nID = tostring( tServer[p1].lastUserID ),
488 nPort = p2,
489 sName = "",
490 wTable = { } -- write ing table
491 }
492
493 return "User was added"
494 else
495 return "Server not found", true
496 end
497 else
498 return "Option not found", true
499 end
500end
501
502command.chat = function(sType, p1, p2, p3)
503 if sType == "public" then
504 if not tServer[ p1 ] then
505 return "Server not found", true
506 end
507
508 if not tServer[ p1 ].user[ p2 ] then
509 return "User not found", true
510 end
511
512 if tServer[ p1 ].user[ p2 ].nAuthID == -1 then
513 return "No authID selected", true
514 end
515
516 if privEnv.modem == nil then
517 return "No modem selected", true
518 end
519
520 if not p3 then
521 return "Message expected", true
522 end
523
524 lib.spoof.message(
525 peripheral.wrap(privEnv.modem),
526 tServer[p1].nPort,
527 tServer[p1].user[p2].nPort,
528 tServer[p1].user[p2].nPort,
529 {
530 sType = "chat",
531 nUserID = tServer[p1].user[p2].nAuthID,
532 sText = p3
533 },
534 "chat")
535
536 return "Message was sent"
537 elseif sType == "private" then
538 if not tServer[ p1 ] then
539 return "Server not found", true
540 end
541
542 if not tServer[ p1 ].user[ p2 ] then
543 return "User not found", true
544 end
545
546 if tServer[ p1 ].user[ p2 ].nAuthID == -1 then
547 return "No authID selected", true
548 end
549
550 if privEnv.modem == nil then
551 return "No modem selected", true
552 end
553
554 lib.spoof.message(
555 peripheral.wrap(privEnv.modem),
556 tServer[p1].user[p2].nPort,
557 tServer[p1].nPort,
558 tServer[p1].nPort,
559 {
560 sType = "text",
561 nUserID = tServer[p1].user[p2].nAuthID,
562 sText = p3
563 },
564 "chat")
565
566 return "Message was sent"
567 else
568 return "Option not found", true
569 end
570end
571
572command.check = function(sType, p1, p2)
573 if sType == "modem" then
574 if type(p1) ~= "string" then
575 p1 = privEnv.modem
576 end
577
578 if type(p1) ~= "string" then
579 return "No modem selected", true
580 end
581
582 if peripheral.getType(p1) == "modem" then
583 if term.isColor() then
584 term.setTextColor(colors.green)
585 end
586
587 return "Modem is working"
588 else
589 return "Modem is notre work", true
590 end
591 elseif sType == "server" then
592 if not tServer[ p1 ] then
593 return "Server not found", true
594 end
595
596 if not privEnv.modem then
597 return "No modem selected", true
598 end
599
600 local tHosts = lib.scann.lookupHosts(privEnv.modem, "chat")
601
602 local bFound = false
603 for _, tHost in pairs(tHosts) do
604 if tHost.nRecipient == tonumber( tServer[p1].nPort ) then
605 bFound = true
606 break
607 end
608 end
609
610 if bFound then
611 return "Server is reachable"
612 end
613
614 return "Server is unrechable"
615 elseif sType == "user" then
616 -- Ping to client and wait for pong
617
618 if not tServer[ p1 ] then
619 return "Server not found", true
620 end
621
622 if not tServer[ p1 ].user[ p2 ] then
623 return "User not found", true
624 end
625
626 if tServer[ p1 ].user[ p2 ].nAuthID == -1 then
627 return "No authID selected", true
628 end
629
630 if privEnv.modem == nil then
631 return "No modem selected", true
632 end
633
634 local nHost = lib.sniff.addHost(
635 tServer[p1].nPort,
636 tServer[p1].user[p2].nPort,
637 privEnv.modem)
638
639 lib.spoof.message(
640 peripheral.wrap(privEnv.modem),
641 tServer[p1].user[p2].nPort,
642 tServer[p1].nPort,
643 tServer[p1].nPort,
644 {
645 sType = "ping to client",
646 nUserID = tServer[p1].user[p2].nAuthID
647 },
648 "chat")
649
650 local bFound = true
651 local nTimer = os.startTimer(2)
652 while true do
653 local sEvent, vData, nPort, nReplyPort, tMessage, nDistance
654 = os.pullEvent()
655
656 if sEvent == "sniff_message" and vData == nHost then
657 local message = lib.sniff.parseRednet(tMessage)
658
659 if message
660 and tMessage.sProtocol == "chat"
661 and message.sType == "pong to server"
662 and message.nUserID == tServer[p1].user[p2].nAuthID then
663 break
664 end
665 elseif sEvent == "timer" and vData == nTimer then
666 bFound = false
667 break
668 end
669 end
670
671 lib.sniff.removeHost(nHost)
672
673 if bFound then
674 if term.isColor() then
675 term.setTextColor(colors.green)
676 end
677
678 return "User is rechable"
679 else
680 return "User is unrechable", true
681 end
682 else
683 return "Option not found", true
684 end
685end
686
687command.dos = function(sType, p1, p2)
688 if sType == "server" then
689 if not tServer[ p1 ] then
690 return "Server not found", true
691 end
692
693 if privEnv.modem == nil then
694 return "No modem selected", true
695 end
696
697 local rPort = math.random(60000, 65532)
698 lib.spoof.message(
699 peripheral.wrap(privEnv.modem),
700 tServer[p1].nPort,
701 rPort,
702 rPort,
703 {
704 sType = "login",
705 nUserID = true,
706 sUsername = true -- Error (Can't concat bool)
707 },
708 "chat")
709
710 return "Dos was performed"
711 elseif sType == "user" then
712 if not tServer[ p1 ] then
713 return "Server not found", true
714 end
715
716 if not tServer[ p1 ].user[ p2 ] then
717 return "User not found", true
718 end
719
720 if tServer[ p1 ].user[ p2 ].nAuthID == -1 then
721 return "No authID selected", true
722 end
723
724 if privEnv.modem == nil then
725 return "No modem selected", true
726 end
727
728 lib.spoof.message(
729 peripheral.wrap(privEnv.modem),
730 tServer[p1].user[p2].nPort,
731 tServer[p1].nPort,
732 tServer[p1].nPort,
733 {
734 sType = "text",
735 nUserID = tServer[p1].user[p2].nAuthID,
736 sText = true -- Error (Can't concat bool)
737 },
738 "chat")
739
740 return "Dos was performed"
741 else
742 return "Option not found", true
743 end
744end
745
746command.find = function(sType, p1)
747 if sType == "server" then -- Add only NEW
748 if privEnv.modem == nil then
749 return "No modem selected", true
750 end
751
752 local tHosts = lib.scann.lookupHosts(privEnv.modem, "chat")
753
754 for _, tHost in pairs(tHosts) do
755 command.add("server", tostring( tHost.nRecipient ))
756 local tID, bErr = command.get("port", tostring( tHost.nRecipient ))
757
758 if not bErr
759 and type(tID) == "table"
760 and type(tID.sType) == "string"
761 and tID.sType == "server" then
762 command.set("server", tID.nID, "sHostname",
763 tostring( tHost.sHostname ))
764 end
765 end
766
767 return #tHosts.." host(s) found"
768 elseif sType == "user" then -- Add only NEW
769 if not tServer[ p1 ] then
770 return "Server not found", true
771 end
772
773 local tUser = { }
774
775 local nHost = sniff.addHost(
776 tServer[p1].nPort, nil, privEnv.modem)
777
778 local nTimer = os.startTimer(15)
779 while true do
780 local sEvent, vData, nPort, nReplyPort, tMessage, nDistance
781 = os.pullEvent()
782
783 if sEvent == "sniff_message" then
784 local message = sniff.parseRednet(tMessage)
785
786 if message
787 and tMessage.sProtocol == "chat"
788 and type(message.sType) == "string"
789 and message.sType == "ping to server" then
790 table.insert(tUser, { nReplyPort, tMessage })
791 end
792 elseif sEvent == "timer" and nTimer == vData then
793 break
794 end
795 end
796
797 sniff.removeHost(nHost)
798
799 for _, aUser in pairs(tUser) do
800 command.add("user", p1, aUser[1])
801 local tID, bErr = command.get("port", aUser[1])
802
803 if not bErr
804 and type(tID) == "table" then
805 command.set("user", p1, tID.nID, "nAuthID",
806 aUser[2].message.nUserID)
807 end
808 end
809
810 return #tUser.." user(s) found"
811 else
812 return "Option not found", true
813 end
814end
815
816command.flood = function(p1, p2, p3)
817 if p1 == "start" then
818 if privEnv.modem == nil then
819 return "No modem selected", true
820 end
821
822 if privEnv.cRoutines.flood then
823 return "Flood already exists", true
824 end
825
826 local lPort = nil
827 if tServer[ p2 ] then
828 lPort = tServer[p2].nPort
829 end
830
831 privEnv.cRoutines.flood =
832 {
833 bRunning = true,
834 name = "Chat dns flood",
835 routine = coroutine.create(function()
836 lib.dos.dns_flood(
837 privEnv.modem,
838 lPort,
839 "dns",
840 15,
841 53824)
842 end)
843 }
844
845 coroutine.resume(privEnv.cRoutines.flood.routine)
846
847 return "Flood was started"
848 elseif p1 == "stop" then
849 os.queueEvent("timer", 53824)
850 return "Flood was stoped"
851 end
852
853 local sType = p1
854 p1, p2 = p2, p3
855 if sType == "server" then
856
857 elseif sType == "user" then
858 else
859 return "Option not found", true
860 end
861end
862
863command.forward = function(sType, p1, p2)
864
865end
866
867command.get = function(sType, p1, p2)
868 if sType == "modem" then
869 if type(privEnv.modem) ~= "string" then
870 return "No modem saved", true
871 end
872
873 return privEnv.modem
874 elseif sType == "port" then
875 local n = tonumber(p1)
876
877 if n and n >= 0 and n <= 65535 then
878 for _, server in pairs(tServer) do
879 if server.nPort == p1 then
880 return {
881 nID = server.nID,
882 sType = "server"
883 }
884 end
885
886 for _, user in pairs(server.user) do
887 if user.nPort == p1 then
888 return {
889 nID = user.nID,
890 sType = "user"
891 }
892 end
893 end
894 end
895 else
896 return "Port not in range", true
897 end
898 elseif sType == "server" then
899 if tServer[ p1 ] then
900 return {
901 nID = tServer[p1].nID,
902 nPort = tServer[p1].nPort,
903 sHostname = tServer[p1].sHostname
904 }
905 else
906 return "Server not found", true
907 end
908 elseif sType == "user" then
909 if tServer[ p1 ] then
910 if tServer[ p1 ].user[ p2 ] then
911 return {
912 nAuthID = tServer[ p1 ].user[ p2 ].nAuthID,
913 nID = tServer[ p1 ].user[ p2 ].nID,
914 nPort = tServer[ p1 ].user[ p2 ].nPort,
915 sName = tServer[ p1 ].user[ p2 ].sName
916 }
917 else
918 return "User not found", true
919 end
920 else
921 return "Server not found", true
922 end
923 else
924 return "Option not found", true
925 end
926end
927
928command.help = function(sStart)
929 if tonumber(sStart) == nil then
930 sStart = 1
931 end
932 local _, h = term.getSize()
933
934 local tAllc = { }
935 for sCommand in pairs(command) do
936 table.insert(tAllc, sCommand)
937 end
938
939 table.sort(tAllc)
940 local nlPage = #tAllc / (h - 2)
941 nlPage = nlPage - (nlPage % 1) + 1
942
943 local nfPage = (h - 2) * (sStart - 1) + 1
944
945 local nIter = nfPage
946 local tResult = { }
947 for i = 1, h - 2 do
948 table.insert(tResult, tAllc[nIter])
949 nIter = nIter + 1
950 end
951
952 tResult.Page = sStart.." / "..nlPage
953
954 return tResult
955end
956
957command.hijack = function(sType, p1, p2)
958 --[[
959 user:
960 - kick user and create new c R o u t i n e
961
962 'Server timeout, closing c R o u t i n e . . .'
963 'Server tried to kick you'
964
965 messages in >> message -> { table }
966 ]]
967 if sType == "server" then
968
969 elseif sType == "user" then
970 --[[
971 if not tServer[ p1 ] then
972 return "Server not found", true
973 end
974
975 if not tServer[ p1 ].user[ p2 ] then
976 return "User not found", true
977 end
978
979 if tServer[ p1 ].user[ p2 ].nAuthID == -1 then
980 return "No authID selected", true
981 end
982
983 if privEnv.modem == nil then
984 return "No modem selected", true
985 end
986
987 local sMess, bErr = command.kick(p1, p2)
988 if bErr then
989 return "Error at kicking: "..sMess, true
990 end
991
992 sMess, bErr = nil, nil
993
994 sMess, bErr = command.new("croutine", "user", p1, p2)
995 if bErr then
996 return "Error at creating routine: "..sMess, true
997 end
998
999 return "User was successfully hijacked"
1000 ]]
1001 else
1002 return "Option not found", true
1003 end
1004end
1005
1006command.interact = function(sType, p1, p2)
1007 if sType == "server" then
1008 -- Server shell
1009
1010
1011 elseif sType == "user" then
1012 -- User shell
1013 if not tServer[ p1 ] then
1014 return "Server not found", true
1015 end
1016
1017 if not tServer[ p1 ].user[ p2 ] then
1018 return "User not found", true
1019 end
1020
1021 if tServer[ p1 ].user[ p2 ].nAuthID == -1 then
1022 return "No authID selected", true
1023 end
1024
1025 if privEnv.modem == nil then
1026 return "No modem selected", true
1027 end
1028
1029 local bRemove = false
1030 if not tServer[p1].user[p2].cRoutines.userMSave then
1031 bRemove = true
1032 local sMess, bErr = command.new("croutine", "userMSave", p1, p2)
1033
1034 if bErr then
1035 return "Error at creating routine: "..sMess, true
1036 end
1037 end
1038
1039 local currentInput = ""
1040 local getInput = function(input)
1041 currentInput = input
1042 end
1043
1044 local dnPColor, dnWColor, dnEColor
1045 if term.isColor() then
1046 dnPColor = colors.orange
1047 dnWColor = colors.white
1048 dnEColor = colors.red
1049 else
1050 nPColor = colors.lightGrey
1051 dnWColor = colors.white
1052 dnEColor = colors.white
1053 end
1054
1055 local lastMessageID = 1
1056 local nTimer = os.startTimer(0.1)
1057 local native_pullEventRaw = os.pullEventRaw
1058 os.pullEventRaw = function(...)
1059 local tEvent = { native_pullEventRaw(...) }
1060
1061 if tEvent[1] == "timer" and tEvent[2] == nTimer then
1062 nTimer = os.startTimer(0.1)
1063
1064 local bNew = false
1065 if lastMessageID <= #tServer[p1].user[p2].wTable then
1066 bNew = true
1067 local w, h = term.getCursorPos()
1068 term.setCursorPos(1, h)
1069 end
1070
1071 for i = lastMessageID, #tServer[p1].user[p2].wTable do
1072 lastMessageID = lastMessageID + 1
1073 term.clearLine()
1074 print(tServer[p1].user[p2].wTable[i])
1075 end
1076
1077 if bNew then
1078 term.clearLine()
1079 term.setTextColor(dnPColor)
1080 write("-> ")
1081
1082 term.setTextColor(dnWColor)
1083 write(currentInput)
1084 end
1085 end
1086
1087 return table.unpack(tEvent)
1088 end
1089
1090 local modem = peripheral.wrap(privEnv.modem)
1091
1092 local tHistory = { }
1093 while true do
1094 term.clearLine()
1095 term.setTextColor(dnPColor)
1096 write("-> ")
1097
1098 term.setTextColor(dnWColor)
1099 local stCommand = read(nil, tHistory, getInput)
1100 table.insert(tHistory, stCommand)
1101
1102 local bFirst = true
1103 local sCommand = ""
1104 local tParm = { }
1105 for sSplit in string.gmatch(stCommand, "[%p%w]+") do
1106 if bFirst then
1107 sCommand = string.lower( sSplit )
1108 bFirst = false
1109 else
1110 table.insert(tParm, sSplit)
1111 end
1112 end
1113
1114 local sMess, bErr = "", false
1115 if string.find(sCommand, "^!") then
1116 sCommand = string.match(sCommand, ".(.+)")
1117 if sCommand == "exit" then
1118 break
1119 end
1120 elseif string.find(sCommand, "^?") then
1121 stCommand = string.match(stCommand, ".(.+)")
1122 local sMess, bErr = command.chat("private", p1, p2, stCommand)
1123 else
1124 if string.find(sCommand, "^:") then
1125 stCommand = string.match(stCommand, ".(.+)")
1126 end
1127
1128 local sMess, bErr = command.chat("public", p1, p2, stCommand)
1129 end
1130
1131 if bErr then
1132 printError(sMess)
1133 end
1134 end
1135
1136 os.pullEventRaw = native_pullEventRaw
1137
1138 if bRemove then
1139 tServer[p1].user[p2].cRoutines.userMSave = nil
1140 end
1141 else
1142 return "Option not found", true
1143 end
1144end
1145
1146command.kick = function(sID, uID)
1147 if not tServer[ sID ] then
1148 return "Server not found", true
1149 end
1150
1151 if not tServer[ sID ].user[ uID ] then
1152 return "User not found", true
1153 end
1154
1155 if tServer[ sID ].user[ uID ].nAuthID == -1 then
1156 return "No authID selected", true
1157 end
1158
1159 if privEnv.modem == nil then
1160 return "No modem selected", true
1161 end
1162
1163 if #tServer[sID].user[uID].cRoutines ~= 0 then
1164 return "Unable to kick player with routines\n"..
1165 "Instead use 'kill'", true
1166 end
1167
1168 local modem = peripheral.wrap( privEnv.modem )
1169
1170 lib.spoof.message(
1171 modem,
1172 tServer[sID].user[uID].nPort,
1173 tServer[sID].nPort,
1174 tServer[sID].nPort,
1175 {
1176 sType = "kick",
1177 nUserID = tServer[sID].user[uID].nAuthID
1178 },
1179 "chat")
1180end
1181
1182command.kill = function(sType, p1, p2)
1183 if sType == "server" then
1184 if not tServer[ p1 ] then
1185 return "Server not found", true
1186 end
1187
1188 if privEnv.modem == nil then
1189 return "No modem selected", true
1190 end
1191
1192 for nID, user in pairs(tServer[p1].user) do
1193 if #user.cRoutines > 0 then
1194 for _, routine in pairs(user.cRoutines) do
1195 routine.bRunning = false
1196 end
1197 else
1198 command.kick(p1, nID)
1199 end
1200 end
1201
1202 local sPrefix = ""
1203 if #tServer[p1].cRoutines > 0 then
1204 sPrefix = "VIRTUAL"
1205
1206 for _, routine in pairs(tServer[p1].cRoutines) do
1207 routine.bRunning = false
1208 end
1209 else
1210 sPrefix = "REAL"
1211
1212 local vResult, bErr command.dos("server", p1)
1213
1214 if bErr then
1215 return "Error during dos: "..vResult, true
1216 end
1217 end
1218
1219 tServer[p1] = nil
1220
1221 return sPrefix.." server was killed"
1222 elseif sType == "user" then
1223 if not tServer[ p1 ] then
1224 return "Server not found", true
1225 end
1226
1227 if not tServer[ p1 ].user[ p2 ] then
1228 return "User not found", true
1229 end
1230
1231 if privEnv.modem == nil then
1232 return "No modem selected", true
1233 end
1234
1235 local sPrefix = ""
1236 if #tServer[p1].user[p2].cRoutines > 0 then
1237 sPrefix = "VIRTUAL"
1238
1239 for _, routine in pairs(tServer[p1].user[p2].cRoutines) do
1240 routine.bRunning = false
1241 end
1242 else
1243 sPrefix = "REAL"
1244
1245 local vResult, bErr command.dos("user", p1, p2)
1246
1247 if bErr then
1248 return "Error during dos: "..vResult, true
1249 end
1250 end
1251
1252 tServer[p1].user[p2] = nil
1253
1254 return sPrefix.." user was killed"
1255 else
1256 return "", true
1257 end
1258end
1259
1260command.list = function(sType, p1)
1261 if sType == "server" then
1262 local tResult = { }
1263
1264 for _, id in pairs(tServer) do
1265 table.insert(tResult, id.nID)
1266 end
1267
1268 return tResult
1269 elseif sType == "user" then
1270 if not tServer[ p1 ] then
1271 return "Server not found", true
1272 end
1273
1274 local tResult = { }
1275
1276 for _, id in pairs(tServer[p1].user) do
1277 table.insert(tResult, id.nID)
1278 end
1279
1280 return tResult
1281 else
1282 return "Option not found", true
1283 end
1284end
1285
1286command.new = function(sType, p1, p2, p3)
1287 if sType == "croutine" then
1288 if p1 == "userMSave" then
1289 if not tServer[ p2 ] then
1290 return "Server not found", true
1291 end
1292
1293 if not tServer[ p2 ].user[ p3 ] then
1294 return "User not found", true
1295 end
1296
1297 if privEnv.modem == nil then
1298 return "No modem selected", true
1299 end
1300
1301 if tServer[ p2 ].user[ p3 ].nAuthID == -1 then
1302 return "No authID selected", true
1303 end
1304
1305 if tServer[p2].user[p3].cRoutines.userMSave then
1306 return "UserMSave routine already exists for user "..
1307 tServer[p2].user[p2].nID, true
1308 end
1309
1310 local nHost = lib.sniff.addHost(
1311 tServer[p2].user[p3].nPort,
1312 tServer[p2].nPort,
1313 privEnv.modem)
1314
1315 tServer[p2].user[p3].cRoutines.userMSave =
1316 {
1317 bRunning = true,
1318 name = "User traffic saver",
1319 routine = coroutine.create( function()
1320 local self = tServer[p2].user[p3].cRoutines.userMSave
1321 local wTable = tServer[p2].user[p3].wTable
1322
1323 local nServerPort = tServer[p2].nPort
1324 local nUserID = tServer[p2].user[p3].nAuthID
1325 local nUserPort = tServer[p2].user[p3].nPort
1326
1327 local nHost = nHost
1328
1329 while self.bRunning do
1330 local sEvent, vData, nPort, nReplyPort, tMessage, nDistance
1331 = os.pullEvent()
1332
1333 if sEvent == "sniff_message" and vData == nHost then
1334 local message = lib.sniff.parseRednet(tMessage)
1335
1336 if message and tMessage.sProtocol == "chat" then
1337 if message.sType == "kick" then
1338 table.insert(wTable, "Kicked by server, closing routine...")
1339 break
1340 elseif message.sType == "text" then
1341 table.insert(wTable, message.sText)
1342 end
1343 end
1344 end
1345 end
1346
1347 lib.sniff.removeHost(nHost)
1348 end)
1349 }
1350
1351 coroutine.resume( tServer[p2].user[p3].cRoutines.userMSave.routine )
1352
1353
1354 elseif p1 == "userPing" then
1355 --[[
1356
1357 Split user routine:
1358 - Reply on ping with pong
1359 - Save text messages to wTable
1360
1361 ]]
1362
1363 if not tServer[ p2 ] then
1364 return "Server not found", true
1365 end
1366
1367 if not tServer[ p2 ].user[ p3 ] then
1368 return "User not found", true
1369 end
1370
1371 if privEnv.modem == nil then
1372 return "No modem selected", true
1373 end
1374
1375 if tServer[ p2 ].user[ p3 ].nAuthID == -1 then
1376 return "No authID selected", true
1377 end
1378
1379 if tServer[p2].user[p3].cRoutines.userPing then
1380 return "UserPing routine already exists for user "..
1381 tServer[p2].user[p2].nID, true
1382 end
1383
1384 local nHost = lib.sniff.addHost(
1385 tServer[p2].user[p3].nPort,
1386 tServer[p2].nPort,
1387 privEnv.modem)
1388
1389 tServer[p2].user[p3].cRoutines.userPing =
1390 {
1391 bRunning = true,
1392 name = "User ping-pong with server",
1393 routine = coroutine.create( function()
1394 local self = tServer[p2].user[p3].cRoutines.userPing
1395
1396 local pModem = peripheral.wrap(privEnv.modem)
1397 local wTable = tServer[p2].user[p3].wTable
1398
1399 local nServerPort = tServer[p2].nPort
1400 local nUserID = tServer[p2].user[p3].nAuthID
1401 local nUserPort = tServer[p2].user[p3].nPort
1402
1403 local nHost = nHost
1404
1405 while self.bRunning do
1406 local sEvent, vData, nPort, nReplyPort, tMessage, nDistance
1407 = os.pullEvent()
1408
1409 if sEvent == "sniff_message" and vData == nHost then
1410 local message = lib.sniff.parseRednet(tMessage)
1411
1412 if message
1413 and tMessage.sProtocol == "chat"
1414 and message.sType == "ping to client" then
1415 lib.spoof.message(
1416 pModem,
1417 nServerPort,
1418 nUserPort,
1419 nUserPort,
1420 {
1421 sType = "pong to server",
1422 nUserID = nUserID
1423 },
1424 "chat")
1425 end
1426 end
1427 end
1428
1429 lib.sniff.removeHost(nHost)
1430 end)
1431 }
1432
1433 coroutine.resume( tServer[p2].user[p3].cRoutines.userPing.routine )
1434 elseif p1 == "server" then
1435 if not tServer[ p1 ] then
1436 return "Server not found", true
1437 end
1438 else
1439 return "Sub-option not found", true
1440 end
1441 elseif sType == "server" then
1442
1443 elseif sType == "user" then
1444 if not tServer[ p1 ] then
1445 return "Server not found", true
1446 end
1447
1448 if privEnv.modem == nil then
1449 return "No modem selected", true
1450 end
1451
1452 if p3 == nil then
1453 return "Name expected", true
1454 end
1455
1456 local vMess, bErr =
1457 command.add("user", p1, p2)
1458
1459 if bErr then
1460 return vMess, true
1461 end
1462
1463 local uID = tostring( tServer[p1].lastUserID )
1464 tServer[p1].user[uID].sName = p3
1465 tServer[p1].user[uID].nAuthID = math.random(1, 2147483647)
1466
1467 command.new("croutine", "userPing", p1, uID)
1468 command.new("croutine", "userMSave", p1, uID)
1469
1470 lib.spoof.message(
1471 peripheral.wrap(privEnv.modem),
1472 tServer[p1].nPort,
1473 tServer[p1].user[uID].nPort,
1474 tServer[p1].user[uID].nPort,
1475 {
1476 sType = "login",
1477 nUserID = tServer[p1].user[uID].nAuthID,
1478 sUsername = p3
1479 },
1480 "chat")
1481
1482 return "New user created", true
1483 else
1484 return "Option not found", true
1485 end
1486end
1487
1488command.remove = function(sType, p1, p2)
1489 if sType == "server" then
1490 if tServer[ p1 ] then
1491 tServer[p1] = nil
1492 return "Server was removed"
1493 else
1494 return "Server not found", true
1495 end
1496 elseif sType == "user" then
1497 if tServer[ p1 ] then
1498 if tServer[ p1 ].user[ p2 ] then
1499 tServer[p1].user[p2] = nil
1500 return "User was removed"
1501 else
1502 return "User not found", true
1503 end
1504 else
1505 return "Server not found", true
1506 end
1507 else
1508 return "Option not found", true
1509 end
1510end
1511
1512command.scan = function(sType, p1, p2, p3)
1513 if sType == "server" then
1514 if not tServer[ p1 ] then
1515 return "Server not found", true
1516 end
1517
1518 if p2 == "start" then
1519
1520 elseif p2 == "stop" then
1521
1522 else
1523 return "Sub-option not found", true
1524 end
1525 elseif sType == "user" then
1526 if not tServer[ p1 ] then
1527 return "Server not found", true
1528 end
1529
1530 if privEnv.modem == nil then
1531 return "No modem selected", true
1532 end
1533
1534 if p2 == "all" then
1535 if p3 ~= "start" and p3 ~= "stop" then
1536 return "Sub-option not found", true
1537 end
1538
1539 for _, user in pairs(tServer[p1].user) do
1540 local sMess, bErr = command.scan("user", p1, user.nID, p3)
1541 end
1542
1543 return "All scans "..p3.."ed"
1544 end
1545
1546 if not tServer[ p1 ].user[ p2 ] then
1547 return "User not found", true
1548 end
1549
1550 if tServer[ p1 ].user[ p2 ].nAuthID == -1 then
1551 return "No authID selected", true
1552 end
1553
1554 if p3 == "start" then
1555 if tServer[p1].user[p2].cRoutines.scan
1556 and tServer[p1].user[p2].cRoutines.scan.bRunning then
1557 return "Scann already started", true
1558 end
1559
1560 print(p1)
1561 print(p2)
1562
1563 local nHost = lib.sniff.addHost(
1564 tServer[p1].user[p2].nPort,
1565 tServer[p1].nPort,
1566 privEnv.modem)
1567
1568 print(nHost)
1569
1570 tServer[p1].user[p2].cRoutines.scan = {
1571 bRunning = true,
1572 name = "User scanner"
1573 }
1574
1575 tServer[p1].user[p2].cRoutines.scan.routine = coroutine.create( function()
1576 local self = tServer[p1].user[p2].cRoutines.scan
1577
1578 local nServerID = p1
1579 local nUserID = p2
1580 local nlHost = nHost
1581
1582 print(nServerID)
1583 print(nUserID)
1584
1585 while self.bRunning do
1586 local sEvent, vData, nPort, nReplyPort, tMessage, nDistance
1587 = os.pullEvent()
1588
1589 if sEvent == "sniff_message" and vData == nlHost then
1590 local message = lib.sniff.parseRednet(tMessage)
1591
1592 print("PRE"..vData.."=="..nlHost)
1593
1594 if message
1595 and tMessage.sProtocol == "chat"
1596 and nPort == tServer[nServerID].user[nUserID].nPort then
1597 if message.sType == "text"
1598 and string.find(message.sText, "^<.+> .*$") then
1599 print("SETTING NAME FOR"..nUserID)
1600
1601 tServer[nServerID].user[nUserID].sName
1602 = string.match(message.sText, "^<(.+)> .*$")
1603 tServer[nServerID].user[nUserID].nAuthID
1604 = message.nUserID
1605
1606 self.name = self.name.." (finished)"
1607 break
1608 end
1609 end
1610 end
1611 end
1612
1613 lib.sniff.removeHost(nlHost)
1614 end)
1615
1616 print("END"..p2)
1617
1618 coroutine.resume(tServer[p1].user[p2].cRoutines.scan.routine)
1619 elseif p3 == "stop" then
1620 if tServer[p1].user[p2].cRoutines.scan == nil
1621 or tServer[p1].user[p2].cRoutines.scan.bRunning == false then
1622 return "Scann is not started", true
1623 end
1624
1625 tServer[p1].user[p2].cRoutines.scan.bRunning = false
1626 os.queueEvent("update")
1627 else
1628 return "Sub-option not found", true
1629 end
1630 else
1631 return "Option not found", true
1632 end
1633end
1634
1635command.sessions = function(sType, p1, p2)
1636 if sType == "server" then
1637 if not tServer[ p1 ] then
1638 return "Server not found", true
1639 end
1640
1641
1642 elseif sType == "user" then
1643 if not tServer[ p1 ] then
1644 return "Server not found", true
1645 end
1646
1647 if not tServer[ p1 ].user[ p2 ] then
1648 return "User not found", true
1649 end
1650
1651 if tServer[ p1 ].user[ p2 ].nAuthID == -1 then
1652 return "No authID selected", true
1653 end
1654
1655 local tResult = { }
1656 for _, routine in pairs(tServer[p1].user[p2].cRoutines) do
1657 table.insert(tResult, routine.name)
1658 end
1659 if #tResult == 0 then
1660 return "No routines found"
1661 else
1662 return tResult
1663 end
1664 else
1665 return "Option not found", true
1666 end
1667
1668 -- Print current sessions
1669end
1670
1671command.set = function(sType, p1, p2, p3, p4)
1672 if sType == "modem" then
1673 if type(p1) ~= "string" then
1674 return "String as side expected", true
1675 end
1676
1677 privEnv.modem = p1
1678
1679 return "Modem side was changed"
1680 elseif sType == "server" then
1681 if not tServer[ p1 ] then
1682 return "Server not found", true
1683 end
1684
1685 if p2 == "nPort" then
1686 local isNumber = tonumber(p3)
1687
1688 if not isNumber then
1689 return "Port as number expected", true
1690 end
1691
1692 if not (isNumber >= 0 and isNumber <= 65535) then
1693 return "Port is not in range", true
1694 end
1695 end
1696
1697 if p2 == "nPort"
1698 or p2 == "sHostname" then
1699 tServer[p1][p2] = p3
1700 elseif p2 == "nID" then
1701 local isNumber = tonumber( p3 )
1702
1703 if isNumber == nil then
1704 for _, server in pairs(tServer) do
1705 if server.nID == p3 then
1706 return "Number is already taken", true
1707 end
1708 end
1709
1710 tServer[p3] = tServer[p1]
1711 tServer[p3].nID = p3
1712 tServer[p1] = nil
1713 else
1714 return "Cant change ID to number", true
1715 end
1716 else
1717 return "This value cant be changed", true
1718 end
1719
1720 return "Server value was changed"
1721 elseif sType == "user" then
1722 if not tServer[ p1 ] then
1723 return "Server not found", true
1724 end
1725
1726 if not tServer[ p1 ].user[ p2 ] then
1727 return "User not found", true
1728 end
1729
1730 if p3 == "nPort" then
1731 local isNumber = tonumber(p4)
1732
1733 if not isNumber then
1734 return "Port as number expected", true
1735 end
1736
1737 if not (isNumber >= 0 and isNumber <= 65535) then
1738 return "Port is not in range", true
1739 end
1740 end
1741
1742 if p3 == "nAuthID"
1743 or p3 == "nPort"
1744 or p3 == "sName" then
1745 tServer[p1].user[p2][p3] = p4
1746 elseif p3 == "nID" then
1747 local isNumber = tonumber( p4 )
1748
1749 if isNumber == nil then
1750 for _, user in pairs(tServer[p1].user[p2]) do
1751 if user.nID == p4 then
1752 return "Number is already taken", true
1753 end
1754 end
1755
1756 tServer[p1].user[p2].nID = p4
1757 else
1758 return "Cant change ID to number", true
1759 end
1760 else
1761 return "This value cant be changed", true
1762 end
1763
1764 return "User value was changed"
1765 else
1766 return "Option not found", true
1767 end
1768end
1769
1770command.unnamned = function(sID1, uID, sID2)
1771 -- Logout
1772 -- Login
1773 -- Forward traffic in both directions
1774
1775
1776end
1777
1778command.unset = function(sType, p1, p2)
1779 if sType == "modem" then
1780 privEnv.modem = nil
1781
1782 return "Modem was reseted"
1783 elseif sType == "server" then
1784 if not tServer[ p1 ] then
1785 return "Server not found", true
1786 end
1787
1788 local server = tServer[p1]
1789
1790 server.lastUserID = 0
1791 server.sHostname = ""
1792 server.user = { }
1793
1794 tServer[p1] = server
1795
1796 return "Server was reseted"
1797 elseif sType == "user" then
1798 if not tServer[ p1 ] then
1799 return "Server not found", true
1800 end
1801
1802 if not tServer[ p1 ].user[ p2 ] then
1803 return "User not found", true
1804 end
1805
1806 local user = tServer[p1].user[p2]
1807
1808 user.sName = ""
1809 user.nAuthID = -1
1810
1811 tServer[p1].user[p2] = user
1812
1813 return "User was reseted"
1814 else
1815 return "Option not found", true
1816 end
1817end
1818
1819----------------------------------------------------------------
1820
1821--[[
1822
1823Newer, Better soon
1824
1825]]
1826
1827local autoComplete = function(sLine)
1828 if #sLine > 0 then
1829 if string.find(sLine, "^[$].*") then
1830 return shell.complete( string.match(sLine, "^[$](.*)$") )
1831 end
1832
1833 sLine = string.match(sLine, "^%s*(.*)$")
1834
1835 if sLine == nil or #sLine <= 0 then
1836 return ""
1837 end
1838
1839 local tSplit = { }
1840 for sSplit in string.gmatch(sLine, "[%p%w]+") do
1841 table.insert(tSplit, sSplit)
1842 end
1843
1844 if string.find(sLine, " $") then
1845 table.insert(tSplit, "")
1846 end
1847
1848 local tCurrent = commandComplete
1849 local fVar = { }
1850 for nThis, sPart in pairs(tSplit) do
1851 if sPart == "fself" or sPart == "tself" then
1852 return ""
1853 end
1854
1855 if nThis == #tSplit then
1856 break
1857 end
1858
1859 if tCurrent[sPart] then
1860 tCurrent = tCurrent[sPart]
1861 else
1862 if tCurrent.tself then
1863 local bFound = false
1864 for _, sC in pairs(tCurrent.tself.fself( table.unpack(fVar) )) do
1865 if sC == sPart then
1866 tCurrent = tCurrent["tself"]
1867 table.insert(fVar, sC)
1868 bFound = true
1869 break
1870 end
1871 end
1872
1873 if not bFound then
1874 return ""
1875 end
1876 else
1877 return ""
1878 end
1879 end
1880 end
1881
1882 local sLast = tSplit[#tSplit]
1883 local tResult = { }
1884 for sName, sPart in pairs(tCurrent) do
1885 if sName == "tself" then
1886 for _, sC in pairs(sPart.fself( table.unpack(fVar) )) do
1887 if string.find(sC, "^"..sLast) then
1888 table.insert(tResult, sC)
1889 end
1890 end
1891
1892 elseif sName ~= "tself" and sName ~= "fself" then
1893 if string.find(sName, "^"..sLast) then
1894 table.insert(tResult, sName)
1895 end
1896 end
1897 end
1898
1899 for i, sResult in pairs(tResult) do
1900 tResult[i] = string.match(sResult, "^"..sLast.."(.*)$")
1901
1902 if tResult[i] == nil then
1903 tResult[i] = ""
1904 end
1905 end
1906
1907 table.sort(tResult)
1908
1909 return tResult
1910 end
1911end
1912
1913----------------------------------------------------------------
1914
1915console = function()
1916 local tHistory = { }
1917
1918 while bRunning do
1919 term.clearLine()
1920 term.setTextColor(nPColor)
1921 write(">> ")
1922
1923 term.setTextColor(nWColor)
1924 local stCommand = read(nil, tHistory, autoComplete)
1925 table.insert(tHistory, stCommand)
1926
1927 local bFirst = true
1928 local sCommand = ""
1929 local tParm = { }
1930 for sSplit in string.gmatch(stCommand, "[%p%w]+") do
1931 if bFirst then
1932 sCommand = string.lower( sSplit )
1933 bFirst = false
1934 else
1935 table.insert(tParm, sSplit)
1936 end
1937 end
1938
1939 if string.find(sCommand, "^[$]") then
1940 shell.run(
1941 string.match(sCommand, ".(.+)"),
1942 table.unpack(tParm))
1943 elseif sCommand == "exit" then
1944 bRunning = false
1945 elseif stCommand ~= "" then
1946 if command[ sCommand ] then
1947 local bOk, vResult, bError = pcall(
1948 command[ sCommand ], table.unpack( tParm ))
1949
1950 if not bOk or bError then
1951 term.setTextColor(colors.red)
1952 end
1953
1954 if vResult ~= nil then
1955 if type(vResult) == "table" then
1956 for sPrefix, sPostfix in pairs(vResult) do
1957 term.setTextColor(nSTColor)
1958 write(sPrefix..": ")
1959
1960 term.setTextColor(nWColor)
1961 print(sPostfix)
1962 end
1963 elseif type(vResult) == "string" then
1964 print(vResult)
1965 end
1966 end
1967
1968 --[[
1969 if type(vResult) == "table" then
1970 vResult = textutils.serialize(vResult)
1971 end
1972
1973 if vResult ~= nil then
1974 print( vResult )
1975 -- if not bOk then
1976 -- os.sleep(15)
1977 -- end -- Debug >> crash
1978 end
1979 ]]
1980 else
1981 term.setTextColor(nEColor)
1982 print("Command not found")
1983 end
1984 end
1985 end
1986end
1987
1988local fCRun = function()
1989 while bRunning do
1990 local tEvent = { os.pullEvent() }
1991
1992 if tEvent[1] == "terminate" then
1993 bRunning = false
1994 return print()
1995 end
1996
1997 for _, cRoutine in pairs(privEnv.cRoutines) do
1998 coroutine.resume( cRoutine.routine, table.unpack(tEvent) )
1999 end
2000
2001 for _, sinServer in pairs(tServer) do for _, sinUser in pairs(sinServer.user) do
2002 for _, cRoutine in pairs(sinUser.cRoutines) do
2003 coroutine.resume( cRoutine.routine, table.unpack(tEvent) )
2004 end
2005 end end
2006
2007 lib.sniff.parallel()
2008 end
2009end
2010
2011fMPCExit = function()
2012 for _, cRoutine in pairs(privEnv.cRoutines) do
2013 cRoutine.bRunning = false
2014 end
2015
2016 for _, sinServer in pairs(tServer) do for _, sinUser in pairs(sinServer.user) do
2017 for _, cRoutine in pairs(sinUser.cRoutines) do
2018 cRoutine.bRunning = false
2019 end
2020 end end
2021
2022 lib.sniff.removeAllHosts()
2023 lib.sniff.stop()
2024
2025 fMPCExit = nil
2026 command = nil
2027end
2028
2029local fConsole
2030if type(tOption[1]) == "string"
2031and not (#tOption == 2
2032and tOption[2] == "load") then
2033 fConsole = console
2034else
2035 return fCRun
2036end
2037
2038while bRunning do
2039 parallel.waitForAny(fConsole, fCRun)
2040end
2041
2042fMPCExit()