Make user slash command work
This commit is contained in:
@ -14,7 +14,7 @@ local function QueryParams(Params) -- {Name = Value, ...}
|
|||||||
|
|
||||||
for ParamName, ParamValue in next, Params do
|
for ParamName, ParamValue in next, Params do
|
||||||
if ParamValue ~= nil then
|
if ParamValue ~= nil then
|
||||||
QueryString = QueryString .. ParamName .. "=" .. ParamValue .. "&"
|
QueryString = QueryString .. tostring(ParamName) .. "=" .. tostring(ParamValue) .. "&"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -22,10 +22,11 @@ local function QueryParams(Params) -- {Name = Value, ...}
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function CreateHeaders(Headers) -- {Name = Value, ...}
|
local function CreateHeaders(Headers) -- {Name = Value, ...}
|
||||||
|
if not Headers then return {} end
|
||||||
local RequestHeaders = {}
|
local RequestHeaders = {}
|
||||||
|
|
||||||
for HeaderName, HeaderValue in next, Headers do
|
for HeaderName, HeaderValue in next, Headers do
|
||||||
RequestHeaders[#RequestHeaders + 1] = { HeaderName, HeaderValue }
|
RequestHeaders[#RequestHeaders + 1] = { tostring(HeaderName), tostring(HeaderValue) }
|
||||||
end
|
end
|
||||||
|
|
||||||
return RequestHeaders
|
return RequestHeaders
|
||||||
@ -49,7 +50,7 @@ local function NormalizeHeaders(Response)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Request(Method, Url, Params, Headers, Callback)
|
local function Request(Method, Url, Params, RequestHeaders, RequestBody, Callback)
|
||||||
if not METHODS[Method] then
|
if not METHODS[Method] then
|
||||||
error("[HTTP] Method " .. Method .. " is not supported.")
|
error("[HTTP] Method " .. Method .. " is not supported.")
|
||||||
end
|
end
|
||||||
@ -58,23 +59,27 @@ local function Request(Method, Url, Params, Headers, Callback)
|
|||||||
error("[HTTP] Url is not a string")
|
error("[HTTP] Url is not a string")
|
||||||
end
|
end
|
||||||
|
|
||||||
local QueryString = QueryParams(Params) -- at worse (I think), this is an empty string (which cannot mess up the request)
|
if type(RequestBody) == "table" then
|
||||||
|
RequestBody = json.encode(RequestBody)
|
||||||
|
end
|
||||||
|
|
||||||
local RequestHeaders = CreateHeaders(Headers) -- At worse, this will just be an empty table (which cannot mess up the request)
|
local QueryString = QueryParams(Params) -- at worse (I think), this is an empty string (which cannot mess up the request)
|
||||||
|
|
||||||
|
local FormattedHeaders = CreateHeaders(RequestHeaders) -- At worse, this will just be an empty table (which cannot mess up the request)
|
||||||
|
|
||||||
local RequestUrl = Url .. QueryString
|
local RequestUrl = Url .. QueryString
|
||||||
print(RequestUrl)
|
print(RequestUrl)
|
||||||
|
|
||||||
if Callback and type(Callback) == "function" then
|
if Callback and type(Callback) == "function" then
|
||||||
return coroutine.wrap(function()
|
return coroutine.wrap(function()
|
||||||
local Response, Body = HTTPRequest(Method, RequestUrl, RequestHeaders)
|
local Headers, Body = HTTPRequest(Method, RequestUrl, FormattedHeaders, RequestBody)
|
||||||
NormalizeHeaders(Response)
|
NormalizeHeaders(Headers)
|
||||||
Callback(Response, TryDecodeJson(Body))
|
Callback(Headers, TryDecodeJson(Body))
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
local Response, Body = HTTPRequest(Method, RequestUrl, RequestHeaders)
|
local Headers, Body = HTTPRequest(Method, RequestUrl, FormattedHeaders, RequestBody)
|
||||||
NormalizeHeaders(Response)
|
NormalizeHeaders(Headers)
|
||||||
return Response, TryDecodeJson(Body)
|
return Headers, TryDecodeJson(Body)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -7,9 +7,41 @@ local Headers = {
|
|||||||
["X-API-Key"] = APIKeys.StrafesNET
|
["X-API-Key"] = APIKeys.StrafesNET
|
||||||
}
|
}
|
||||||
|
|
||||||
local API_URL = "https://api.strafes.net/api/v1/"
|
function L1Copy(t, b)
|
||||||
|
b = b or {}
|
||||||
|
for x, y in next, t do b[x] = y end
|
||||||
|
return b
|
||||||
|
end
|
||||||
|
|
||||||
local API_ENDPOINTS = {
|
local STRAFESNET_API_URL = "https://api.strafes.net/api/v1/"
|
||||||
|
local FIVEMAN_API_URL = 'https://api.fiveman1.net/v1/'
|
||||||
|
local ROBLOX_API_URL = 'https://users.roblox.com/v1/'
|
||||||
|
local ROBLOX_BADGES_API = 'https://badges.roblox.com/v1/'
|
||||||
|
local ROBLOX_PRESENCE_URL = 'https://presence.roblox.com/v1/'
|
||||||
|
local ROBLOX_THUMBNAIL_URL = 'https://thumbnails.roblox.com/v1/'
|
||||||
|
local ROBLOX_INVENTORY_API = 'https://inventory.roblox.com/v1/'
|
||||||
|
local ROBLOX_GROUPS_ROLES_URL = 'https://groups.roblox.com/v2/users/%s/groups/roles'
|
||||||
|
|
||||||
|
ROBLOX_THUMBNAIL_SIZES = {
|
||||||
|
[48] = '48x48',
|
||||||
|
[50] = '50x50',
|
||||||
|
[60] = '60x60',
|
||||||
|
[75] = '75x75',
|
||||||
|
[100] = '100x100',
|
||||||
|
[110] = '110x110',
|
||||||
|
[150] = '150x150',
|
||||||
|
[180] = '180x180',
|
||||||
|
[352] = '352x352',
|
||||||
|
[420] = '420x420',
|
||||||
|
[720] = '720x720'
|
||||||
|
}
|
||||||
|
ROBLOX_THUMBNAIL_TYPES = {
|
||||||
|
AVATAR = 'avatar',
|
||||||
|
BUST = 'avatar-bust',
|
||||||
|
HEADSHOT = 'avatar-headshot'
|
||||||
|
}
|
||||||
|
|
||||||
|
local STRAFESNET_API_ENDPOINTS = {
|
||||||
MAPS = {
|
MAPS = {
|
||||||
LIST = "map",
|
LIST = "map",
|
||||||
GET = "map/%d"
|
GET = "map/%d"
|
||||||
@ -33,19 +65,19 @@ local API_ENDPOINTS = {
|
|||||||
local StrafesNET = {}
|
local StrafesNET = {}
|
||||||
|
|
||||||
function StrafesNET.ListMaps(GameId, PageSize, PageNumber)
|
function StrafesNET.ListMaps(GameId, PageSize, PageNumber)
|
||||||
local RequestUrl = API_URL .. API_ENDPOINTS.MAPS.LIST
|
local RequestUrl = STRAFESNET_API_URL .. STRAFESNET_API_ENDPOINTS.MAPS.LIST
|
||||||
local Params = { game_id = GameId, page_size = PageSize or 10, page_number = PageNumber or 1 }
|
local Params = { game_id = GameId, page_size = PageSize or 10, page_number = PageNumber or 1 }
|
||||||
return Request("GET", RequestUrl, Params, Headers)
|
return Request("GET", RequestUrl, Params, Headers)
|
||||||
end
|
end
|
||||||
|
|
||||||
function StrafesNET.GetMap(MapId)
|
function StrafesNET.GetMap(MapId)
|
||||||
local RequestUrl = API_URL .. API_ENDPOINTS.MAPS.GET:format(MapId)
|
local RequestUrl = STRAFESNET_API_URL .. STRAFESNET_API_ENDPOINTS.MAPS.GET:format(MapId)
|
||||||
local Params = { id = MapId }
|
local Params = { id = MapId }
|
||||||
return Request("GET", RequestUrl, Params, Headers)
|
return Request("GET", RequestUrl, Params, Headers)
|
||||||
end
|
end
|
||||||
|
|
||||||
function StrafesNET.ListRanks(GameId, ModeId, StyleId, SortBy, PageSize, PageNumber)
|
function StrafesNET.ListRanks(GameId, ModeId, StyleId, SortBy, PageSize, PageNumber)
|
||||||
local RequestUrl = API_URL .. API_ENDPOINTS.RANKS.LIST
|
local RequestUrl = STRAFESNET_API_URL .. STRAFESNET_API_ENDPOINTS.RANKS.LIST
|
||||||
local Params = {
|
local Params = {
|
||||||
gameId = GameId,
|
gameId = GameId,
|
||||||
modeId = ModeId,
|
modeId = ModeId,
|
||||||
@ -58,7 +90,7 @@ function StrafesNET.ListRanks(GameId, ModeId, StyleId, SortBy, PageSize, PageNum
|
|||||||
end
|
end
|
||||||
|
|
||||||
function StrafesNET.ListTimes(UserId, MapId, GameId, ModeId, StyleId, SortBy, PageSize, PageNumber)
|
function StrafesNET.ListTimes(UserId, MapId, GameId, ModeId, StyleId, SortBy, PageSize, PageNumber)
|
||||||
local RequestUrl = API_URL .. API_ENDPOINTS.TIMES.LIST
|
local RequestUrl = STRAFESNET_API_URL .. STRAFESNET_API_ENDPOINTS.TIMES.LIST
|
||||||
local Params = {
|
local Params = {
|
||||||
user_id = UserId,
|
user_id = UserId,
|
||||||
map_id = MapId,
|
map_id = MapId,
|
||||||
@ -73,12 +105,12 @@ function StrafesNET.ListTimes(UserId, MapId, GameId, ModeId, StyleId, SortBy, Pa
|
|||||||
end
|
end
|
||||||
|
|
||||||
function StrafesNET.GetTime(TimeId)
|
function StrafesNET.GetTime(TimeId)
|
||||||
local RequestUrl = API_URL .. API_ENDPOINTS.TIMES.GET:format(TimeId)
|
local RequestUrl = STRAFESNET_API_URL .. STRAFESNET_API_ENDPOINTS.TIMES.GET:format(TimeId)
|
||||||
return Request("GET", RequestUrl, nil, Headers)
|
return Request("GET", RequestUrl, nil, Headers)
|
||||||
end
|
end
|
||||||
|
|
||||||
function StrafesNET.ListUsers(StateId, PageSize, PageNumber)
|
function StrafesNET.ListUsers(StateId, PageSize, PageNumber)
|
||||||
local RequestUrl = API_URL .. API_ENDPOINTS.USERS.LIST
|
local RequestUrl = STRAFESNET_API_URL .. STRAFESNET_API_ENDPOINTS.USERS.LIST
|
||||||
local Params = {
|
local Params = {
|
||||||
state_id = StateId,
|
state_id = StateId,
|
||||||
page_size = PageSize or 10,
|
page_size = PageSize or 10,
|
||||||
@ -88,12 +120,12 @@ function StrafesNET.ListUsers(StateId, PageSize, PageNumber)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function StrafesNET.GetUser(UserId)
|
function StrafesNET.GetUser(UserId)
|
||||||
local RequestUrl = API_URL .. API_ENDPOINTS.USERS.GET:format(UserId)
|
local RequestUrl = STRAFESNET_API_URL .. STRAFESNET_API_ENDPOINTS.USERS.GET:format(UserId)
|
||||||
return Request("GET", RequestUrl, nil, Headers)
|
return Request("GET", RequestUrl, nil, Headers)
|
||||||
end
|
end
|
||||||
|
|
||||||
function StrafesNET.GetUserRank(UserId, GameId, ModeId, StyleId)
|
function StrafesNET.GetUserRank(UserId, GameId, ModeId, StyleId)
|
||||||
local RequestUrl = API_URL .. API_ENDPOINTS.USERS.RANKS.GET:format(UserId)
|
local RequestUrl = STRAFESNET_API_URL .. STRAFESNET_API_ENDPOINTS.USERS.RANKS.GET:format(UserId)
|
||||||
local Params = {
|
local Params = {
|
||||||
game_id = GameId,
|
game_id = GameId,
|
||||||
mode_id = ModeId,
|
mode_id = ModeId,
|
||||||
@ -102,4 +134,118 @@ function StrafesNET.GetUserRank(UserId, GameId, ModeId, StyleId)
|
|||||||
return Request("GET", RequestUrl, Params, Headers)
|
return Request("GET", RequestUrl, Params, Headers)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function StrafesNET.GetRobloxInfoFromUserId(USER_ID)
|
||||||
|
if not USER_ID then return 'empty id' end
|
||||||
|
return Request("GET", ROBLOX_API_URL .. "users/" .. USER_ID)
|
||||||
|
end
|
||||||
|
|
||||||
|
function StrafesNET.GetRobloxInfoFromUsername(USERNAME)
|
||||||
|
if not USERNAME then return 'empty username' end
|
||||||
|
if #USERNAME > 32 then return 'Username too long' end
|
||||||
|
|
||||||
|
local headers, body = Request("POST", ROBLOX_API_URL .. "usernames/users", nil,
|
||||||
|
{ ["Content-Type"] = "application/json" }, { usernames = { USERNAME } })
|
||||||
|
if not body or not body.data or not body.data[1] then
|
||||||
|
return 'Username \'' .. USERNAME .. '\' not found.'
|
||||||
|
end
|
||||||
|
|
||||||
|
return StrafesNET.GetRobloxInfoFromUserId(body.data[1].id)
|
||||||
|
end
|
||||||
|
|
||||||
|
function StrafesNET.GetRobloxInfoFromDiscordId(DISCORD_ID)
|
||||||
|
if not DISCORD_ID then return 'empty id' end
|
||||||
|
-- table.foreach(DISCORD_ID, print)
|
||||||
|
local headers, body = Request("GET", FIVEMAN_API_URL .. "users/" .. DISCORD_ID)
|
||||||
|
if headers.status == "error" then return headers.messages end
|
||||||
|
|
||||||
|
return Request("GET", ROBLOX_API_URL .. "users/" .. body.result.robloxId)
|
||||||
|
end
|
||||||
|
|
||||||
|
function StrafesNET.GetUserFromAny(user, message)
|
||||||
|
local str = user:match('^["\'](.+)[\'"]$')
|
||||||
|
local num = user:match('^(%d+)$')
|
||||||
|
|
||||||
|
if str then
|
||||||
|
local roblox_user = StrafesNET.GetRobloxInfoFromUsername(str)
|
||||||
|
if not roblox_user.id then return 'User not found' end
|
||||||
|
return roblox_user
|
||||||
|
elseif num then
|
||||||
|
local roblox_user = StrafesNET.GetRobloxInfoFromUserId(user)
|
||||||
|
if not roblox_user.id then return 'Invalid user id' end
|
||||||
|
return roblox_user
|
||||||
|
elseif user == 'me' then
|
||||||
|
local me = message.author
|
||||||
|
local roblox_user = StrafesNET.GetRobloxInfoFromDiscordId(me.id)
|
||||||
|
if not roblox_user.id then
|
||||||
|
return
|
||||||
|
'You are not registered with the fiveman1 api, use !link with the rbhop bot to link your roblox account'
|
||||||
|
end
|
||||||
|
return roblox_user
|
||||||
|
elseif user:match('<@%d+>') then
|
||||||
|
local user_id = user:match('<@(%d+)>')
|
||||||
|
local member = message.guild:getMember(user_id)
|
||||||
|
local roblox_user = StrafesNET.GetRobloxInfoFromDiscordId(member.id)
|
||||||
|
if not roblox_user.id then
|
||||||
|
return
|
||||||
|
'User is not registered with the fiveman1 api, use !link with the rbhop bot to link your roblox account'
|
||||||
|
end
|
||||||
|
return roblox_user
|
||||||
|
else
|
||||||
|
local roblox_user = StrafesNET.GetRobloxInfoFromUsername(user)
|
||||||
|
if not roblox_user.id then return 'User not found' end
|
||||||
|
return roblox_user
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function StrafesNET.GetUserOnlineStatus(USER_ID)
|
||||||
|
if not USER_ID then return 'empty id' end
|
||||||
|
|
||||||
|
local presence = Request("POST", ROBLOX_PRESENCE_URL .. "presence/users", { userIds = { USER_ID } }).userPresences
|
||||||
|
[1]
|
||||||
|
|
||||||
|
local last_online = Request("POST", ROBLOX_PRESENCE_URL .. "presence/last-online", { userIds = { USER_ID } })
|
||||||
|
.lastOnlineTimestamps[1]
|
||||||
|
|
||||||
|
L1Copy(last_online, presence)
|
||||||
|
return presence
|
||||||
|
end
|
||||||
|
|
||||||
|
function StrafesNET.GetUserUsernameHistory(USER_ID)
|
||||||
|
if not USER_ID then return 'empty id' end
|
||||||
|
return Request("GET", ROBLOX_API_URL .. "users/" .. USER_ID .. "/username-history",
|
||||||
|
{ limit = 50, sortOrder = 'Desc' })
|
||||||
|
end
|
||||||
|
|
||||||
|
function StrafesNET.GetBadgesAwardedDates(USER_ID, BADGE_LIST)
|
||||||
|
if not USER_ID then return 'empty id' end
|
||||||
|
return Request("GET", ROBLOX_BADGES_API .. "users/" .. USER_ID .. "/badges/awarded-dates",
|
||||||
|
{ badgeIds = table.concat(BADGE_LIST, ",") })
|
||||||
|
end
|
||||||
|
|
||||||
|
function StrafesNET.GetVerificationItemID(USER_ID)
|
||||||
|
if not USER_ID then return 'empty id' end
|
||||||
|
|
||||||
|
local headers1, body1 = Request("GET", ROBLOX_INVENTORY_API .. "users/" .. USER_ID .. "/items/Asset/102611803")
|
||||||
|
if body1.errors then return body1 end
|
||||||
|
|
||||||
|
local headers2, body2 = Request("GET", ROBLOX_INVENTORY_API .. "users/" .. USER_ID .. "/items/Asset/1567446")
|
||||||
|
if body2.errors then return body2 end
|
||||||
|
|
||||||
|
local data = {}
|
||||||
|
if body2.data and body2.data[1] then data[#data + 1] = body2.data[1] end
|
||||||
|
if body1.data and body1.data[1] then data[#data + 1] = body1.data[1] end
|
||||||
|
|
||||||
|
return { data = data }
|
||||||
|
end
|
||||||
|
|
||||||
|
function StrafesNET.GetUserThumbnail(USER_ID, TYPE, SIZE)
|
||||||
|
if not USER_ID then return 'empty id' end
|
||||||
|
|
||||||
|
local _TYPE = ROBLOX_THUMBNAIL_TYPES[TYPE] or "avatar"
|
||||||
|
local _SIZE = ROBLOX_THUMBNAIL_SIZES[SIZE] or "180x180"
|
||||||
|
|
||||||
|
return Request("GET", ROBLOX_THUMBNAIL_URL .. "users/" .. _TYPE,
|
||||||
|
{ userIds = USER_ID, size = _SIZE, format = "Png", isCircular = false })
|
||||||
|
end
|
||||||
|
|
||||||
return StrafesNET
|
return StrafesNET
|
||||||
|
@ -4,7 +4,7 @@ local Discordia = require('discordia')
|
|||||||
local Date = Discordia.Date
|
local Date = Discordia.Date
|
||||||
Discordia.extensions()
|
Discordia.extensions()
|
||||||
|
|
||||||
local API = require('../Modules/strafes_net.lua')
|
local StrafesNET = require('../Modules/StrafesNET.lua')
|
||||||
|
|
||||||
local UserCommand = SlashCommandTools.slashCommand('user', 'Looks up specified user on Roblox')
|
local UserCommand = SlashCommandTools.slashCommand('user', 'Looks up specified user on Roblox')
|
||||||
|
|
||||||
@ -17,181 +17,164 @@ UserCommand:addOption(UserIdOption)
|
|||||||
UserCommand:addOption(MemberOption)
|
UserCommand:addOption(MemberOption)
|
||||||
|
|
||||||
Badges = {
|
Badges = {
|
||||||
'275640532', --Bhop, pre-group
|
'275640532', --Bhop, pre-group
|
||||||
'363928432', --Surf, pre-group
|
'363928432', --Surf, pre-group
|
||||||
'2124614454', --Bhop, post-group
|
'2124614454', --Bhop, post-group
|
||||||
'2124615096', --Surf, post-group
|
'2124615096', --Surf, post-group
|
||||||
}
|
}
|
||||||
BadgesToName = {
|
BadgesToName = {
|
||||||
[275640532]='old bhop',
|
[275640532] = 'old bhop',
|
||||||
[363928432]='old surf',
|
[363928432] = 'old surf',
|
||||||
[2124614454]='new bhop',
|
[2124614454] = 'new bhop',
|
||||||
[2124615096]='new surf',
|
[2124615096] = 'new surf',
|
||||||
}
|
}
|
||||||
local function round(x,n)
|
local function round(x, n)
|
||||||
return string.format('%.'..(n or 0)..'f',x)
|
return string.format('%.' .. (n or 0) .. 'f', x)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function FromYMD(ymd)
|
local function FromYMD(ymd)
|
||||||
return Date.fromISO(ymd.."T00:00:00")[1]
|
return Date.fromISO(ymd .. "T00:00:00")[1]
|
||||||
end
|
end
|
||||||
local function leftpad(s,n,p)
|
local function leftpad(s, n, p)
|
||||||
return string.rep(p,n-#tostring(s))..s
|
return string.rep(p, n - #tostring(s)) .. s
|
||||||
end
|
end
|
||||||
local function ToYMD(seconds)
|
local function ToYMD(seconds)
|
||||||
return "<t:"..seconds..":R>"
|
return "<t:" .. seconds .. ":R>"
|
||||||
end
|
end
|
||||||
local IDToDate = { --Terrible ranges but it's all we have
|
local IDToDate = { --Terrible ranges but it's all we have
|
||||||
-- {1000000000, FromYMD("2006-01-01")}, --I guess?
|
-- {1000000000, FromYMD("2006-01-01")}, --I guess?
|
||||||
-- {1864564055, FromYMD("2008-08-04")},
|
-- {1864564055, FromYMD("2008-08-04")},
|
||||||
{1228821079, FromYMD("2013-02-07")}, -- asomstephano12344 (mass scanning near sign removal date)
|
{ 3800920136, FromYMD("2016-04-16") },
|
||||||
{3800920136, FromYMD("2016-04-16")},
|
{ 9855616205, FromYMD("2017-04-02") },
|
||||||
{9855616205, FromYMD("2017-04-02")},
|
{ 30361018662, FromYMD("2018-11-14") },
|
||||||
{30361018662, FromYMD("2018-11-14")},
|
{ 32665806459, FromYMD("2019-01-07") },
|
||||||
{32665806459, FromYMD("2019-01-07")},
|
{ 34758058773, FromYMD("2019-02-24") },
|
||||||
{34758058773, FromYMD("2019-02-24")},
|
{ 65918261258, FromYMD("2020-06-05") },
|
||||||
{65918261258, FromYMD("2020-06-05")},
|
{ 171994717435, FromYMD("2023-03-24") },
|
||||||
{171994717435, FromYMD("2023-03-24")},
|
{ 173210319088, FromYMD("2023-04-14") },
|
||||||
{173210319088, FromYMD("2023-04-14")},
|
{ 206368884641, FromYMD("2023-07-16") },
|
||||||
{206368884641, FromYMD("2023-07-16")},
|
{ 229093879745, FromYMD("2024-01-02") },
|
||||||
{229093879745, FromYMD("2024-01-02")},
|
{ 232802028144, FromYMD("2024-04-08") },
|
||||||
{232802028144, FromYMD("2024-04-08")},
|
{ 234886704167, FromYMD("2024-06-28") },
|
||||||
{234886704167, FromYMD("2024-06-28")},
|
{ 241580400713, FromYMD("2025-02-16") },
|
||||||
{241580400713, FromYMD("2025-02-16")},
|
|
||||||
{244356127782, FromYMD("2025-05-18")},
|
|
||||||
}
|
}
|
||||||
--We assume linear interpolation since anything more complex I can't process
|
--We assume linear interpolation since anything more complex I can't process
|
||||||
local function linterp(i1, i2, m)
|
local function linterp(i1, i2, m)
|
||||||
return math.floor(i1 + (i2-i1)*m)
|
return math.floor(i1 + (i2 - i1) * m)
|
||||||
end
|
end
|
||||||
local function GuessDateFromAssetID(InstanceID, AssetID)
|
local function GuessDateFromAssetID(AssetID)
|
||||||
local note = ""
|
|
||||||
if AssetID == 1567446 then
|
|
||||||
note = " (Verification Sign)"
|
|
||||||
end
|
|
||||||
for i = #IDToDate, 1, -1 do --Newest to oldest
|
for i = #IDToDate, 1, -1 do --Newest to oldest
|
||||||
local ID,Time = unpack(IDToDate[i])
|
local ID, Time = unpack(IDToDate[i])
|
||||||
if ID < InstanceID then
|
if ID < AssetID then
|
||||||
if not IDToDate[i+1] then
|
if not IDToDate[i + 1] then
|
||||||
-- Screw it we ball, just do unjustified interpolation
|
return "After " .. ToYMD(Time)
|
||||||
local ID1, Time1 = unpack(IDToDate[#IDToDate-1])
|
|
||||||
local ID2, Time2 = unpack(IDToDate[#IDToDate])
|
|
||||||
return "Around "..ToYMD(linterp(Time1, Time2, (InstanceID-ID1)/(ID2-ID1)))..note
|
|
||||||
end
|
end
|
||||||
local ParentID, ParentTime = unpack(IDToDate[i+1])
|
local ParentID, ParentTime = unpack(IDToDate[i + 1])
|
||||||
return "Around "..ToYMD(linterp(Time, ParentTime, (InstanceID-ID)/(ParentID-ID)))..note
|
return "Around " .. ToYMD(linterp(Time, ParentTime, (AssetID - ID) / (ParentID - ID)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Screw it we ball, just do unjustified interpolation
|
return "Before " .. ToYMD(IDToDate[1][2])
|
||||||
local ID1, Time1 = unpack(IDToDate[1])
|
|
||||||
local ID2, Time2 = unpack(IDToDate[2])
|
|
||||||
return "Around "..ToYMD(linterp(Time1, Time2, (InstanceID-ID1)/(ID2-ID1)))..note
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function Callback(Interaction, Command, Args)
|
local function Callback(Interaction, Command, Args)
|
||||||
local user_info
|
local user_info
|
||||||
if Args then
|
if Args then
|
||||||
local username = Args.username
|
local username = Args.username
|
||||||
local user_id = Args.user_id
|
local user_id = Args.user_id
|
||||||
local member = Args.member
|
local member = Args.member
|
||||||
if username then
|
if username then
|
||||||
user_info = API:GetRobloxInfoFromUsername(username)
|
_, user_info = StrafesNET.GetRobloxInfoFromUsername(username)
|
||||||
elseif user_id then
|
elseif user_id then
|
||||||
user_info = API:GetRobloxInfoFromUserId(user_id)
|
_, user_info = StrafesNET.GetRobloxInfoFromUserId(user_id)
|
||||||
elseif member then
|
elseif member then
|
||||||
user_info = API:GetRobloxInfoFromDiscordId(member.id)
|
_, user_info = StrafesNET.GetRobloxInfoFromDiscordId(member.id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local user = Interaction.member or Interaction.user
|
local user = Interaction.member or Interaction.user
|
||||||
if user then
|
if user then
|
||||||
user_info = API:GetRobloxInfoFromDiscordId(user.id)
|
_, user_info = StrafesNET.GetRobloxInfoFromDiscordId(user.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not user_info.id then
|
if not user_info.id then
|
||||||
return error("User not found")
|
return error("User not found")
|
||||||
end
|
end
|
||||||
|
|
||||||
local description = user_info.description=='' and 'This user has no description' or user_info.description
|
local description = user_info.description == '' and 'This user has no description' or user_info.description
|
||||||
-- table.foreach(user_info,print)
|
|
||||||
local created = tostring(Date.fromISO(user_info.created):toSeconds())
|
local created = tostring(Date.fromISO(user_info.created):toSeconds())
|
||||||
local current = Date():toSeconds()
|
local current = Date():toSeconds()
|
||||||
local accountAge = round((current-created)/86400)
|
local accountAge = round((current - created) / 86400)
|
||||||
local isBanned = user_info.isBanned
|
local isBanned = user_info.isBanned
|
||||||
local id = user_info.id
|
local id = user_info.id
|
||||||
local name = user_info.name
|
local name = user_info.name
|
||||||
local displayName = user_info.displayName
|
local displayName = user_info.displayName
|
||||||
|
|
||||||
local usernameHistory = API:GetUserUsernameHistory(id).data or {}
|
local usernameHistoryHeaders, usernameHistoryBody = StrafesNET.GetUserUsernameHistory(id)
|
||||||
|
local usernameHistory = usernameHistoryBody.data or {}
|
||||||
local usernameHistoryTable = {}
|
local usernameHistoryTable = {}
|
||||||
for index,usernameObj in next,usernameHistory do
|
for index, usernameObj in next, usernameHistory do
|
||||||
table.insert(usernameHistoryTable,usernameObj.name)
|
table.insert(usernameHistoryTable, usernameObj.name)
|
||||||
end
|
end
|
||||||
local usernameHistoryString = table.concat(usernameHistoryTable,', ')
|
local usernameHistoryString = table.concat(usernameHistoryTable, ', ')
|
||||||
|
|
||||||
local onlineStatus_info = {lastLocation="Unknown", lastOnline=0, userPresenceType=-1}
|
local onlineStatus_info = { lastLocation = "Unknown", lastOnline = 0, userPresenceType = -1 }
|
||||||
-- table.foreach(onlineStatus_info,print)
|
-- table.foreach(onlineStatus_info,print)
|
||||||
|
|
||||||
local LastLocation = onlineStatus_info.lastLocation
|
local LastLocation = onlineStatus_info.lastLocation
|
||||||
if onlineStatus_info.userPresenceType==2 then LastLocation="Ingame" end
|
if onlineStatus_info.userPresenceType == 2 then LastLocation = "Ingame" end
|
||||||
local LastOnline = 0--Date.fromISO(onlineStatus_info.lastOnline):toSeconds()
|
local LastOnline = 0 --Date.fromISO(onlineStatus_info.lastOnline):toSeconds()
|
||||||
|
|
||||||
local verificationAssetId = API:GetVerificationItemID(id)
|
local verificationAssetId = StrafesNET.GetVerificationItemID(id)
|
||||||
local verificationDate = "Not verified"
|
local verificationDate = "Not verified"
|
||||||
if verificationAssetId.errors then
|
if verificationAssetId.errors then
|
||||||
verificationDate = "Failed to fetch"
|
verificationDate = "Failed to fetch"
|
||||||
elseif verificationAssetId.data[1] then
|
elseif verificationAssetId.data[1] then
|
||||||
verificationDate = ""
|
verificationDate = GuessDateFromAssetID(verificationAssetId.data[1].instanceId)
|
||||||
for i, data in next, verificationAssetId.data do
|
|
||||||
verificationDate = verificationDate .. GuessDateFromAssetID(data.instanceId, data.id)
|
|
||||||
if i ~= #verificationAssetId.data then
|
|
||||||
verificationDate = verificationDate .. "\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local badgeRequest = API:GetBadgesAwardedDates(id,Badges)
|
local _, badgeRequest = StrafesNET.GetBadgesAwardedDates(id, Badges)
|
||||||
local badgeData = badgeRequest.data
|
local badgeData = badgeRequest.data
|
||||||
|
|
||||||
-- local badgesDates = {}
|
-- local badgesDates = {}
|
||||||
|
|
||||||
local firstBadge,firstBadgeDate = 0,math.huge
|
local firstBadge, firstBadgeDate = 0, math.huge
|
||||||
for _,badge in next,badgeData do
|
for _, badge in next, badgeData do
|
||||||
local badgeId = badge.badgeId
|
local badgeId = badge.badgeId
|
||||||
local awardedDate = tonumber(Date.fromISO(badge.awardedDate):toSeconds())
|
local awardedDate = tonumber(Date.fromISO(badge.awardedDate):toSeconds())
|
||||||
if firstBadgeDate>awardedDate then
|
if firstBadgeDate > awardedDate then
|
||||||
firstBadge=badgeId
|
firstBadge = badgeId
|
||||||
firstBadgeDate=awardedDate
|
firstBadgeDate = awardedDate
|
||||||
end
|
end
|
||||||
-- badgesDates[badgeId]=awardedDate
|
-- badgesDates[badgeId]=awardedDate
|
||||||
end
|
end
|
||||||
local userThumbnail = API:GetUserThumbnail(id).data[1]
|
local userThumbnailHeaders, userThumbnailBody = StrafesNET.GetUserThumbnail(id)
|
||||||
|
local userThumbnail = userThumbnailBody.data[1]
|
||||||
|
|
||||||
local embed = {
|
local embed = {
|
||||||
title = displayName..' (@'..name..')',
|
title = displayName .. ' (@' .. name .. ')',
|
||||||
url = 'https://roblox.com/users/'..id..'/profile',
|
url = 'https://roblox.com/users/' .. id .. '/profile',
|
||||||
thumbnail = {
|
thumbnail = {
|
||||||
url = userThumbnail.imageUrl,
|
url = userThumbnail.imageUrl,
|
||||||
},
|
},
|
||||||
fields = {
|
fields = {
|
||||||
{name='ID',value=id,inline=true},
|
{ name = 'ID', value = id, inline = true },
|
||||||
{name='Account Age',value=accountAge..' days',inline=true},
|
{ name = 'Account Age', value = accountAge .. ' days', inline = true },
|
||||||
{name='Created',value='<t:'..round(created)..':R>',inline=true},
|
{ name = 'Created', value = '<t:' .. round(created) .. ':R>', inline = true },
|
||||||
{name='Verified Email',value=verificationDate,inline=true},
|
{ name = 'Verified Email', value = verificationDate, inline = true },
|
||||||
{name='Last Online',value='<t:'..round(LastOnline)..':R>',inline=true},
|
{ name = 'Last Online', value = '<t:' .. round(LastOnline) .. ':R>', inline = true },
|
||||||
{name='Last Location',value=LastLocation,inline=true},
|
{ name = 'Last Location', value = LastLocation, inline = true },
|
||||||
{name='Banned',value=isBanned,inline=true},
|
{ name = 'Banned', value = isBanned, inline = true },
|
||||||
{name='Description',value=description,inline=false},
|
{ name = 'Description', value = description, inline = false },
|
||||||
{name='Username History ('..#usernameHistoryTable..(#usernameHistoryTable==50 and '*' or '')..')',value=usernameHistoryString,inline=false},
|
{ name = 'Username History (' .. #usernameHistoryTable .. (#usernameHistoryTable == 50 and '*' or '') .. ')', value = usernameHistoryString, inline = false },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if firstBadge and firstBadgeDate~=math.huge then
|
if firstBadge and firstBadgeDate ~= math.huge then
|
||||||
table.insert(embed.fields,{name='FQG',value=BadgesToName[firstBadge],inline=true})
|
table.insert(embed.fields, { name = 'FQG', value = BadgesToName[firstBadge], inline = true })
|
||||||
table.insert(embed.fields,{name='Joined',value='<t:'..round(firstBadgeDate)..':R>',inline=true})
|
table.insert(embed.fields, { name = 'Joined', value = '<t:' .. round(firstBadgeDate) .. ':R>', inline = true })
|
||||||
end
|
end
|
||||||
Interaction:reply({embed=embed})
|
Interaction:reply({ embed = embed })
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
Command = UserCommand,
|
Command = UserCommand,
|
||||||
Callback = Callback
|
Callback = Callback
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user