SHOW:
|
|
- or go back to the newest paste.
1 | - | local t = peripheral.find("EntityDetector") |
1 | + | local sVersion = "v0.9 RC1" |
2 | local nBuild = 90 | |
3 | local debugMode = false | |
4 | ||
5 | - | function getPlayers(range, x, y, z) |
5 | + | -- Variables par défaut |
6 | - | if not z then |
6 | + | |
7 | - | return false |
7 | + | local sLogFormat = "#y#m#d.log" |
8 | - | end |
8 | + | local sLogDir = "/playerd_logs/" |
9 | - | |
9 | + | |
10 | - | local playerList = {} |
10 | + | local useChatInterface = true |
11 | - | local f = t.getEntityList(range, x, y, z) |
11 | + | local printLog = true |
12 | - | |
12 | + | local disableTerminateEvent = false |
13 | - | for k, v in pairs(f) do |
13 | + | local disableAutomaticUpdates = false |
14 | - | if v.type == "EntityPlayerMP" then |
14 | + | |
15 | - | table.insert(playerList, v.name) |
15 | + | --[[ |
16 | - | end |
16 | + | Liste des variables pour les messages du chat : |
17 | - | end |
17 | + | |
18 | - | |
18 | + | #p : Nom du joueur qui entre/sort |
19 | - | return playerList |
19 | + | #M : Minute réelle |
20 | #h : Heure réelle | |
21 | #d : Jour réel | |
22 | #m : Mois réel | |
23 | - | while true do |
23 | + | #y : Année réelle |
24 | - | tOldPlayers = tPlayers |
24 | + | --]] |
25 | - | tPlayers = getPlayers(20, 3244, 32, -260) |
25 | + | |
26 | - | |
26 | + | local joinMessage = "#p joined" |
27 | - | if #tPlayers ~= #tOldPlayers then |
27 | + | local leftMessage = "#p left" |
28 | - | print(#tPlayers.." players") |
28 | + | local chatTo = {"your_name"} |
29 | - | if #tPlayers > #tOldPlayers then |
29 | + | local chatName = "Player Probe "..sVersion.." on "..os.computerID() |
30 | - | os.queueEvent("player_join", tPlayers, tOldPlayers) |
30 | + | local canUseCommands = {"your_name"} |
31 | - | elseif #tPlayers < #tOldPlayers then |
31 | + | |
32 | - | os.queueEvent("player_left", tPlayers, tOldPlayers) |
32 | + | local tWhitelist = {} |
33 | - | end |
33 | + | |
34 | - | end |
34 | + | local joinProgram = "" |
35 | - | |
35 | + | local leftProgram = "" |
36 | - | sleep(1) |
36 | + | |
37 | - | end |
37 | + | -- Fin des variables par défaut |
38 | ||
39 | -- Déclaration de la fonction au centre du programme | |
40 | - | local function playerHandler() |
40 | + | |
41 | - | while true do |
41 | + | local function getTableDifference(oldTable, newTable) |
42 | - | bState = false |
42 | + | if not newTable then |
43 | - | |
43 | + | return false |
44 | - | local event, tPlayers, tOldPlayers = os.pullEvent() |
44 | + | end |
45 | - | |
45 | + | |
46 | - | if event == "player_join" then |
46 | + | local tDifference = {} |
47 | - | for i = 1, #tPlayers do |
47 | + | |
48 | - | sActualPlayer = tPlayers[i] |
48 | + | --[[ |
49 | - | |
49 | + | |
50 | - | if #tOldPlayers > 0 then |
50 | + | print("oldTable :") |
51 | - | for i = 1, #tOldPlayers do |
51 | + | |
52 | - | if tOldPlayers[i] == sActualPlayer then |
52 | + | for i = 1, #oldTable do |
53 | - | bState = true |
53 | + | print(oldTable[i]) |
54 | - | end |
54 | + | end |
55 | - | |
55 | + | |
56 | - | if bState == false then |
56 | + | print("newTable :") |
57 | - | print(sActualPlayer.." join") |
57 | + | |
58 | - | end |
58 | + | for i = 1, #newTable do |
59 | - | end |
59 | + | print(newTable[i]) |
60 | - | else |
60 | + | end |
61 | - | print(sActualPlayer.." join") |
61 | + | |
62 | - | end |
62 | + | print("Différences :") |
63 | - | end |
63 | + | |
64 | - | elseif event == "player_left" then |
64 | + | --]] |
65 | - | print("left") |
65 | + | |
66 | - | end |
66 | + | for i = 1, #oldTable do |
67 | - | end |
67 | + | local isOK = false |
68 | ||
69 | local selectedTable = oldTable[i] | |
70 | - | parallel.waitForAll(main, playerHandler) |
70 | + | --print("J'ai "..selectedTable.." actuellement") |
71 | ||
72 | for i = 1, #newTable do | |
73 | --print("Je compare "..selectedTable.." avec "..newTable[i]) | |
74 | ||
75 | if selectedTable == newTable[i] then | |
76 | --print("OK") | |
77 | isOK = true | |
78 | break | |
79 | end | |
80 | end | |
81 | ||
82 | if isOK == false then | |
83 | --print(selectedTable.." n'est pas dans table2") | |
84 | table.insert(tDifference, selectedTable) | |
85 | end | |
86 | end | |
87 | ||
88 | return tDifference | |
89 | end | |
90 | ||
91 | -- Fin de la déclaration | |
92 | ||
93 | -- Init Environment | |
94 | ||
95 | term.setBackgroundColor(colors.black) | |
96 | term.setTextColor(colors.white) | |
97 | term.clear() | |
98 | term.setCursorPos(1, 1) | |
99 | print("Player Detector Init Environment") | |
100 | term.setCursorPos(1, 2) | |
101 | ||
102 | for i = 1, term.getSize() do | |
103 | write("-") | |
104 | end | |
105 | ||
106 | term.setCursorPos(1, 4) | |
107 | ||
108 | if not fs.exists("player_detector.conf") then | |
109 | print("\nNo config file found, init setup...") | |
110 | local configFile = fs.open("player_detector.conf", "w") | |
111 | configFile.write("{\nLogFormat = \"#y#M#d.log\", \nLogDir = \"/playerd_logs/\", \nuseChatInterface = true, \nprintLog = true, \ndisableTerminateEvent = false, \ndisableAutomaticUpdates = false, \njoinMessage = \"#p joined\", \nleftMessage = \"#p left\", \nchatTo = {\"your_name\"}, \nchatName = \"".."Player Probe on "..os.computerID().."\", \ncanUseCommands = {\"your_name\"}, \ntWhitelist = {}, \njoinProgram = \"\", \nleftProgram = \"\", \n}") | |
112 | configFile.close() | |
113 | print("\nFile created, a text editor will be prompt to edit settings, please save before quit the editor.") | |
114 | print("Press any key to continue...") | |
115 | os.pullEvent("key") | |
116 | ||
117 | shell.run("edit player_detector.conf") | |
118 | ||
119 | term.setBackgroundColor(colors.black) | |
120 | term.setTextColor(colors.white) | |
121 | term.clear() | |
122 | term.setCursorPos(1, 1) | |
123 | print("Player Detector Init Environment") | |
124 | term.setCursorPos(1, 2) | |
125 | ||
126 | for i = 1, term.getSize() do | |
127 | write("-") | |
128 | end | |
129 | ||
130 | term.setCursorPos(1, 4) | |
131 | else | |
132 | print("\nConfig file found") | |
133 | end | |
134 | ||
135 | print("Loading settings...") | |
136 | settings.load("player_detector.conf") | |
137 | ||
138 | sLogFormat = settings.get("LogFormat", sLogFormat) | |
139 | sLogDir = settings.get("LogDir", sLogDir) | |
140 | useChatInterface = settings.get("useChatInterface", useChatInterface) | |
141 | printLog = settings.get("printLog", printLog) | |
142 | disableTerminateEvent = settings.get("disableTerminateEvent", disableTerminateEvent) | |
143 | disableAutomaticUpdates = settings.get("disableAutomaticUpdates", disableAutomaticUpdates) | |
144 | joinMessage = settings.get("joinMessage", joinMessage) | |
145 | leftMessage = settings.get("leftMessage", leftMessage) | |
146 | chatTo = settings.get("chatTo", chatTo) | |
147 | chatName = settings.get("chatName", chatName) | |
148 | canUseCommands = settings.get("canUseCommands", canUseCommands) | |
149 | tWhitelist = settings.get("tWhitelist", tWhitelist) | |
150 | joinProgram = settings.get("joinProgram", joinProgram) | |
151 | leftProgram = settings.get("leftProgram", leftProgram) | |
152 | ||
153 | -- Check new version | |
154 | ||
155 | if not disableAutomaticUpdates and http.get("http://pastebin.com/raw/ZD8t8ZSK") then | |
156 | print("\nChecking for updates...") | |
157 | ||
158 | local sBuildNet = http.get("http://pastebin.com/raw/ZD8t8ZSK") | |
159 | local nBuildNet = tonumber(sBuildNet.readAll()) | |
160 | sBuildNet.close() | |
161 | ||
162 | if nBuildNet > nBuild then | |
163 | print("A new version is available ! (build "..nBuildNet..")") | |
164 | --print("I'm running "..shell.getRunningProgram()) | |
165 | print("Downloading new version...") | |
166 | ||
167 | local sNewSoftware = http.get("http://pastebin.com/raw/7Jg670Ra") | |
168 | ||
169 | local sTempFile = fs.open(".temp", "w") | |
170 | sTempFile.write(sNewSoftware.readAll()) | |
171 | sTempFile.close() | |
172 | ||
173 | sNewSoftware.close() | |
174 | ||
175 | if fs.exists(".temp") then | |
176 | print("Downloaded succesfully, updating...") | |
177 | fs.delete(shell.getRunningProgram()) | |
178 | fs.move(".temp", shell.getRunningProgram()) | |
179 | fs.delete(".temp") | |
180 | write("Rebooting") | |
181 | write(".") | |
182 | sleep(1) | |
183 | write(".") | |
184 | sleep(1) | |
185 | write(".") | |
186 | sleep(1) | |
187 | os.reboot() | |
188 | else | |
189 | print("Download fail...") | |
190 | end | |
191 | else | |
192 | print("You are on the latest version") | |
193 | end | |
194 | elseif disableAutomaticUpdates then | |
195 | print("\nAutomatics updates are disabled.") | |
196 | else | |
197 | print("An error has occured, please check your internet connection.") | |
198 | end | |
199 | ||
200 | print("") | |
201 | ||
202 | print("Checking config file...") | |
203 | local tKeyAllowed = {"{", "LogFormat", "LogDir", "useChatInterface", "printLog", "disableTerminateEvent", "disableAutomaticUpdates", "joinMessage", "leftMessage", "chatTo", "chatName", "canUseCommands", "tWhitelist", "joinProgram", "leftProgram", "}"} | |
204 | local tPresentKeys = {} | |
205 | local tErroredKey = {} | |
206 | local tConfigLines = {} | |
207 | local sActualLine = "" | |
208 | local sScanningLine = "" | |
209 | local sScanningKey = "" | |
210 | local bScanResult = false | |
211 | ||
212 | local configCheck = fs.open("player_detector.conf", "r") | |
213 | ||
214 | while sActualLine ~= nil do | |
215 | sActualLine = configCheck.readLine() | |
216 | table.insert(tConfigLines, sActualLine) | |
217 | end | |
218 | ||
219 | configCheck.close() | |
220 | ||
221 | for i = 1, #tConfigLines do | |
222 | sScanningLine = tConfigLines[i] | |
223 | bScanResult = false | |
224 | ||
225 | for i = 1, #tKeyAllowed do | |
226 | sScanningKey = sScanningLine:sub(1, #tKeyAllowed[i]) | |
227 | if sScanningKey == tKeyAllowed[i] then | |
228 | bScanResult = true | |
229 | break | |
230 | end | |
231 | end | |
232 | ||
233 | if bScanResult == false then | |
234 | if not sScanningLine:sub(1, 7) == "LogFile" then | |
235 | table.insert(tErroredKey, "L"..i.." > \""..sScanningLine.."\"") | |
236 | end | |
237 | else | |
238 | table.insert(tPresentKeys, sScanningKey) | |
239 | end | |
240 | end | |
241 | ||
242 | if #tErroredKey > 0 then | |
243 | if #tErroredKey == 1 then | |
244 | printError("Errored key found :") | |
245 | else | |
246 | printError("Errored keys found :") | |
247 | end | |
248 | print("") | |
249 | ||
250 | textutils.pagedTabulate(tErroredKey) | |
251 | print("\nPress any key to continue...") | |
252 | os.pullEvent("key") | |
253 | else | |
254 | print("No errored key found !") | |
255 | end | |
256 | ||
257 | local tKeyDifference = getTableDifference(tKeyAllowed, tPresentKeys) | |
258 | ||
259 | if #tKeyDifference > 0 then | |
260 | if #tKeyDifference == 1 then | |
261 | printError("Missing key found :") | |
262 | else | |
263 | printError("Missing keys found :") | |
264 | end | |
265 | ||
266 | print("") | |
267 | textutils.pagedTabulate(tKeyDifference) | |
268 | print("") | |
269 | ||
270 | print("< >") | |
271 | ||
272 | local nCurX, nCurY = term.getCursorPos() | |
273 | term.setCursorPos(2, nCurY - 1) | |
274 | ||
275 | for i = 1, 10 do | |
276 | sleep(1) | |
277 | write("=") | |
278 | end | |
279 | ||
280 | sleep(1) | |
281 | else | |
282 | print("No missing key found !") | |
283 | end | |
284 | ||
285 | --sleep(5) | |
286 | ||
287 | -- End Init Environment | |
288 | ||
289 | local bRun = true | |
290 | ||
291 | local monX, monY = term.getSize() | |
292 | local oldMonX, oldMonY = term.getSize() | |
293 | ||
294 | local tActualDate = {} | |
295 | ||
296 | if monX < 29 then | |
297 | printError("Resolution is too low !") | |
298 | sleep(5) | |
299 | end | |
300 | ||
301 | if disableTerminateEvent == true then | |
302 | local oldPullEvent = os.pullEvent | |
303 | os.pullEvent = os.pullEventRaw | |
304 | end | |
305 | ||
306 | --LIP : EntityDetector / OpenCCSensor : sensor | |
307 | --LIP : WorldInterface / Peripherals++ : timeSensor | |
308 | --LIP : ChatInterface / Peripherals++ : chatBox | |
309 | ||
310 | local tSensorPeripheral = peripheral.find("sensor") | |
311 | local tTimePeripheral = peripheral.find("timeSensor") | |
312 | local tChatPeripheral = peripheral.find("chatBox") | |
313 | ||
314 | local tSensorSide = "" | |
315 | local tTimeSide = "" | |
316 | local tChatSide = "" | |
317 | ||
318 | local bScrollEffectDone = false | |
319 | ||
320 | local chatInterfaceConnected = true | |
321 | ||
322 | if not tSensorPeripheral then | |
323 | error("No sensor found !") | |
324 | end | |
325 | ||
326 | if tSensorPeripheral.getSensorName() ~= "proximityCard" then | |
327 | error("No proximityCard inserted !") | |
328 | end | |
329 | ||
330 | if not tTimePeripheral then | |
331 | error("No timeSensor found !") | |
332 | end | |
333 | ||
334 | if not tChatPeripheral then | |
335 | chatInterfaceConnected = false | |
336 | end | |
337 | ||
338 | for i = 1, #peripheral.getNames() do | |
339 | local sPeripheralType = peripheral.getType(peripheral.getNames()[i]) | |
340 | ||
341 | if sPeripheralType == "sensor" then | |
342 | tSensorSide = peripheral.getNames()[i] | |
343 | elseif sPeripheralType == "timeSensor" then | |
344 | tTimeSide = peripheral.getNames()[i] | |
345 | elseif sPeripheralType == "chatBox" then | |
346 | tChatSide = peripheral.getNames()[i] | |
347 | end | |
348 | end | |
349 | ||
350 | local tPlayers = {} | |
351 | local tOldPlayers = {} | |
352 | ||
353 | local tInventoryPlayers = {} | |
354 | local tActualInventoryPlayers = {} | |
355 | ||
356 | if not fs.exists(sLogDir) then | |
357 | fs.makeDir(sLogDir) | |
358 | end | |
359 | ||
360 | term.clear() | |
361 | term.setCursorPos(1, 1) | |
362 | ||
363 | if monX >= 51 then | |
364 | print("Player detector "..sVersion) | |
365 | term.setCursorPos(monX - string.len(string.char(174).." arc13") + 1, 1) | |
366 | term.write(string.char(174).." arc13") | |
367 | ||
368 | if term.isColor() then | |
369 | term.setTextColor(colors.lightGray) | |
370 | end | |
371 | ||
372 | term.setCursorPos(1, 3) | |
373 | if useChatInterface and chatInterfaceConnected then | |
374 | print("ChatBox enabled") | |
375 | else | |
376 | print("ChatBox disabled") | |
377 | end | |
378 | ||
379 | term.setCursorPos(1, 4) | |
380 | elseif monX < 51 and monX >= 29 then | |
381 | print("Player detector "..sVersion) | |
382 | term.setCursorPos(monX - string.len(string.char(174).." arc13") + 1, 1) | |
383 | term.write(string.char(174).." arc13") | |
384 | term.setCursorPos(1, 3) | |
385 | if useChatInterface and chatInterfaceConnected then | |
386 | print("ChatBox enabled") | |
387 | else | |
388 | print("ChatBox disabled") | |
389 | end | |
390 | ||
391 | term.setCursorPos(1, 4) | |
392 | end | |
393 | ||
394 | if term.isColor() then | |
395 | term.setTextColor(colors.gray) | |
396 | end | |
397 | ||
398 | for i = 1, term.getSize() do | |
399 | write("-") | |
400 | end | |
401 | ||
402 | term.setTextColor(colors.white) | |
403 | ||
404 | print("\n") | |
405 | ||
406 | if not printLog then | |
407 | print("Log here is disabled !") | |
408 | end | |
409 | ||
410 | local function redrawHeader() | |
411 | local oldCurX, oldCurY = term.getCursorPos() | |
412 | ||
413 | term.setCursorPos(1, 1) | |
414 | term.clearLine() | |
415 | print("Player detector "..sVersion) | |
416 | term.setCursorPos(monX - string.len(string.char(174).." arc13") + 1, 1) | |
417 | term.write(string.char(174).." arc13") | |
418 | ||
419 | if term.isColor() then | |
420 | term.setTextColor(colors.gray) | |
421 | end | |
422 | ||
423 | if bScrollEffectDone == true then | |
424 | term.setCursorPos(1, 2) | |
425 | else | |
426 | if monX >= 51 then | |
427 | term.setCursorPos(1, 4) | |
428 | elseif monX < 51 and monX >= 29 then | |
429 | term.setCursorPos(1, 4) | |
430 | end | |
431 | end | |
432 | ||
433 | for i = 1, term.getSize() do | |
434 | write("-") | |
435 | end | |
436 | ||
437 | term.setTextColor(colors.white) | |
438 | ||
439 | if monX < 29 then | |
440 | term.clear() | |
441 | term.setCursorPos(1, 1) | |
442 | print("Resolution too low !") | |
443 | end | |
444 | ||
445 | term.setCursorPos(oldCurX, oldCurY) | |
446 | end | |
447 | ||
448 | local function scrollEffect() | |
449 | sleep(5) | |
450 | ||
451 | local oldCurX, oldCurY = term.getCursorPos() | |
452 | ||
453 | for i = 1, 1 do | |
454 | term.scroll(1) | |
455 | ||
456 | term.setCursorPos(1, 1) | |
457 | print("Player detector "..sVersion) | |
458 | term.setCursorPos(monX - string.len(string.char(174).." arc13") + 1, 1) | |
459 | term.write(string.char(174).." arc13") | |
460 | paintutils.drawLine(1, 2, monX, 2, colors.black) | |
461 | ||
462 | if monX < 51 and monX >= 29 and i == 2 then | |
463 | term.setCursorPos(1, 2) | |
464 | ||
465 | if term.isColor() then | |
466 | term.setTextColor(colors.gray) | |
467 | end | |
468 | ||
469 | for i = 1, term.getSize() do | |
470 | write("-") | |
471 | end | |
472 | ||
473 | term.setTextColor(colors.white) | |
474 | end | |
475 | ||
476 | sleep(0.2) | |
477 | end | |
478 | term.scroll(1) | |
479 | ||
480 | term.setCursorPos(1, 1) | |
481 | print("Player detector "..sVersion) | |
482 | term.setCursorPos(monX - string.len(string.char(174).." arc13") + 1, 1) | |
483 | term.write(string.char(174).." arc13") | |
484 | ||
485 | if monX < 51 and monX >= 29 then | |
486 | term.setCursorPos(1, 2) | |
487 | ||
488 | if term.isColor() then | |
489 | term.setTextColor(colors.gray) | |
490 | end | |
491 | ||
492 | for i = 1, term.getSize() do | |
493 | write("-") | |
494 | end | |
495 | ||
496 | term.setTextColor(colors.white) | |
497 | end | |
498 | ||
499 | bScrollEffectDone = true | |
500 | ||
501 | redrawHeader() | |
502 | ||
503 | if monX >= 51 then | |
504 | term.setCursorPos(oldCurX, oldCurY - 3) | |
505 | elseif monX < 51 and monX >= 29 then | |
506 | term.setCursorPos(oldCurX, oldCurY - 2) | |
507 | end | |
508 | end | |
509 | ||
510 | local function isInWhitelist(sPlayerName) | |
511 | for i = 1, #tWhitelist do | |
512 | if sPlayerName == tWhitelist[i] then | |
513 | --tChatPeripheral.tell("arc13", "whitelisted") | |
514 | return true | |
515 | end | |
516 | end | |
517 | ||
518 | --tChatPeripheral.tell("arc13", "not whitelisted") | |
519 | return false | |
520 | end | |
521 | ||
522 | local function getInventorySize(tInventory) | |
523 | local i = 0 | |
524 | ||
525 | for k, v in pairs(tInventory) do | |
526 | i = i + 1 | |
527 | end | |
528 | ||
529 | return i | |
530 | end | |
531 | ||
532 | local function getPlayers() | |
533 | local playerList = {} | |
534 | local f = tSensorPeripheral.getTargets() | |
535 | ||
536 | for k, v in pairs(f) do | |
537 | if v.IsPlayer then | |
538 | table.insert(playerList, k) | |
539 | end | |
540 | end | |
541 | ||
542 | for i = 1, #playerList do | |
543 | --print(playerList[i]) | |
544 | end | |
545 | ||
546 | return playerList | |
547 | end | |
548 | ||
549 | function logJoin(sPlayerJoined) | |
550 | if printLog then | |
551 | if term.isColor() then | |
552 | term.setTextColor(colors.lightGray) | |
553 | end | |
554 | ||
555 | local sFormattedPlayer = "" | |
556 | ||
557 | if #tPlayers > 1 then | |
558 | sFormattedPlayer = "players" | |
559 | else | |
560 | sFormattedPlayer = "player" | |
561 | end | |
562 | ||
563 | tActualDate = tTimePeripheral.getDate() | |
564 | write("["..string.format("%02i", tActualDate.hour)..":"..string.format("%02i", tActualDate.minute)..", "..#tPlayers.." "..sFormattedPlayer.."] ") | |
565 | term.setTextColor(colors.white) | |
566 | print(sPlayerJoined.." join") | |
567 | end | |
568 | ||
569 | local sLogName = sLogFormat | |
570 | sLogName = sLogName:gsub("#m", string.format("%02i", tActualDate.minute)) | |
571 | sLogName = sLogName:gsub("#h", string.format("%02i", tActualDate.hour)) | |
572 | sLogName = sLogName:gsub("#d", string.format("%02i", tActualDate.day)) | |
573 | sLogName = sLogName:gsub("#M", string.format("%02i", tActualDate.month)) | |
574 | sLogName = sLogName:gsub("#y", string.format("%02i", tActualDate.year)) | |
575 | ||
576 | local file = fs.open(sLogDir..sLogName, fs.exists(sLogDir..sLogName) and "a" or "w") | |
577 | ||
578 | file.writeLine("["..string.format("%02i", tActualDate.hour)..":"..string.format("%02i", tActualDate.minute).."] "..sPlayerJoined.." join") | |
579 | file.close() | |
580 | ||
581 | if useChatInterface == true and chatInterfaceConnected == true then | |
582 | for i = 1, #chatTo do | |
583 | local sMsg = string.gsub(joinMessage, "#p", sPlayerJoined) | |
584 | sMsg = sMsg:gsub("#M", string.format("%02i", tActualDate.minute)) | |
585 | sMsg = sMsg:gsub("#h", string.format("%02i", tActualDate.hour)) | |
586 | sMsg = sMsg:gsub("#d", string.format("%02i", tActualDate.day)) | |
587 | sMsg = sMsg:gsub("#m", string.format("%02i", tActualDate.month)) | |
588 | sMsg = sMsg:gsub("#y", string.format("%02i", tActualDate.year)) | |
589 | ||
590 | if chatName == "" then | |
591 | tChatPeripheral.tell(chatTo[i], sMsg) | |
592 | else | |
593 | tChatPeripheral.tell(chatTo[i], "["..chatName.."] "..sMsg) | |
594 | end | |
595 | end | |
596 | end | |
597 | end | |
598 | ||
599 | local function logLeft(sPlayerLeft) | |
600 | if printLog then | |
601 | if term.isColor() then | |
602 | term.setTextColor(colors.lightGray) | |
603 | end | |
604 | ||
605 | local sFormattedPlayer = "" | |
606 | ||
607 | if #tPlayers > 1 then | |
608 | sFormattedPlayer = "players" | |
609 | else | |
610 | sFormattedPlayer = "player" | |
611 | end | |
612 | ||
613 | tActualDate = tTimePeripheral.getDate() | |
614 | write("["..string.format("%02i", tActualDate.hour)..":"..string.format("%02i", tActualDate.minute)..", "..#tPlayers.." "..sFormattedPlayer.."] ") | |
615 | term.setTextColor(colors.white) | |
616 | print(sPlayerLeft.." left") | |
617 | end | |
618 | ||
619 | local sLogName = sLogFormat | |
620 | sLogName = sLogName:gsub("#m", string.format("%02i", tActualDate.minute)) | |
621 | sLogName = sLogName:gsub("#h", string.format("%02i", tActualDate.hour)) | |
622 | sLogName = sLogName:gsub("#d", string.format("%02i", tActualDate.day)) | |
623 | sLogName = sLogName:gsub("#M", string.format("%02i", tActualDate.month)) | |
624 | sLogName = sLogName:gsub("#y", string.format("%02i", tActualDate.year)) | |
625 | ||
626 | local file = fs.open(sLogDir..sLogName, fs.exists(sLogDir..sLogName) and "a" or "w") | |
627 | ||
628 | file.writeLine("["..string.format("%02i", tActualDate.hour)..":"..string.format("%02i", tActualDate.minute).."] "..sPlayerLeft.." left") | |
629 | ||
630 | file.close() | |
631 | ||
632 | if useChatInterface == true and chatInterfaceConnected == true then | |
633 | for i = 1, #chatTo do | |
634 | local sMsg = string.gsub(leftMessage, "#p", sPlayerLeft) | |
635 | sMsg = sMsg:gsub("#M", string.format("%02i", tActualDate.minute)) | |
636 | sMsg = sMsg:gsub("#h", string.format("%02i", tActualDate.hour)) | |
637 | sMsg = sMsg:gsub("#d", string.format("%02i", tActualDate.day)) | |
638 | sMsg = sMsg:gsub("#m", string.format("%02i", tActualDate.month)) | |
639 | sMsg = sMsg:gsub("#y", string.format("%02i", tActualDate.year)) | |
640 | ||
641 | if chatName == "" then | |
642 | tChatPeripheral.tell(chatTo[i], sMsg) | |
643 | else | |
644 | tChatPeripheral.tell(chatTo[i], "["..chatName.."] "..sMsg) | |
645 | end | |
646 | end | |
647 | end | |
648 | end | |
649 | ||
650 | local function playerJoin(tPlayers, tOldPlayers) | |
651 | local tDifference = getTableDifference(tPlayers, tOldPlayers) | |
652 | ||
653 | if joinProgram ~= "" and multishell then | |
654 | local sTempPlayers = "" | |
655 | ||
656 | for i = 1, #tDifference do | |
657 | sTempPlayers = sTempPlayers..tDifference[i].."," | |
658 | end | |
659 | ||
660 | shell.openTab(joinProgram.." "..sTempPlayers) | |
661 | end | |
662 | ||
663 | os.queueEvent("player_join", tDifference) | |
664 | ||
665 | for i = 1, #tDifference do | |
666 | if not isInWhitelist(tDifference[i]) then | |
667 | logJoin(tDifference[i]) | |
668 | ||
669 | redrawHeader() | |
670 | else | |
671 | if printLog then | |
672 | print("Whitelisted : "..tDifference[i]) | |
673 | end | |
674 | end | |
675 | end | |
676 | end | |
677 | ||
678 | local function playerLeft(tPlayers, tOldPlayers) | |
679 | local tDifference = getTableDifference(tOldPlayers, tPlayers) | |
680 | ||
681 | if debugMode then | |
682 | print("Differences:") | |
683 | for i = 1, #tDifference do | |
684 | print(tDifference[i]) | |
685 | end | |
686 | end | |
687 | ||
688 | if leftProgram ~= "" and multishell then | |
689 | local sTempPlayers = "" | |
690 | ||
691 | for i = 1, #tDifference do | |
692 | sTempPlayers = sTempPlayers..tDifference[i].."," | |
693 | end | |
694 | ||
695 | shell.openTab(leftProgram.." "..sTempPlayers) | |
696 | end | |
697 | ||
698 | os.queueEvent("player_left", tDifference) | |
699 | ||
700 | for i = 1, #tDifference do | |
701 | if not isInWhitelist(tDifference[i]) then | |
702 | logLeft(tDifference[i]) | |
703 | ||
704 | redrawHeader() | |
705 | else | |
706 | if printLog then | |
707 | print("Whitelisted : "..tDifference[i]) | |
708 | end | |
709 | end | |
710 | end | |
711 | end | |
712 | ||
713 | local function main() | |
714 | while bRun do | |
715 | tOldPlayers = tPlayers | |
716 | tPlayers = getPlayers() | |
717 | ||
718 | if debugMode then | |
719 | print("tOldPlayers:") | |
720 | for i = 1, #tOldPlayers do | |
721 | print(tOldPlayers[i]) | |
722 | end | |
723 | ||
724 | print("tPlayers:") | |
725 | for i = 1, #tPlayers do | |
726 | print(tPlayers[i]) | |
727 | end | |
728 | ||
729 | --sleep(5) | |
730 | end | |
731 | ||
732 | if #tPlayers ~= #tOldPlayers then | |
733 | if debugMode then | |
734 | print("New player") | |
735 | end | |
736 | if #tPlayers > #tOldPlayers then | |
737 | if debugMode then | |
738 | print("Player joined") | |
739 | end | |
740 | ||
741 | threadJoin = coroutine.create(playerJoin) | |
742 | coroutine.resume(threadJoin, tPlayers, tOldPlayers) | |
743 | elseif #tPlayers < #tOldPlayers then | |
744 | if debugMode then | |
745 | print("Player left") | |
746 | end | |
747 | ||
748 | threadLeft = coroutine.create(playerLeft) | |
749 | coroutine.resume(threadLeft, tPlayers, tOldPlayers) | |
750 | end | |
751 | else | |
752 | if debugMode then | |
753 | --print("No new player") | |
754 | end | |
755 | end | |
756 | ||
757 | sleep(0.1) | |
758 | end | |
759 | end | |
760 | ||
761 | -- Les events de peripherals sont incompréhensibles | |
762 | local function peripheralHandler() | |
763 | while bRun do | |
764 | redrawHeader() | |
765 | ||
766 | local sEvent, sSide = os.pullEvent() | |
767 | ||
768 | if sEvent == "peripheral" or sEvent == "peripheral_detach" then | |
769 | print(sSide) | |
770 | print(tTimeSide) | |
771 | print(tSensorSide) | |
772 | print(tChatSide) | |
773 | end | |
774 | ||
775 | if sEvent == "peripheral" then | |
776 | if peripheral.getType(sSide) == "chatBox" then | |
777 | chatInterfaceConnected = true | |
778 | print("[SYSTEM] Chat Box connected") | |
779 | tChatSide = sSide | |
780 | end | |
781 | elseif sEvent == "peripheral_detach" then | |
782 | if sSide == tTimeSide then | |
783 | -- Le timeSensor à été détaché | |
784 | error("[SYSTEM] Time Sensor disconnected") | |
785 | elseif sSide == tSensorSide then | |
786 | -- Le sensor à été détaché | |
787 | error("[SYSTEM] Proximity Sensor disconnected") | |
788 | elseif sSide == tChatSide then | |
789 | -- La Chat Box à été détaché | |
790 | chatInterfaceConnected = false | |
791 | tChatSide = "" | |
792 | print("[SYSTEM] Chat Box disconnected") | |
793 | end | |
794 | end | |
795 | end | |
796 | end | |
797 | ||
798 | local function chatHandler() | |
799 | while bRun do | |
800 | local sEvent, sPlayer, sMessage = os.pullEvent("chat") | |
801 | ||
802 | for i = 1, #canUseCommands do | |
803 | if sPlayer == canUseCommands[i] then | |
804 | if sMessage == "##disable_chat" then | |
805 | useChatInterface = false | |
806 | tChatPeripheral.tell(sPlayer, "Chat disabled !") | |
807 | elseif sMessage == "##enable_chat" then | |
808 | useChatInterface = true | |
809 | tChatPeripheral.tell(sPlayer, "Chat enabled !") | |
810 | elseif sMessage == "##stop" then | |
811 | tChatPeripheral.tell(sPlayer, "Terminated") | |
812 | os.pullEvent = oldPullEvent | |
813 | bRun = false | |
814 | elseif sMessage == "##get_players" then | |
815 | local tPlayersToSend = getPlayers() | |
816 | ||
817 | local sMsgToSend = "" | |
818 | ||
819 | if #tPlayersToSend == 0 then | |
820 | tChatPeripheral.tell(sPlayer, "No players detected") | |
821 | elseif #tPlayersToSend == 1 then | |
822 | tChatPeripheral.tell(sPlayer, "Player : "..tPlayersToSend[1]) | |
823 | else | |
824 | for i = 1, #tPlayersToSend - 1 do | |
825 | sMsgToSend = sMsgToSend..tPlayersToSend[i]..", " | |
826 | end | |
827 | ||
828 | sMsgToSend = sMsgToSend..tPlayersToSend[#tPlayersToSend] | |
829 | ||
830 | tChatPeripheral.tell(sPlayer, sMsgToSend) | |
831 | end | |
832 | end | |
833 | end | |
834 | end | |
835 | end | |
836 | end | |
837 | ||
838 | local function UIRefresh() | |
839 | while bRun do | |
840 | sleep(2) | |
841 | ||
842 | redrawHeader() | |
843 | end | |
844 | end | |
845 | ||
846 | local function resizeHandler() | |
847 | while bRun do | |
848 | event, side = os.pullEvent("monitor_resize") | |
849 | ||
850 | oldMonX, oldMonY = monX, monY | |
851 | ||
852 | monX, monY = term.getSize() | |
853 | ||
854 | if monX ~= oldMonX or monY ~= oldMonY then | |
855 | -- Resolution has changed, the program run on a monitor | |
856 | ||
857 | if monX >= 29 then | |
858 | redrawHeader() | |
859 | ||
860 | if bScrollEffectDone == true then | |
861 | term.setCursorPos(1, 3) | |
862 | else | |
863 | if monX >= 51 then | |
864 | term.setCursorPos(1, 6) | |
865 | elseif monX < 51 and monX >= 29 then | |
866 | term.setCursorPos(1, 5) | |
867 | end | |
868 | end | |
869 | else | |
870 | term.setCursorPos(1, 1) | |
871 | print("Resolution too low !") | |
872 | end | |
873 | end | |
874 | end | |
875 | end | |
876 | ||
877 | local function getPlayerInventory(sPlayer) | |
878 | return tSensorPeripheral.getTargetDetails(sPlayer).Inventory | |
879 | end | |
880 | ||
881 | local function inventoryUpdate() | |
882 | while bRun do | |
883 | local tPlayersInRange = getPlayers() | |
884 | ||
885 | for i = 1, #tPlayersInRange do | |
886 | local bSuccess, tTargetDetails = pcall(getPlayerInventory, tPlayersInRange[i]) | |
887 | ||
888 | if bSuccess then | |
889 | if not tActualInventoryPlayers[tPlayersInRange[i]] then | |
890 | tActualInventoryPlayers[tPlayersInRange[i]] = {inventory = {}} | |
891 | end | |
892 | ||
893 | local tActualInventory = {} | |
894 | ||
895 | tActualInventoryPlayers[tPlayersInRange[i]]["inventorySize"] = getInventorySize(tTargetDetails) | |
896 | ||
897 | for k, v in pairs(tTargetDetails) do | |
898 | table.insert(tActualInventory, v.Name) | |
899 | end | |
900 | ||
901 | tActualInventoryPlayers[tPlayersInRange[i]]["inventory"] = tActualInventory | |
902 | else | |
903 | --print("error") | |
904 | end | |
905 | end | |
906 | ||
907 | sleep(0.1) | |
908 | end | |
909 | end | |
910 | ||
911 | local function inventoryHandler() | |
912 | while bRun do | |
913 | local invHandlerEvent, invHandlerPlayer = os.pullEvent() | |
914 | ||
915 | if invHandlerEvent == "player_join" then | |
916 | for i = 1, #invHandlerPlayer do | |
917 | local bSuccess, tTargetDetails = pcall(getPlayerInventory, invHandlerPlayer[i]) | |
918 | ||
919 | if bSuccess then | |
920 | if not tInventoryPlayers[invHandlerPlayer[i]] then | |
921 | tInventoryPlayers[invHandlerPlayer[i]] = {inventory = {}} | |
922 | end | |
923 | ||
924 | local tActualInventory = {} | |
925 | ||
926 | tInventoryPlayers[invHandlerPlayer[i]]["inventorySize"] = getInventorySize(tTargetDetails) | |
927 | ||
928 | for k, v in pairs(tTargetDetails) do | |
929 | table.insert(tActualInventory, v.Name) | |
930 | end | |
931 | ||
932 | tInventoryPlayers[invHandlerPlayer[i]]["inventory"] = tActualInventory | |
933 | else | |
934 | --print("error") | |
935 | end | |
936 | end | |
937 | elseif invHandlerEvent == "player_left" then | |
938 | for i = 1, #invHandlerPlayer do | |
939 | if not isInWhitelist(invHandlerPlayer[i]) then | |
940 | local sLogName = sLogFormat | |
941 | sLogName = sLogName:gsub("#m", string.format("%02i", tActualDate.minute)) | |
942 | sLogName = sLogName:gsub("#h", string.format("%02i", tActualDate.hour)) | |
943 | sLogName = sLogName:gsub("#d", string.format("%02i", tActualDate.day)) | |
944 | sLogName = sLogName:gsub("#M", string.format("%02i", tActualDate.month)) | |
945 | sLogName = sLogName:gsub("#y", string.format("%02i", tActualDate.year)) | |
946 | ||
947 | local file = fs.open(sLogDir..sLogName, fs.exists(sLogDir..sLogName) and "a" or "w") | |
948 | ||
949 | local tCurrentInventory = {} | |
950 | ||
951 | for k, v in pairs(tActualInventoryPlayers[invHandlerPlayer[i]]["inventory"]) do | |
952 | table.insert(tCurrentInventory, v.displayName) | |
953 | end | |
954 | ||
955 | local tInvDifferencePlus = getTableDifference(tActualInventoryPlayers[invHandlerPlayer[i]]["inventory"], tInventoryPlayers[invHandlerPlayer[i]]["inventory"]) | |
956 | local tInvDifferenceMinus = getTableDifference(tInventoryPlayers[invHandlerPlayer[i]]["inventory"], tActualInventoryPlayers[invHandlerPlayer[i]]["inventory"]) | |
957 | ||
958 | if #tInvDifferencePlus > 0 or #tInvDifferenceMinus > 0 then | |
959 | print("Inventory has changed ! ("..tActualInventoryPlayers[invHandlerPlayer[i]]["inventorySize"].." items now, "..tInventoryPlayers[invHandlerPlayer[i]]["inventorySize"].." before)") | |
960 | end | |
961 | ||
962 | if #tInvDifferencePlus > 0 then | |
963 | -- Un/plusieurs item(s) à/ont été(s) ajouté(s) | |
964 | ||
965 | os.queueEvent("inventory_add", invHandlerPlayer[i], tInvDifferencePlus) | |
966 | ||
967 | file.writeLine("Inventory has changed (+) : ") | |
968 | ||
969 | file.write("/") | |
970 | ||
971 | for i = 1, #tInvDifferencePlus do | |
972 | file.write(tInvDifferencePlus[i].."/") | |
973 | if debugMode then | |
974 | print(tInvDifferencePlus[i]) | |
975 | end | |
976 | end | |
977 | ||
978 | file.write("\n") | |
979 | end | |
980 | ||
981 | if #tInvDifferenceMinus > 0 then | |
982 | -- Un/plusieurs item(s) à/ont été(s) enlevée(s) | |
983 | ||
984 | os.queueEvent("inventory_remove", invHandlerPlayer[i], tInvDifferenceMinus) | |
985 | ||
986 | file.writeLine("Inventory has changed (-) : ") | |
987 | ||
988 | file.write("/") | |
989 | ||
990 | for i = 1, #tInvDifferenceMinus do | |
991 | file.write(tInvDifferenceMinus[i].."/") | |
992 | if debugMode then | |
993 | print(tInvDifferenceMinus[i]) | |
994 | end | |
995 | end | |
996 | ||
997 | file.write("\n") | |
998 | end | |
999 | ||
1000 | file.close() | |
1001 | end | |
1002 | end | |
1003 | end | |
1004 | end | |
1005 | end | |
1006 | ||
1007 | parallel.waitForAll(main, chatHandler, scrollEffect, UIRefresh, resizeHandler, inventoryUpdate, inventoryHandler) |