user look up
This commit is contained in:
parent
1a04105afb
commit
8a61da19fb
26
src/main.lua
26
src/main.lua
@ -266,24 +266,20 @@ client:on('messageCreate', function(message)
|
||||
local cmdName=args[1]
|
||||
table.remove(args,1)
|
||||
local command=commands.command_list[cmdName]
|
||||
if not _G.locked then
|
||||
if command~=nil then
|
||||
if message.guild~=nil then
|
||||
local s,e=pcall(function()
|
||||
command.exec({message=message,args=args,mentions=mentions,t={client,discordia,token}})
|
||||
end)
|
||||
if not s then
|
||||
message:reply('tripped : '..e:split('/')[#e:split('/')])
|
||||
end
|
||||
else
|
||||
message:reply('i will not let you type in dms!!! 😠')
|
||||
if command~=nil then
|
||||
if message.guild~=nil then
|
||||
local s,e=pcall(function()
|
||||
command.exec({message=message,args=args,mentions=mentions,t={client,discordia,token}})
|
||||
end)
|
||||
if not s then
|
||||
message:reply('tripped : '..e:split('/')[#e:split('/')])
|
||||
end
|
||||
else
|
||||
message:reply('command does not exist 👎')
|
||||
message:reply('i will not let you type in dms!!! 😠')
|
||||
end
|
||||
else --_G.current = {name=user.name,game=API.GAMES[game],style=API.STYLES[style]:lower()}
|
||||
message:reply('Bot is currently in use, please try again later ('.._G.current.name..' for '.._G.current.game..' in '.._G.current.style..')')
|
||||
end
|
||||
else
|
||||
message:reply('command does not exist 👎')
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -29,6 +29,7 @@ commands:Add('rank',{},'rank <username|mention|"me"> <game> <style>', function(t
|
||||
end
|
||||
local sn_info = API:GetUser(user.id)
|
||||
if not sn_info.ID then return message:reply('```No data with StrafesNET is associated with that user.```') end
|
||||
if sn_info.State==2 then return message:reply('```This user is currently blacklisted```') end
|
||||
local rank = API:GetRank(user.id,game,style)
|
||||
local rank_string = API:FormatRank(rank.Rank)
|
||||
local skill = API:FormatSkill(rank.Skill)
|
||||
|
@ -6,93 +6,84 @@ discordia.extensions()
|
||||
commands:Add('skill',{},'skill <username|mention|"me"> <game> <style>', function(t)
|
||||
local args=t.args
|
||||
local message=t.message
|
||||
if #args<3 then return message:reply('invalid arguments') end
|
||||
local user=args[1]
|
||||
local game=API.GAMES[args[2]]
|
||||
local style=API.STYLES[args[3]]
|
||||
if not game then return message:reply('invalid game') end
|
||||
if not style then return message:reply('invalid style') end
|
||||
print('getting user')
|
||||
if user=='me' then
|
||||
local me=message.author
|
||||
local roblox_user=API:GetRobloxInfoFromDiscordId(me.id)
|
||||
if not roblox_user.id then return message:reply('```You are not registered with the RoverAPI```') end
|
||||
user=roblox_user
|
||||
elseif user:match('<@%d+>') then
|
||||
local user_id=user:match('<@(%d+)>')
|
||||
local member=message.guild:getMember(user_id)
|
||||
local roblox_user=API:GetRobloxInfoFromDiscordId(member.id)
|
||||
if not roblox_user.id then return message:reply('```You are not registered with the RoverAPI```') end
|
||||
user=roblox_user
|
||||
else
|
||||
local roblox_user=API:GetRobloxInfoFromUsername(user)
|
||||
if not roblox_user.id then return message:reply('```User not found```') end
|
||||
user=roblox_user
|
||||
end
|
||||
local sn_info = API:GetUser(user.id)
|
||||
if not sn_info.ID then return message:reply('```No data with StrafesNET is associated with that user.```') end
|
||||
print('user:',user.id)
|
||||
_G.locked = true
|
||||
_G.current = {name=user.name,game=API.GAMES[game],style=API.STYLES[style]:lower()}
|
||||
local times = {}
|
||||
local res,rheaders = API:GetUserTimes(user.id,nil,style,game)
|
||||
if #res~=0 then
|
||||
local pages = tonumber(rheaders['Pagination-Count'])
|
||||
for _,v in next,res do
|
||||
table.insert(times,v)
|
||||
end
|
||||
if pages>1 then
|
||||
for i=2,pages do
|
||||
print('getting times page',i)
|
||||
res,rheaders = API:GetUserTimes(user.id,nil,style,game,i)
|
||||
for _,v in next,res do
|
||||
table.insert(times,v)
|
||||
if not _G.locked then
|
||||
if #args<3 then return message:reply('invalid arguments') end
|
||||
local user=args[1]
|
||||
local game=API.GAMES[args[2]]
|
||||
local style=API.STYLES[args[3]]
|
||||
if not game then return message:reply('invalid game') end
|
||||
if not style then return message:reply('invalid style') end
|
||||
print('getting user')
|
||||
local user = API:GetUserFromAny(user,message)
|
||||
if type(user)=='string' then return message:reply('```'..user..'```') end
|
||||
local sn_info = API:GetUser(user.id)
|
||||
if not sn_info.ID then return message:reply('```No data with StrafesNET is associated with that user.```') end
|
||||
print(user.name,user.id,API.GAMES[game],API.STYLES[style]:lower())
|
||||
_G.locked = true
|
||||
_G.current = {name=user.name,game=API.GAMES[game],style=API.STYLES[style]:lower()}
|
||||
local times = {}
|
||||
local res,rheaders = API:GetUserTimes(user.id,nil,style,game)
|
||||
if #res~=0 then
|
||||
local pages = tonumber(rheaders['Pagination-Count'])
|
||||
for _,v in next,res do
|
||||
table.insert(times,v)
|
||||
end
|
||||
if pages>1 then
|
||||
for i=2,pages do
|
||||
print('getting times page',i)
|
||||
res,rheaders = API:GetUserTimes(user.id,nil,style,game,i)
|
||||
for _,v in next,res do
|
||||
table.insert(times,v)
|
||||
end
|
||||
end
|
||||
end
|
||||
print('times:',#times)
|
||||
t.message:reply('ETA: '..(math.floor(#times*3/100))..' minutes '..((#times*3)%60)..' seconds (found '..#times..' times out of '..API.MAPS[game].count..' maps)')
|
||||
local test_a,test_b = 0,0
|
||||
for _,time in next,times do
|
||||
local rank = API:GetTimeRank(time.ID).Rank
|
||||
local count = tonumber(API:GetMapCompletionCount(time.Map,style))
|
||||
time.Points = API:CalculatePoint(rank,count)
|
||||
time.Rank = rank
|
||||
time.MapCompletionCount = count
|
||||
time.Skill = API:FormatSkill((count-rank)/(count-1))
|
||||
time.SkillRaw = (count-rank)/(count-1)
|
||||
test_a=test_a+(count-rank)
|
||||
test_b=test_b+(count-1)
|
||||
end
|
||||
table.sort(times,function(t1,t2)
|
||||
return t1.SkillRaw<t2.SkillRaw
|
||||
end)
|
||||
local points = 0
|
||||
for _,time in next,times do
|
||||
points = points+time.Points
|
||||
end
|
||||
local msg = 'Average Skill: '..API:FormatSkill((test_a+1)/(test_b-1))..'\n'..
|
||||
'Points: '..points..'\n'
|
||||
|
||||
for _,time in next,times do
|
||||
-- msg = msg..'['..time.Rank..'/'..time.MapCompletionCount..'] '..time.Map..' ('..time.Skill..')\n'
|
||||
msg = msg..API.MAPS[game][time.Map].DisplayName..' ('..time.Map..'): '..time.Skill..' for '..time.Rank..'/'..time.MapCompletionCount..' with '..API:FormatTime(time.Time)..'\n'
|
||||
end
|
||||
local txt = './skill-'..API.GAMES[game]..'-'..API.STYLES[style]:lower()..'-'..user.name..'.txt'
|
||||
local file=io.open(txt,'w+')
|
||||
file:write(msg)
|
||||
file:close()
|
||||
message:reply({
|
||||
file=txt,
|
||||
reference={
|
||||
message=message,
|
||||
mention=true
|
||||
}
|
||||
})
|
||||
os.remove(txt)
|
||||
_G.locked = false
|
||||
else
|
||||
message:reply('```No times found for that user.```')
|
||||
_G.locked = false
|
||||
end
|
||||
print('times:',#times)
|
||||
t.message:reply('ETA: '..(math.floor(#times*3/100))..' minutes '..((#times*3)%60)..' seconds (found '..#times..' times out of '..API.MAPS[game].count..' maps)')
|
||||
local test_a,test_b = 0,0
|
||||
for _,time in next,times do
|
||||
local rank = API:GetTimeRank(time.ID).Rank
|
||||
local count = tonumber(API:GetMapCompletionCount(time.Map,style))
|
||||
time.Points = API:CalculatePoint(rank,count)
|
||||
time.Rank = rank
|
||||
time.MapCompletionCount = count
|
||||
time.Skill = API:FormatSkill((count-rank)/(count-1))
|
||||
time.SkillRaw = (count-rank)/(count-1)
|
||||
test_a=test_a+(count-rank)
|
||||
test_b=test_b+(count-1)
|
||||
end
|
||||
table.sort(times,function(t1,t2)
|
||||
return t1.SkillRaw<t2.SkillRaw
|
||||
end)
|
||||
local points = 0
|
||||
for _,time in next,times do
|
||||
points = points+time.Points
|
||||
end
|
||||
local msg = 'Average Skill: '..API:FormatSkill((test_a+1)/(test_b-1))..'\n'..
|
||||
'Points: '..points..'\n'
|
||||
|
||||
for _,time in next,times do
|
||||
-- msg = msg..'['..time.Rank..'/'..time.MapCompletionCount..'] '..time.Map..' ('..time.Skill..')\n'
|
||||
msg = msg..API.MAPS[game][time.Map].DisplayName..' ('..time.Map..'): '..time.Skill..' for '..time.Rank..'/'..time.MapCompletionCount..' with '..API:FormatTime(time.Time)..'\n'
|
||||
end
|
||||
local txt = './skill-'..API.GAMES[game]..'-'..API.STYLES[style]:lower()..'-'..user.name..'.txt'
|
||||
local file=io.open(txt,'w+')
|
||||
file:write(msg)
|
||||
file:close()
|
||||
message:reply({
|
||||
file=txt,
|
||||
reference={
|
||||
message=message,
|
||||
mention=true
|
||||
}
|
||||
})
|
||||
os.remove(txt)
|
||||
_G.locked = false
|
||||
else
|
||||
message:reply('```No times found for that user.```')
|
||||
_G.locked = false
|
||||
--_G.current = {name=user.name,game=API.GAMES[game],style=API.STYLES[style]:lower()}
|
||||
message:reply('Bot is currently in use, please try again later ('.._G.current.name..' for '.._G.current.game..' in '.._G.current.style..')')
|
||||
end
|
||||
end)
|
74
src/modules/commands/user.lua
Normal file
74
src/modules/commands/user.lua
Normal file
@ -0,0 +1,74 @@
|
||||
local discordia=require('discordia')
|
||||
local date = discordia.Date
|
||||
local API=require('./../strafes_net.lua')
|
||||
local commands=require('./../commands.lua')
|
||||
--[[
|
||||
{
|
||||
"description": "string",
|
||||
"created": "2022-08-22T02:55:01.607Z",
|
||||
"isBanned": true,
|
||||
"externalAppDisplayName": "string",
|
||||
"hasVerifiedBadge": true,
|
||||
"id": 0,
|
||||
"name": "string",
|
||||
"displayName": "string"
|
||||
}]]
|
||||
--[[
|
||||
{"GameId":null,
|
||||
"IsOnline":false,
|
||||
"LastLocation":"Offline",
|
||||
"LastOnline":"2022-08-21T22:32:23.4-05:00",
|
||||
"LocationType":2,
|
||||
"PlaceId":null,
|
||||
"VisitorId":1455906620,
|
||||
"PresenceType":0,
|
||||
"UniverseId":null,
|
||||
"Visibility":0}
|
||||
]]
|
||||
local function round(x,n)
|
||||
return string.format('%.'..(n or 0)..'f',x)
|
||||
end
|
||||
discordia.extensions()
|
||||
commands:Add('user',{},'user <username|mention|"me">', function(t)
|
||||
local args=t.args
|
||||
local message=t.message
|
||||
local user=args[1]
|
||||
local user_info=API:GetUserFromAny(user,message)
|
||||
if type(user_info)=='string' then return message:reply('```'..user_info..'```') end
|
||||
-- for a,b in next,user_info do user_info[a]=tostring(b)end
|
||||
local description = user_info.description
|
||||
local created = tostring(date.fromISO(user_info.created):toSeconds())
|
||||
local current = date():toSeconds()
|
||||
local accountAge = round((current-created)/86400)
|
||||
local isBanned = user_info.isBanned
|
||||
local id = user_info.id
|
||||
local name = user_info.name
|
||||
local displayName = user_info.displayName
|
||||
|
||||
local onlineStatus_info = API:GetUserOnlineStatus(user_info.id)
|
||||
|
||||
-- for a,b in next,onlineStatus_info do onlineStatus_info[a]=tostring(b)end
|
||||
local LastLocation = onlineStatus_info.LastLocation
|
||||
local LastOnline = date.fromISO(onlineStatus_info.LastOnline):toSeconds()
|
||||
|
||||
local userThumbnail = API:GetUserThumbnail(user_info.id).data[1]
|
||||
|
||||
local embed = {
|
||||
title = displayName..' (@'..name..')',
|
||||
url = 'https://roblox.com/users/'..id..'/profile',
|
||||
thumbnail = {
|
||||
url = userThumbnail.imageUrl,
|
||||
},
|
||||
fields = {
|
||||
{name='ID',value=id,inline=true},
|
||||
{name='Account Age',value=accountAge..' days',inline=true},
|
||||
{name='Created',value='<t:'..round(created)..':R>',inline=true},
|
||||
{name='Last Online',value='<t:'..round(LastOnline)..':R>',inline=true},
|
||||
{name='Last Location',value=LastLocation,inline=true},
|
||||
{name='Banned',value=isBanned,inline=true},
|
||||
|
||||
{name='Description',value=description or 'None',inline=false},
|
||||
}
|
||||
}
|
||||
message:reply({embed=embed})
|
||||
end)
|
@ -1,13 +1,21 @@
|
||||
local http = require('coro-http')
|
||||
local json = require('json')
|
||||
function wait(n)c=os.clock t=c()while c()-t<=n do end;end
|
||||
local request=function(method,url,headers,params)
|
||||
local headers,body=http.request(method,url,headers or {{"Content-Type", "application/json"}},params)
|
||||
body=json.decode(body)
|
||||
--[[
|
||||
1: method
|
||||
2: url
|
||||
3: headers
|
||||
4: body
|
||||
5: options]]
|
||||
local function request(method,url,headers,body,options)
|
||||
local headers,body=http.request(method,url,headers,body,options)
|
||||
local rbody=json.decode(body)
|
||||
local rheaders={}
|
||||
for _,t in pairs(headers) do
|
||||
if type(t)=='table' then
|
||||
rheaders[t[1]]=t[2]
|
||||
else
|
||||
rheaders[_]=t
|
||||
end
|
||||
end
|
||||
local remaining = tonumber(rheaders['RateLimit-Remaining'])
|
||||
@ -16,7 +24,7 @@ local request=function(method,url,headers,params)
|
||||
local t = remaining==0 and reset or .38
|
||||
wait(t)
|
||||
end
|
||||
return body,rheaders
|
||||
return rbody,rheaders
|
||||
end
|
||||
|
||||
-- local urlparamencode=function()
|
||||
|
@ -6,6 +6,8 @@ local STRAFESNET_API_URL = 'https://api.strafes.net/v1/'
|
||||
local ROVER_API_URL = 'https://verify.eryn.io/api/'
|
||||
local ROBLOX_API_URL = 'https://users.roblox.com/v1/'
|
||||
local ROBLOX_API_URL2 = 'https://api.roblox.com/'
|
||||
local ROBLOX_THUMBNAIL_URL = 'https://thumbnails.roblox.com/v1/'
|
||||
local ROBLOX_PREMIUM_URL = 'https://premiumfeatures.roblox.com/v1/'
|
||||
|
||||
local RANK_CONSTANT = 0.5
|
||||
|
||||
@ -40,9 +42,38 @@ API.STYLES=STYLES
|
||||
API.STYLES_LIST=STYLES_LIST
|
||||
API.STATES=STATES
|
||||
|
||||
API.ROBLOX_LOCATION_TYPES={
|
||||
[0]='Mobile Website',
|
||||
[1]='Mobile In-Game',
|
||||
[2]='Website',
|
||||
[3]='Roblox Studio',
|
||||
[4]='In-Game',
|
||||
[5]='XboxApp',
|
||||
[6]='TeamCreate'
|
||||
}
|
||||
|
||||
API.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'
|
||||
}
|
||||
API.ROBLOX_THUMBNAIL_TYPES = {
|
||||
AVATAR='avatar',
|
||||
BUST='avatar-bust',
|
||||
HEADSHOT='avatar-headshot'
|
||||
}
|
||||
|
||||
-- insyri make this BTW
|
||||
-- use as local err, res = parseToURLArgs(), thanks golang for this idea
|
||||
function parseToURLArgs(tb) function Err(err) return err, nil end function Ok(res) return nil, res end if not tb then return Err('got nothing') end if type(tb) ~= 'table' then return Err('expected table, got '..type(tb)) end local str = '?' local index = 1 for key, value in pairs(tb) do if index == 1 then str = str..key..'='..t(value) else str = str..'&'..key..'='..t(value) end index = index + 1 end return Ok(str) end
|
||||
function parseToURLArgs(tb) local function Err(err) return err, nil end local function Ok(res) return nil, res end if not tb then return Err('got nothing') end if type(tb) ~= 'table' then return Err('expected table, got '..type(tb)) end local str = '?' local index = 1 for key, value in pairs(tb) do if index == 1 then str = str..key..'='..t(value) else str = str..'&'..key..'='..t(value) end index = index + 1 end return Ok(str) end
|
||||
-- fiveman made these (converted to lua from python)
|
||||
function format_helper(a,b)a=tostring(a)while#a<b do a='0'..a end;return a end
|
||||
function formatTime(a)if a>86400000 then return'>1 day'end;local c=format_helper(a%1000,3)local d=format_helper(math.floor(a/1000)%60,2)local e=format_helper(math.floor(a/(1000*60))%60,2)local f=format_helper(math.floor(a/(1000*60*60))%24,2)if f=='00'then return e..':'..d..'.'..c else return f..':'..e..':'..d end end
|
||||
@ -162,6 +193,27 @@ function API:CalculatePoint(rank,count)
|
||||
return RANK_CONSTANT*(math.exp(RANK_CONSTANT)-1)/(1-math.exp(math.max(-700, -RANK_CONSTANT*count)))*math.exp(math.max(-700, -RANK_CONSTANT*rank))+(1-RANK_CONSTANT)*(1+2*(count-rank))/(count*count)
|
||||
end
|
||||
|
||||
function API:GetUserFromAny(user,message)
|
||||
if user=='me' then
|
||||
local me=message.author
|
||||
local roblox_user=API:GetRobloxInfoFromDiscordId(me.id)
|
||||
if not roblox_user.id then return 'You are not registered with the RoverAPI' 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=API:GetRobloxInfoFromDiscordId(member.id)
|
||||
if not roblox_user.id then return 'User is not registered with the RoverAPI' end
|
||||
return roblox_user
|
||||
else
|
||||
local roblox_user=API:GetRobloxInfoFromUsername(user)
|
||||
if not roblox_user.id then return 'User not found' end
|
||||
return roblox_user
|
||||
end
|
||||
return 'Something went wrong (this should generally not happen)'
|
||||
end
|
||||
|
||||
|
||||
-- [[ ROBLOX / ROVER AND OTHER APIs ]] --
|
||||
|
||||
function API:GetRobloxInfoFromUserId(USER_ID)
|
||||
@ -188,4 +240,46 @@ function API:GetRobloxInfoFromDiscordId(DISCORD_ID)
|
||||
return response2
|
||||
end
|
||||
|
||||
function API:GetUserOnlineStatus(USER_ID) -- https://api.roblox.com/users/1455906620/onlinestatus
|
||||
if not USER_ID then return 'empty id' end
|
||||
local response,headers = http_request('GET', ROBLOX_API_URL2..'users/'..USER_ID..'/onlinestatus', API_HEADER)
|
||||
return response,headers
|
||||
end
|
||||
|
||||
function API:GetUserThumbnail(USER_ID,TYPE,SIZE) -- https://thumbnails.roblox.com/v1/users/avatar?userIds=1455906620&size=180x180&format=Png&isCircular=false
|
||||
if not USER_ID then return 'empty id' end
|
||||
local _TYPE = self.ROBLOX_THUMBNAIL_TYPES[TYPE] or 'avatar'
|
||||
local _SIZE = self.ROBLOX_THUMBNAIL_SIZES[SIZE] or '180x180'
|
||||
local err, res = parseToURLArgs({userIds=USER_ID,size=_SIZE,format='Png',isCircular=false})
|
||||
if err then return err end
|
||||
local response,headers = http_request('GET', ROBLOX_THUMBNAIL_URL..'users/'.._TYPE..res, API_HEADER)
|
||||
return response,headers
|
||||
end
|
||||
|
||||
function API:GetUserPremiumState(USER_ID,X_CSRF_TOKEN) -- https://premiumfeatures.roblox.com/v1/users/1455906620/validate-membership
|
||||
if not USER_ID then return 'empty id' end
|
||||
local response,headers = http_request('GET', ROBLOX_PREMIUM_URL..'users/'..USER_ID..'/validate-membership', API_HEADER,nil,{ROBLOX_COOKIE})
|
||||
return response,headers
|
||||
end
|
||||
|
||||
--[[
|
||||
1: method
|
||||
2: url
|
||||
3: headers
|
||||
4: body
|
||||
5: options
|
||||
|
||||
1 "POST",
|
||||
2 "https://groups.roblox.com/v1/user/groups/primary",
|
||||
3 {
|
||||
{"Content-Type", "text/json"},
|
||||
{"X-CSRF-TOKEN", X_CSRF_TOKEN},
|
||||
{"Cookie", ".ROBLOSECURITY=YOUR_COOKIE_GOES_HERE_AFTER_THE_EQUAL_SIGN"}
|
||||
},
|
||||
4 "{\"groupId\": GROUP_ID_NUMBER}",
|
||||
5 {"ALSO_PUT_YOUR_COOKIE_HERE"}
|
||||
|
||||
|
||||
|
||||
]]
|
||||
return API
|
BIN
ytdl.exe.old
Normal file
BIN
ytdl.exe.old
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user