DaikiKaminari

playerDetector

Feb 6th, 2022 (edited)
1,279
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.35 KB | None | 0 0
  1. --- GLOBAL VARIABLES ---
  2. local json -- json API
  3. local config -- variable where the config will be loaded
  4. local defaultConfig = { -- default client config, feel free to change it
  5.     ["version"] = 1.53,
  6.     ["status"] = "RELEASE",
  7.     ["sides"] = {
  8.         ["back"] = true,
  9.         ["front"] = true,
  10.         ["left"] = true,
  11.         ["right"] = true,
  12.         ["bottom"] = true,
  13.         ["top"] = true
  14.     },
  15.     ["emit_redstone_when_connected"] = true,
  16.     ["api_uri"] = "https://api.mineaurion.com/v1/serveurs/",
  17. }
  18.  
  19. --- UTILS ---
  20. -- Returns true if the tab contains the val
  21. local function hasValue(tab, val)
  22.     for index,value in pairs(tab) do
  23.       if value == val then
  24.         return true
  25.       end
  26.     end
  27.     return false
  28. end
  29.  
  30. -- Converts something in a boolean
  31. local function toBoolean(anything)
  32.     local false_equivalent = {nil, "nil", 0, 0.0, "0", "0.0", false, "false", "False", "FALSE"}
  33.     for _,v in pairs(false_equivalent) do
  34.         if anything == v then
  35.             return false
  36.         end
  37.     end
  38.     return true
  39. end
  40.  
  41. --- INIT ---
  42. -- Saves the config
  43. local function saveConfig()
  44.     local str = json.encodePretty(config)
  45.     assert(str and str ~= "", "ERROR : Encoding of the config went wrong.")
  46.     local file = fs.open("/config.json", "w")
  47.     file.write(str)
  48.     file.close()
  49. end
  50.  
  51. -- Returns true if the program is up to date, false otherwise and nil on error
  52. local function isUpToDate()
  53.     local http_request = http.get("https://raw.githubusercontent.com/DaikiKaminari/playerDetector/master/version.json")
  54.     if not http_request then
  55.         print("WARNING : unable to check if the program is up to date. HTTP request failed.")
  56.         return nil
  57.     end
  58.     local body_content = http_request.readAll()
  59.     if body_content == "" or body_content == "[]" then
  60.         print("WARNING : unable to check if the program is up to date. Request body is empty.")
  61.         return nil
  62.     end
  63.     live_config = json.decode(body_content)
  64.     live_version = live_config["version"]
  65.     current_version = defaultConfig["version"]
  66.     return current_version >= live_version, live_config["should_old_config_be_erased"], live_config["status"]
  67. end
  68.  
  69. -- Update the program
  70. local function update(should_old_config_be_erased, status)
  71.     local http_request = http.get("https://raw.githubusercontent.com/DaikiKaminari/playerDetector/master/playerDetector.lua")
  72.     if not http_request then
  73.         print("WARNING : failed to update. HTTP request failed.")
  74.         return
  75.     end
  76.     local body_content = http_request.readAll()
  77.     if body_content == "" then
  78.         print("WARNING : failed to update. Request body is empty.")
  79.         return
  80.     end
  81.     local file_name = (status == "RELEASE") and "startup" or "player_detector_dev"
  82.     local file = fs.open(file_name, "w")
  83.     file.write(body_content)
  84.     file.close()
  85.     if should_old_config_be_erased then
  86.         shell.run("rm config.json")
  87.     else
  88.         if fs.exists("config.json") then -- prevent from writing a config if none already exist
  89.             config["version"] = defaultConfig["version"]
  90.             saveConfig()
  91.         end
  92.     end
  93.     if status == "RELEASE" then
  94.         shell.run("rm player_detector_dev")
  95.     end
  96.     print("INFO : update successful.\nINFO : reboot...")
  97.     sleep(5)
  98.     os.reboot()
  99. end
  100.  
  101. -- Returns true if the server ip exists, false otherwise and nil if the API is not reachable
  102. local function isServerIpValid(input)
  103.     local http_request = http.get(defaultConfig["api_uri"] .. input)
  104.     if not http_request then
  105.         print("WARNING : failed to access the API. HTTP request failed.")
  106.         return nil
  107.     end
  108.     local body_content = http_request.readAll()
  109.     if body_content == "[]" or body_content == "[]" then
  110.         return false
  111.     end
  112.     return true
  113. end
  114.  
  115. -- Ask the player to write the pseudos to detect and update the config
  116. local function setPseudosList(save_config)
  117.     config["pseudos"] = {}
  118.     print("\nEcris les pseudos a detecter (appuyer sur entrer pour l'ajout et aussi quand tu as termine) :")
  119.     local input
  120.     repeat
  121.         input = io.read()
  122.         if input ~= "" then
  123.             table.insert(config["pseudos"], input)
  124.         end
  125.     until input==""
  126.     if save_config then
  127.         saveConfig()
  128.     end
  129. end
  130.  
  131. -- Ask the player to write the IP of the server he is on and update the config
  132. local function setServer(save_config)
  133.     print("\nEcris l'IP du serveur sur lequel tu es (ex: infinity.mineaurion.com) :")
  134.     local input
  135.     repeat
  136.         if input then -- enters the condition only if the player entered a wrong server IP
  137.             print("\nL'IP renseignee n'existe pas ou l'API Mineaurion n'est pas accessible.")
  138.             print("Retente :")
  139.         end
  140.         input = io.read()
  141.     until isServerIpValid(input)
  142.     config["server_ip"] = input
  143.     if save_config then
  144.         saveConfig()
  145.     end
  146. end
  147.  
  148. -- Ask the player to configure sides where the redstone will be output
  149. local function setSides(save_config)
  150.     print("\nEcris 0 ou 1 selon si tu veux que le signal de redstone soit emit ou pas :")
  151.     for side,status in pairs(config["sides"]) do
  152.         print(side .. " : " .. tostring(status) .. " (statut courant)")
  153.         local input = io.read()
  154.         local new_status = (input == "") or toBoolean(input)
  155.         config["sides"][side] = new_status
  156.         rs.setOutput(side, false)
  157.     end
  158.     if save_config then
  159.         saveConfig()
  160.     end
  161. end
  162.  
  163. local function init()
  164.     -- load json API
  165.     if not (fs.exists("json") or fs.exists("json.lua") or fs.exists("rom/modules/main/json.lua") or fs.exists("rom/modules/main/json.lua")) then
  166.         print("INFO : json API not installed yet, downloading...")
  167.         local http_request = http.get("https://raw.githubusercontent.com/DaikiKaminari/CC-Libs/master/ObjectJSON/json.lua")
  168.         assert(http_request, "ERROR : failed to download the json API. HTTP request failed.")
  169.         local f = fs.open("json.lua", "w")
  170.         f.write(http_request.readAll())
  171.         f.close()
  172.         print("INFO : json API installed.")
  173.     end
  174.     json = require("json")
  175.  
  176.     -- check update
  177.     local is_up_to_date, should_old_config_be_erased, status = isUpToDate()
  178.     if is_up_to_date then
  179.         print("INFO : Up to date in version : " .. defaultConfig["version"] .. "-" .. defaultConfig["status"])
  180.     elseif is_up_to_date == "nil" then
  181.         print("INFO : Checking for updates failed.")
  182.     else
  183.         print("INFO : Updating...")
  184.         update(should_old_config_be_erased, status) -- the computer should reboot if the update is successful
  185.         print("INFO : Update failed.")
  186.     end
  187.  
  188.     -- Check if config file exists, otherwise create it
  189.     if not fs.exists("config.json") then
  190.         config = defaultConfig
  191.         -- Reset display
  192.         term.clear()
  193.         term.setCursorPos(1, 1)
  194.         -- Input
  195.         setPseudosList(false)
  196.         setServer(false)
  197.         -- Write config
  198.         saveConfig()
  199.         print("INFO : config saved.\n")
  200.     end
  201.  
  202.     -- Read config file
  203.     config = json.decodeFromFile("/config.json")
  204.  
  205.     -- rename the computer in order to preserve the program if the computer is removed and replaced
  206.     local pseudos_str = ""
  207.     for _,pseudo in pairs(config["pseudos"]) do
  208.         pseudos_str = pseudos_str .. "_" .. pseudo
  209.     end
  210.     shell.run("label set player_detector_de" .. pseudos_str)
  211. end
  212.  
  213. --- FUNCTIONS ---
  214. -- Returns true if the player is connected, false otherwise
  215. local function arePlayersConnected(registered_pseudos, serverID)
  216.     local http_request = http.get(config["api_uri"] .. serverID)
  217.     if not http_request then
  218.         print("WARNING : unable to reach Mineaurion API. HTTP request failed.")
  219.         return false
  220.     end
  221.     local body_content = http_request.readAll()
  222.     if body_content == "" or body_content == "[]" then
  223.         print("WARNING : unable to reach Mineaurion API. Request body is empty.")
  224.         return false
  225.     end
  226.  
  227.     local body_content = json.decode(body_content)
  228.     local connected_players = body_content["joueurs"]
  229.     if not connected_players or not next(connected_players) then
  230.         return false
  231.     end
  232.     for _,pseudo in pairs(registered_pseudos) do
  233.         if hasValue(connected_players, pseudo) then
  234.             return true
  235.         end
  236.     end
  237.     return false
  238. end
  239.  
  240. -- Send or cut the redstone signal on all defined sides
  241. local function actualizeRedstone(player_connected)
  242.     for side,status in pairs(config["sides"]) do
  243.         if status then
  244.             rs.setOutput(side, config["emit_redstone_when_connected"] == player_connected)
  245.         end
  246.     end
  247. end
  248.  
  249. -- Change the config
  250. local function doAction(key)
  251.     if string.upper(key) == "RESET_PSEUDOS" then
  252.         setPseudosList(true)
  253.     elseif string.upper(key) == "RESET_SERVER_IP" then
  254.         setServer(true)
  255.     elseif string.upper(key) == "CONFIG_SIDES" then
  256.         setSides(true)
  257.     elseif string.upper(key) == "REBOOT" then
  258.         os.reboot()
  259.     else
  260.         print("\nCommande non reconnue, liste des commandes reconnues : RESET_PSEUDOS, RESET_SERVER_IP, CONFIG_SIDES, REBOOT")
  261.         return
  262.     end
  263.     os.reboot()
  264. end
  265.  
  266. --- MAIN ---
  267. local function runDetector()
  268.     while true do
  269.         local is_someone_connected = arePlayersConnected(config["pseudos"], config["server_ip"])
  270.         actualizeRedstone(is_someone_connected)
  271.         sleep(60)
  272.     end
  273. end
  274.  
  275. local function runDetectAction()
  276.     while true do
  277.         print("\nPour reset la config taper au choix ou reboot, ecris : RESET_PSEUDOS, RESET_SERVER_IP, CONFIG_SIDES, REBOOT")
  278.         local input = io.read()
  279.         doAction(input)
  280.         sleep(0)
  281.     end
  282. end
  283.  
  284. local function main()
  285.     init()
  286.     print("\nDetecte les joueurs : " .. textutils.serialise(config["pseudos"]))
  287.     print("Sur le serveur : " .. config["server_ip"])
  288.     if config["emit_redstone_when_connected"] then
  289.         print("\nEmet un signal de redstone quand un des joueur est connecte, sinon non.")
  290.         print("Pour couper un spawner il faut donc inverser le signal, il est possible d'utiliser des transmitter/receiver de redstone.")
  291.     else
  292.         print("\nN'emet PAS signal redstone quand un des joueur est connecte, sinon oui.")
  293.         print("Il suffit de coller le computer aux spawners, ou d'utiliser des transmitter/receiver de redstone.")
  294.     end
  295.     parallel.waitForAny(runDetector, runDetectAction)
  296. end
  297.  
  298. main()
Add Comment
Please, Sign In to add comment