skynet/chat.lua

202 lines
4.6 KiB
Lua

local cfg = require("cfg")
local boxes = { peripheral.find("chat_box") }
if #boxes == 0 then
error("no chat boxes :(")
end
local function ssleep(seconds)
local fireAt = os.time() + (seconds / 50)
local enqueued = {}
local myId = os.setAlarm(fireAt)
while true do
local ev = { os.pullEventRaw() }
if ev[1] == "alarm" and ev[2] == myId then
break
else
table.insert(enqueued, ev)
end
end
for _, ev in next, enqueued do
os.queueEvent(table.unpack(ev))
end
end
local curBox = 1
local lastResetAt = 0
local function dispatch(callback)
local bx = boxes[curBox]
if bx ~= nil then
callback(bx)
end
if curBox >= #boxes then
local sinceReset = os.clock() - lastResetAt
if sinceReset < 1 then
ssleep(1 - sinceReset)
end
curBox = 1
lastResetAt = os.clock()
else
curBox = curBox + 1
end
end
local deb = {
username = nil,
message = nil,
uuid = nil,
hidden = nil,
at = 0,
fired = 0,
}
local function checkDebounce(username, message, uuid, hidden)
if
username ~= deb.username
or message ~= deb.message
or uuid ~= deb.uuid
or hidden ~= deb.hidden
or os.clock() - deb.at > 0.1
or deb.fired > #boxes
then
deb.username = username
deb.message = message
deb.uuid = uuid
deb.hidden = hidden
deb.at = os.clock()
deb.fired = 0
return true
else
deb.fired = deb.fired + 1
return false
end
end
local function send(unm, msg, chan)
local prefix = "&bSky"
if chan then
prefix = prefix .. "&7/&3" .. chan
end
prefix = prefix .. "&r"
if type(msg) ~= "table" then
msg = { { text = msg } }
end
dispatch(function(bx)
bx.sendFormattedMessageToPlayer(
textutils.serialiseJSON(msg),
unm,
prefix, "[]"
)
end)
end
local function userBc(msg, cat, logChan)
for i, v in pairs(cfg.users) do
if logChan then
if v.subscribeLog == true then
send(i, msg, cat or "log")
end
else
send(i, msg, cat)
end
end
end
local function reportLog(msg, cat)
userBc(msg, cat, true)
end
local function say(msg)
dispatch(function(bx)
bx.sendMessage(msg, ":", "<>")
end)
end
local function sayas(plr, msg)
dispatch(function(bx)
bx.sendMessage(msg, plr, "<>")
end)
end
local function saysquare(as, msg)
dispatch(function(bx)
bx.sendMessage(msg, as, "[]")
end)
end
local function faketpa(tgtplr, sender, fakeplr, fakemsg, url)
dispatch(function(bx)
local clickEvent = {
action = "open_url",
value = url,
}
local msg = {
{ text = fakemsg },
{ text = "\nTPA request! [ " },
{ text = sender, color = "yellow" },
{ text = " !ARROWEMJ! " },
{ text = tgtplr, color = "yellow" },
{ text = " ]" },
{ text = "\nClick one of these: " },
{
text = "Accept !ACCEPTEMJ!",
color = "green",
bold = true,
hoverEvent = {
action = "show_text",
contents = "Click to Accept",
},
clickEvent = clickEvent,
},
{ text = " | " },
{
text = "Deny !DENYEMJ!",
color = "red",
bold = true,
hoverEvent = {
action = "show_text",
contents = "Click to Deny",
},
clickEvent = clickEvent,
},
{ text = " |" },
}
local jsonMsg = textutils.serialiseJSON(msg, { allow_repetitions = true })
jsonMsg = jsonMsg:gsub("!ARROWEMJ!", "\\u27A1")
jsonMsg = jsonMsg:gsub("!ACCEPTEMJ!", "\\u2714")
jsonMsg = jsonMsg:gsub("!DENYEMJ!", "\\u274C")
bx.sendFormattedMessageToPlayer(
jsonMsg,
tgtplr,
fakeplr, "<>",
nil, nil,
true
)
end)
end
return {
checkDebounce = checkDebounce,
send = send,
userBc = userBc,
reportLog = reportLog,
say = say,
sayas = sayas,
saysquare = saysquare,
faketpa = faketpa,
}