Advertisement
DaikiKaminari

playerDetectorV2

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