84 lines
2.9 KiB
Lua
84 lines
2.9 KiB
Lua
local nk = require("nakama")
|
|
|
|
local utils = {}
|
|
|
|
utils.ADMIN_ROLES = { ["admin"] = true, ["moderator"] = true, ["owner"] = true }
|
|
utils.SYSTEM_USER_ID = "00000000-0000-0000-0000-000000000000"
|
|
|
|
function utils.is_admin(context)
|
|
if not context.user_id then return false end
|
|
|
|
local status, account = pcall(nk.account_get_id, context.user_id)
|
|
if not status or not account then return false end
|
|
|
|
local metadata = {}
|
|
if type(account.user.metadata) == "string" then
|
|
status, metadata = pcall(nk.json_decode, account.user.metadata)
|
|
if not status then metadata = {} end
|
|
else
|
|
metadata = account.user.metadata or {}
|
|
end
|
|
|
|
local role = metadata.role or ""
|
|
return utils.ADMIN_ROLES[role] == true
|
|
end
|
|
|
|
function utils.is_match_host(context, match_id)
|
|
if not context.user_id or not match_id then return false end
|
|
local status, match = pcall(nk.match_get, match_id)
|
|
if not status or not match then return false end
|
|
|
|
-- Needs to decode match.state if you're using authoritative matches
|
|
-- Simplified for lua translation:
|
|
local state = {}
|
|
if match.state then
|
|
status, state = pcall(nk.json_decode, match.state)
|
|
if not status then state = {} end
|
|
end
|
|
return state.hostUserId == context.user_id
|
|
end
|
|
|
|
function utils.require_admin(context)
|
|
if not utils.is_admin(context) then
|
|
error("Admin privileges required")
|
|
end
|
|
end
|
|
|
|
function utils.require_admin_or_host(context, match_id)
|
|
if not utils.is_admin(context) and not utils.is_match_host(context, match_id) then
|
|
error("Admin or host privileges required")
|
|
end
|
|
end
|
|
|
|
-- Channel type constants for nk.channel_id_build (Nakama Lua runtime).
|
|
-- NOTE: these differ from the Godot client's NakamaSocket.ChannelType enum.
|
|
utils.CHANNEL_TYPE_ROOM = 1
|
|
utils.CHANNEL_TYPE_DIRECT = 2
|
|
utils.CHANNEL_TYPE_GROUP = 3
|
|
|
|
-- Resolve a chat channel identifier for admin chat RPCs.
|
|
--
|
|
-- The client may send either an already-hashed Nakama channel ID, or a friendly
|
|
-- room name (e.g. "social_global"). A raw room name is NOT a valid channel ID for
|
|
-- nk.channel_messages_list, so we build the canonical hashed ID via the
|
|
-- authoritative nk.channel_id_build API (system user as sender → global room).
|
|
-- Returns the resolved channel ID, or the original value if it already looks
|
|
-- hashed / can't be built.
|
|
function utils.resolve_channel_id(channel_id)
|
|
if not channel_id or channel_id == "" then
|
|
return ""
|
|
end
|
|
-- A hashed Nakama channel ID contains a '.' separator; a plain room name does
|
|
-- not. Only treat dot-free values as room names needing resolution.
|
|
if string.find(channel_id, "%.") then
|
|
return channel_id
|
|
end
|
|
local status, built = pcall(nk.channel_id_build, "", channel_id, utils.CHANNEL_TYPE_ROOM)
|
|
if status and built and built ~= "" then
|
|
return built
|
|
end
|
|
return channel_id
|
|
end
|
|
|
|
return utils
|