diff --git a/player-sensor/ligma.lua b/player-sensor/ligma.lua new file mode 100644 index 0000000..efab9ec --- /dev/null +++ b/player-sensor/ligma.lua @@ -0,0 +1,98 @@ +-- Configuration + +local WH_URL = "https://discord.com/api/webhooks/id/token" +local IGNORE = { "player1", "player2" } -- case sensitive +local DIMENSION = "minecraft:overworld" -- dimension the area is in +local AREA = { -- The cubic area to monitor for players + [0] = { x = 100, y = 0, z = 200 }, -- Position 1 + [1] = { x = 200, y = 200, z = 300 } -- Position 2 +} +local REDSTONE_SIDE = "right" -- pulse a redstone signal to this side whenever a player is detected + +-- End of configuration + +local sensor = peripheral.find("playerDetector") +local KNOWN_PLAYERS = {} +local COOLDOWNS = {} +local COOLDOWN = 0.1 + +function sendWhMessage(msg) + local payload = { content = msg } + http.post(WH_URL, + textutils.serializeJSON(payload), + { ["Content-Type"] = "application/json" }) +end + +function findPlayers() + local players = sensor.getPlayersInCoords(AREA[0], AREA[1]) + return players +end + +function getPlayerPos(player) + local pos = sensor.getPlayerPos(player) + return pos +end + +function isInArr(arr, val) + for k,v in pairs(arr) do + if v == val then return k end + end + return false +end + +function bell() + redstone.setOutput(REDSTONE_SIDE, true) + sleep(0.1) + redstone.setOutput(REDSTONE_SIDE, false) +end + +function timestamp() + return (os.day() * 24) + os.time() +end + +function isCooldown(player) + local item = COOLDOWNS[player] + local time = timestamp() + return not (not item or item < time) +end + +function setCooldown(player) + COOLDOWNS[player] = timestamp() + COOLDOWN +end + +function isIgnore(player) + return isInArr(IGNORE, player) ~= false +end + +while true do + local found = findPlayers() + + -- check for new players + for k,v in pairs(found) do + local pos = getPlayerPos(v) + local inArr = isInArr(KNOWN_PLAYERS, v) + + if pos ~= nil and pos.dimension == DIMENSION and not inArr and not isCooldown(v) and not isIgnore(v) then + setCooldown(v) + print("Player "..v.." entered area") + bell() + sendWhMessage("Player `"..v.."` entered area ".. + "at `"..pos.x..","..pos.y..","..pos.z.."`.") + + table.insert(KNOWN_PLAYERS, v) + end + end + + -- check if players left the area + for k,v in pairs(KNOWN_PLAYERS) do + local pos = getPlayerPos(v) + if pos ~= nil and (not isInArr(found, v) or pos.dimension ~= DIMENSION) and not isCooldown(v) and not isIgnore(v) then + setCooldown(v) + print("Player "..v.." left area") + bell() + sendWhMessage("Player `"..v.."` left area at `".. + pos.x..","..pos.y..","..pos.z.."`.") + table.remove(KNOWN_PLAYERS, isInArr(KNOWN_PLAYERS, v)) + end + end +end