Delete old and unused garbage

This commit is contained in:
tommy 2024-07-10 15:49:51 -04:00
parent 8298c9b573
commit a9a5e1b556
13 changed files with 38 additions and 883 deletions

View File

@ -1,80 +1,45 @@
local discordia = require('discordia')
local dcmd = require('discordia-slash')
local token = require('./modules/token.lua')
local commands=require('./modules/commands.lua')
local prefix = ','
local client = discordia.Client()
client:useSlashCommands()
_G.dcmd=dcmd
_G.client = client
_G.locked = false
local Discordia = require('discordia')
local DiscordiaSlash = require('discordia-slash')
local Token = require('./Modules/Token.lua')
local CommandCollector = require('./Modules/CommandCollector.lua')
local Client = Discordia.Client():useApplicationCommands()
Discordia.extensions()
discordia.extensions()
local MessageCommandCollector = CommandCollector.new('Message'):Collect()
local SlashCommandCollector = CommandCollector.new('Slash'):Collect()
local UserCommandCollector = CommandCollector.new('User'):Collect()
client:on('ready',function()
commands:INIT()
local f=io.open('restart.txt','r+'):read()
local t=tostring(f):split(',')
if #t==3 then
client:getGuild(t[1]):getChannel(t[2]):send(
{
content='bot ready',
reference={
message=client:getChannel(t[2]):getMessage(t[3]),
mention=true
}
}
)
io.open('restart.txt','w+'):write(''):close()
else
print('restart.txt is empty or something so probably a first start')
end
Client:on('ready', function()
-- local GlobalCommands = Client:getGlobalApplicationCommands()
-- for CommandId in pairs(GlobalCommands) do
-- Client:deleteGlobalApplicationCommand(CommandId)
-- end
MessageCommandCollector:Publish(Client)
SlashCommandCollector:Publish(Client)
UserCommandCollector:Publish(Client)
end)
function parseMentions(message)
local content=message.content
local usersMentioned={}
if #message.mentionedUsers>0 then
for user in message.mentionedUsers:iter() do
usersMentioned[user.id]=user
end
end
local msgSplit=content:split(' ')
for i,v in next, msgSplit do
if v:match('<@![0-9]+>') then
local id=v:match('<@!([0-9]+)>')
if usersMentioned[id] then
msgSplit[i]=usersMentioned[id].mentionString
end
end
end
return table.concat(msgSplit,' ') or '',usersMentioned
end
client:on('messageCreate', function(message)
if message.author.bot then return end
local content,mentions=parseMentions(message)
if content:sub(1,#prefix)==prefix and content~=prefix then
local cmd=content:sub(#prefix+1,#content)
local args=cmd:split(' ')
local cmdName=args[1]
table.remove(args,1)
local command=commands.command_list[cmdName]
if command~=nil then
if message.guild~=nil then
local tb
local s,e=xpcall(function()
command.exec({message=message,args=args,mentions=mentions,t={client,discordia,token}})
end,function(err)
tb = debug.traceback()
return err
end)
if not s then
message:reply('tripped : '..e:split('/')[#e:split('/')])
print(e,tb)
end
end
end
Client:on('slashCommand', function(Interaction, Command, Args)
local SlashCommand = SlashCommandCollector:Get(Command.name)
if SlashCommand then
SlashCommand.Callback(Interaction, Command, Args)
end
end)
client:run('Bot '..token)
Client:on('messageCommand', function(Interaction, Command, Message)
local MessageCommand = MessageCommandCollector:Get(Command.name)
if MessageCommand then
MessageCommand.Callback(Interaction, Command, Message)
end
end)
Client:on('userCommand', function(Interaction, Command, Member)
local UserCommand = UserCommandCollector:Get(Command.name)
if UserCommand then
UserCommand.Callback(Interaction, Command, Member)
end
end)
Client:run('Bot '..Token)

View File

@ -1,34 +0,0 @@
local discordia=require('discordia')
discordia.extensions()
local commands={command_list={}}
setmetatable(commands.command_list,{__index=function(self,index)
for i,v in pairs(self) do
for i2,v2 in pairs(v.alias) do
if v2==index then
return self[i]
end
end
end
return nil
end})
function commands:Add(name,alias,desc,exec)
name=type(name)=='string' and name or ('Command'..#self.command_list)
self.command_list[name]={
name=name,
alias=type(alias)=='table'and alias or {'None'},
desc=type(desc)=='string'and desc or ('No description provided'),
exec=type(exec)=='function'and exec or function(message)
return message:reply('No command assigned')
end
}
return self.command_list[name]
end
function commands:Get(name)
return self.command_list[name]
end
function commands:INIT()
for file in io.popen([[dir "./src/modules/commands" /b]]):lines() do require('./commands/'..file) end
print('commands done')
end
return commands

View File

@ -1,14 +0,0 @@
local discordia=require('discordia')
local commands=require('./../commands.lua')
discordia.extensions()
commands:Add('cmds',{'commands','cmd','help'},'Returns a list of all commands',function(t)
local final='```\n'
for i,v in pairs(commands.command_list) do
local name=v.name
local alias=table.concat(v.alias,', ') or 'None'
local desc=v.desc
final=final..'Name: '..name..'\nDescription: '..desc..'\n'..'Aliases: '..alias..'\n\n'
end
final=final..'```'
t.message:reply(final)
end)

View File

@ -1,78 +0,0 @@
local discordia=require('discordia')
local commands=require('./../commands.lua')
discordia.extensions()
function split(s,d)
local t,c,i={},'',0
for k in s:gmatch('.') do
i=i+1
if k==d and string.sub(s,i+1)~='' then
t[#t+1]=c
c=''
goto continue
end
c=c..k
::continue::
end
t[#t+1]=c
return t
end
function clearTmp()
for file in io.popen([[dir "./tmp" /b]]):lines() do
if file then
os.remove('./tmp/'..file)
end
end
end
function isTmpEmpty()
local dir = io.popen([[dir "./tmp" /b]]):read()
return dir==nil, dir, dir~=nil and split(dir,'\n') or {}
end
commands:Add('sc',{},'download soundcloud song (usage: "sc [link]")', function(t)
local args = t.args
local message = t.message
if args[1] then
if args[1]:match('https://soundcloud.com/[%w-_]+/[%w-_]+') then
clearTmp()
local link=args[1]:match('https://soundcloud.com/[%w-_]+/[%w-_]+')
message:reply('Attempting to download song from <'..link..'>')
local filepath = ''
local s=io.popen('ytdl.exe -o "./tmp/%(uploader_id)s-%(display_id)s.%(ext)s" '..link)
local songName
repeat
local str = s:read()
if str then
local tag = str:match('^%[(.+)%]')
if tag=='soundcloud' then
local song = str:match('^%[soundcloud%] (.+):')
if song:match('%d+')~=song then
songName = song:match('.+/(.+)')
end
end
end
until s:read()==nil
s:close()
if type(songName)=='string' and songName~='' then
message:reply('found song: '..songName)
local empty,file = isTmpEmpty()
if not empty then
message:reply({file='./tmp/'..file})
os.remove('./tmp/'..file)
end
end
else
message:reply('Invalid URL')
end
else
message:reply('No URL provided')
end
end)
-- commands:Add('ct',{},'',function()
-- clearTmp()
-- end)
-- commands:Add('ft',{},'',function()
-- filterTmp()
-- end)

View File

@ -1,28 +0,0 @@
local discordia=require('discordia')
local API=require('./../strafes_net.lua')
local commands=require('./../commands.lua')
discordia.extensions()
commands:Add('map',{},'get map info', function(t)
local args = t.args
local message = t.message
local game = API.GAMES[args[1]]
local map
if not game then
local str = table.concat(args,' ')
map = API.MAPS[1][str] or API.MAPS[2][str]
else
map = API.MAPS[game][table.concat(args,' ',2)]
end
if not map then return message:reply('```No map found```') end
local formatted_message = '```'..
'Map: '..map.DisplayName..' ('..API.GAMES[map.Game]..')\n'..
'ID: '..map.ID..'\n'..
'Creator: '..map.Creator..'\n'..
'PlayCount: '..map.PlayCount..'\n'..
'Published: '..os.date('%A, %B %d %Y @ %I:%M (%p)',map.Date)..
'```'
return message:reply(formatted_message)
end)

View File

@ -1,71 +0,0 @@
-- local discordia=require('discordia')
-- local API=require('./../strafes_net.lua')
-- discordia.extensions()
-- API.MAPS={}
-- local function insert(t, value)
-- local start, ending, mid, state = 1, #t, 1, 0
-- while start <= ending do
-- mid = math.floor((start + ending) / 2)
-- if #value.DisplayName < #t[mid].DisplayName then
-- ending, state = mid - 1, 0
-- else
-- start, state = mid + 1, 1
-- end
-- end
-- table.insert(t, mid + state, value)
-- end
-- for _, game in next, API.GAMES do
-- if type(tonumber(game)) == 'number' then
-- local count = 0 -- add into the maps table afterwards
-- local maps = {}
-- local res, headers = API:GetMaps(game)
-- local pages = tonumber(headers['Pagination-Count'])
-- count = count + #res
-- for _, v in next, res do
-- insert(maps, v)
-- end
-- if pages > 1 then
-- for i = 2, pages do
-- res, headers = API:GetMaps(game, i)
-- count = count + #res
-- for _, j in next, res do
-- insert(maps, j)
-- end
-- end
-- end
-- setmetatable(maps, {__index = function(self, k)
-- if k=='count' then return self.count end
-- -- Just to make sure it goes in the right order
-- if type(k)=='string' then
-- for i = 1, self.count do
-- local v = self[i]
-- if type(v) == 'table' and v.DisplayName:lower():find(tostring(k:gsub('%%', '%%%%'):gsub('^%^', '%%^'):gsub('%$$', '%%$'):gsub('%(', '%%('):gsub('%)', '%%)'):gsub('%.', '%%.'):gsub('%[', '%%['):gsub('%]', '%%]'):gsub('%*', '%%*'):gsub('%+', '%%+'):gsub('%-', '%%-'):gsub('%?', '%%?')):lower()) then
-- return v
-- end
-- end
-- elseif type(k)=='number' then
-- for i = 1, self.count do
-- local v = self[i]
-- if type(v) == 'table' and v.ID==k then
-- return v
-- end
-- end
-- end
-- end})
-- maps.count = count
-- API.MAPS[game] = maps
-- print('map init done for game:', API.GAMES[game], 'count:', API.MAPS[game].count)
-- end
-- end

View File

@ -1,114 +0,0 @@
local discordia=require('discordia')
local json=require('json')
local http_request=require('./../http.lua')
local Commands=require('./../commands.lua')
discordia.extensions()
local COLOURS={
GREEN=0x00ff00,
RED=0xff0000
}
--initialize minecraft ip data
local MinecraftDataFile=io.open('minecraft_data.json','r')
if not MinecraftDataFile or (MinecraftDataFile and MinecraftDataFile:read('*a')=='') then
print('no such file exists! so make it')
io.open('minecraft_data.json','w+'):write(json.encode({})):close()
end
if MinecraftDataFile then
MinecraftDataFile:close()
end
Commands:Add('setip',{},'set ip for status',function(CommandData)
local CommandArgs=CommandData.args
local CommandMessage=CommandData.message
local ServerIPStr=CommandArgs[1]
if not ServerIPStr then
return CommandMessage:reply('No IP provided')
end
local ServerIP=ServerIPStr:match("(%d+%.%d+%.%d+%.%d+)") or ServerIPStr:match("(%w*%.?%w+%.%w+)")
if not ServerIP then
return CommandMessage:reply('Invalid server IP')
end
local ServerPort=ServerIPStr:match(ServerIP..':(%d+)') or 25565
local GuildId=CommandMessage.guild.id
if not GuildId then
return CommandMessage:reply('You cannot use this command outside of a Discord server')
end
local GuildMinecraftData={IP=ServerIP,PORT=ServerPort}
local GlobalMinecraftData=json.decode(io.open('minecraft_data.json','r'):read('*a'))
GlobalMinecraftData[GuildId]=GuildMinecraftData
io.open('minecraft_data.json','w+'):write(json.encode(GlobalMinecraftData)):close()
return CommandMessage:reply({
content='Successfully added `'..ServerIP..':'..ServerPort..'` for ServerId='..GuildId,
reference={
message=CommandMessage,
mention=true
}
})
end)
Commands:Add('status',{},'get status for minecraft server',function(CommandData)
local CommandMessage=CommandData.message
local GuildId=CommandMessage.guild.id
if not GuildId then
return CommandMessage:reply('You cannot use this command outside of a Discord server')
end
local GlobalMinecraftData=json.decode(io.open('minecraft_data.json','r'):read('*a'))
if not GlobalMinecraftData then
return CommandMessage:reply('Could not read server data')
end
local ServerMinecraftData=GlobalMinecraftData[GuildId]
if not ServerMinecraftData then
return CommandMessage:reply('There is no data for this Discord server')
end
local ServerIPStr=ServerMinecraftData.IP..':'..ServerMinecraftData.PORT
local Response,Headers=http_request('GET',('https://api.mcsrvstat.us/3/%s'):format(ServerIPStr))
local IsOnline=Response.online
local EmbedData
if IsOnline then
local MaxPlayers=Response.players.max
local OnlinePlayers=Response.players.online
local AnonymousPlayers=OnlinePlayers
local Players={}
if OnlinePlayers>0 then
for PlayerIndex,PlayerData in next,Response.players.list do
table.insert(Players,PlayerData.name)
AnonymousPlayers=AnonymousPlayers-1
end
else
table.insert(Players,'No players online')
end
if AnonymousPlayers>0 then
for AnonymousPlayerIndex=1,AnonymousPlayers do
table.insert(Players,'Anonymous Player')
end
end
EmbedData={
title='Server Status for '..ServerIPStr,
description=Response.motd.clean[1]..' ('..Response.version..')',
fields={
{name='Players',value=OnlinePlayers..'/'..MaxPlayers,inline=true},
{name='List of players',value=table.concat(Players,'\n'),inline=true}
},
color=COLOURS.GREEN
}
else
EmbedData={
title='Server Status for '..ServerIPStr,
description='Server is offline',
color=COLOURS.RED
}
end
return CommandMessage:reply({embed=EmbedData})
end)

View File

@ -1,60 +0,0 @@
local discordia=require('discordia')
local API=require('./../strafes_net.lua')
local commands=require('./../commands.lua')
local pad = API.Pad
discordia.extensions()
-- args: user, game, style, map
commands:Add('pb', {}, 'get placement on map', function(t)
local args = t.args
local message = t.message
if #args < 4 then return message:reply('invalid arguments') end
local user = API:GetUserFromAny(args[1],message)
local sn_info = API:GetUser(user.id)
local game = API.GAMES[args[2]]
local style = API.STYLES[args[3]]
local map = API.MAPS[game][table.concat(args,' ',4)]
-- i love checks
if not game then return message:reply('invalid game') end
if not style then return message:reply('invalid style') end
if not map then return message:reply('invalid map') end
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 time = API:GetUserTimes(user.id, map.ID, style, game)[1]
if not time then return message:reply('```No time was found.```') end
local rank = API:GetTimeRank(time.ID).Rank
local count = tonumber(API:GetMapCompletionCount(time.Map, style))
if not rank or not count then
rank = 1
count = 1
end
local time_formatted = API.FormatTime(time.Time)
local date = os.date("%x", time.Date)
local placement = rank .. '/' .. count
local points = API.CalculatePoint(rank, count)
local t_n, d_n, p_n= #time_formatted, 8, math.max(#placement, 10)
local first_line = 'PB Time for map: '..map.DisplayName..' ('..API.GAMES[game]..', '..API.STYLES_LIST[style]..')'
local second_line = pad('Time:', t_n + 1) .. '| '
.. pad('Date:', d_n + 1) .. '| '
.. pad('Placement:', p_n + 1) .. '| '
.. 'Points:'
local third_line = pad(time_formatted, t_n + 1) .. '| '
.. pad(date, d_n + 1) .. '| '
.. pad(placement, p_n + 1) .. '| '
.. tostring(points)
return message:reply('```' .. first_line .. '\n' .. second_line .. '\n' .. third_line .. '```')
end)

View File

@ -1,40 +0,0 @@
local discordia=require('discordia')
local API=require('./../strafes_net.lua')
local commands=require('./../commands.lua')
function dump(a,b,c,d)b=b or 50;d=d or("DUMP START "..tostring(a))c=c or 0;for e,f in next,a do local g;if type(f)=="string"then g="\""..f.."\""else g=tostring(f)end;d=d.."\nD "..string.rep(" ",c*2)..tostring(e)..": "..g;if type(f)=="table"then if c>=b then d=d.." [ ... ]"else d=dump(f,b,c+1,d)end end end;return d end
discordia.extensions()
commands:Add('rank',{},'rank <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
user = API:GetUserFromAny(user,message)
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)
local formatted_message = '```'..
'Name: '..user.displayName..' ('..user.name..')\n'..
'Style: '..API.STYLES_LIST[rank.Style]..'\n'..
'Rank: '..rank_string..'\n'..
'Skill: '..skill..'\n'..
'Placement: '..rank.Placement..'\n'..
'State: '..API.STATES[sn_info.State]..'\n'..
'```'
message:reply(formatted_message)
end)

View File

@ -1,22 +0,0 @@
local discordia=require('discordia')
local commands=require('./../commands.lua')
discordia.extensions()
function wait(n)local c=os.clock local t=c()while c()-t < n do end;end
commands:Add('restart',{},"restart bot [dev]", function(t)
if t.message.author==t.t[1].owner then
t.message:addReaction('👍')
t.t[1]:stop()
wait(1.5)
io.open('restart.txt','w+'):write(t.message.guild.id..','..t.message.channel.id..','..t.message.id):close()
os.execute('.\\exes\\luvit ./src/main.lua')
end
end)
commands:Add('leave',{},'leave',function(t)
if t.message.author==t.t[1].owner then
t.message:delete()
local left = t.message.guild:leave()
if left then
print('left')
end
end
end)

View File

@ -1,132 +0,0 @@
local discordia=require('discordia')
local API=require('./../strafes_net.lua')
local commands=require('./../commands.lua')
function sleep(n) local t = os.clock() while os.clock()-t <= n do end end
discordia.extensions()
local pad = API.Pad
commands:Add('skill',{},'skill <username|mention|"me"> <game> <style> <sort?=skill|point>', function(t)
local args=t.args
local message=t.message
if not _G.locked then
if #args<3 then return message:reply('usage: `skill <username|mention|"me"> <game> <style> <sort?="skill"|"point">`') 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
local sort = args[4]
if type(sort)=='string' and not sort:lower():find('skill') and not sort:lower():find('point') then
return message:reply('invalid sort option, valid options are "skill" or "point"')
elseif sort==nil then
sort = 'skill'
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
if sn_info.State==2 then return message:reply('```This user is currently blacklisted```') 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))
if not rank or not count then
print('NO RANK OR COUNT')
print(rank,count)
rank = 1
count = 1
end
time.Points = API.CalculatePoint(rank,count)
time.Rank = rank
time.MapCompletionCount = count
time.SkillRaw = rank == 1 and 1 or (count-rank)/(count-1)
time.Skill = API.FormatSkill(time.SkillRaw)
test_a=test_a+(count-rank)
test_b=test_b+(count-1)
end
table.sort(times,sort:find('skill') and function(t1,t2)
return t1.SkillRaw<t2.SkillRaw
end or sort:find('point') and function(t1,t2)
return t1.Points<t2.Points
end)
local points = 0
for _,time in next,times do
points = points+time.Points
end
local skillFinal = (test_a)/(test_b-1)
local msg = 'Average Skill: '..API.FormatSkill(math.clamp(skillFinal,0,1))..'\n'..
'Points: '..points..'\n'..
pad('Map',50)..' | '..pad('Points')..' | '..pad('Skill',7)..' | '.. pad('Placement',14)..' | Time\n\n'
for _,time in next,times do
-- msg = msg..'['..time.Rank..'/'..time.MapCompletionCount..'] '..time.Map..' ('..time.Skill..')\n'
local mapStr = API.MAPS[game][time.Map].DisplayName..' ('..time.Map..')'
local skill = time.Skill
local point = time.Points
local rankStr = time.Rank..'/'..time.MapCompletionCount
local timeStr = API.FormatTime(time.Time)
msg = msg.. pad(mapStr,50)..' | '..pad(point)..' | '..pad(skill,7)..' | '.. pad(rankStr,14)..' | '..timeStr..'\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
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
end)
commands:Add('compare',{},'compare n1 n2', function(t)
local args=t.args
local message=t.message
local n1 = args[1]
local n2 = args[2]
local compared = API.CalculateDifference(n1,n2)
local compared_percent = API.CalculateDifferencePercent(n1,n2)
message:reply(tostring(compared)..' ('..compared_percent..')')
end)
commands:Add('calc',{},nil,function(t)
local args=t.args
local message=t.message
local rank = args[1]
local count = args[2]
local points=API.CalculatePoint(rank,count)
local skill=API.FormatSkill(rank == 1 and 1 or (count-rank)/(count-1))
message:reply('```Points: '..points..'\nSkill: '..skill..'```')
end )

View File

@ -1,167 +0,0 @@
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}
]]
Badges = {
'275640532', --Bhop, pre-group
'363928432', --Surf, pre-group
'2124614454', --Bhop, post-group
'2124615096', --Surf, post-group
}
BadgesToName = {
[275640532]='old bhop',
[363928432]='old surf',
[2124614454]='new bhop',
[2124615096]='new surf',
}
local function round(x,n)
return string.format('%.'..(n or 0)..'f',x)
end
local function FromYMD(ymd)
return date.fromISO(ymd.."T00:00:00")[1]
end
local function leftpad(s,n,p)
return string.rep(p,n-#tostring(s))..s
end
local function ToYMD(seconds)
return "<t:"..seconds..":R>"
end
local IDToDate = { --Terrible ranges but it's all we have
-- {1000000000, FromYMD("2006-01-01")}, --I guess?
-- {1864564055, FromYMD("2008-08-04")},
{3800920136, FromYMD("2016-04-16")},
{9855616205, FromYMD("2017-04-02")},
{30361018662, FromYMD("2018-11-14")},
{32665806459, FromYMD("2019-01-07")},
{34758058773, FromYMD("2019-02-24")},
{65918261258, FromYMD("2020-06-05")},
{171994717435, FromYMD("2023-03-24")},
{173210319088, FromYMD("2023-04-14")},
{206368884641, FromYMD("2023-07-16")},
{229093879745, FromYMD("2024-01-02")},
{232802028144, FromYMD("2024-04-08")},
{234886704167, FromYMD("2024-06-28")}
}
--We assume linear interpolation since anything more complex I can't process
local function linterp(i1, i2, m)
return math.floor(i1 + (i2-i1)*m)
end
local function GuessDateFromAssetID(AssetID)
for i = #IDToDate, 1, -1 do --Newest to oldest
local ID,Time = unpack(IDToDate[i])
if ID < AssetID then
if not IDToDate[i+1] then
return "After "..ToYMD(Time)
end
local ParentID, ParentTime = unpack(IDToDate[i+1])
return "Around "..ToYMD(linterp(Time, ParentTime, (AssetID-ID)/(ParentID-ID)))
end
end
return "Before "..ToYMD(IDToDate[1][2])
end
discordia.extensions()
commands:Add('user',{},'user <username|mention|"me">', function(t)
local args=t.args
local message=t.message
local user=args[1] or 'me'
local user_info=API:GetUserFromAny(user,message)
if type(user_info)=='string' then return message:reply('```'..user_info..'```') end
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 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 usernameHistory = API:GetUserUsernameHistory(id).data or {}
local usernameHistoryTable = {}
for index,usernameObj in next,usernameHistory do
table.insert(usernameHistoryTable,usernameObj.name)
end
local usernameHistoryString = table.concat(usernameHistoryTable,', ')
local onlineStatus_info = API:GetUserOnlineStatus(id) or {lastLocation="Unknown", lastOnline=0, userPresenceType=-1}
-- table.foreach(onlineStatus_info,print)
local LastLocation = onlineStatus_info.lastLocation
if onlineStatus_info.userPresenceType==2 then LastLocation="Ingame" end
local LastOnline = date.fromISO(onlineStatus_info.lastOnline):toSeconds()
local verificationAssetId = API:GetVerificationItemID(id)
local verificationDate = "Not verified"
if verificationAssetId.errors then
verificationDate = "Failed to fetch"
elseif verificationAssetId.data[1] then
verificationDate = GuessDateFromAssetID(verificationAssetId.data[1].instanceId)
end
local badgeRequest = API:GetBadgesAwardedDates(id,Badges)
local badgeData = badgeRequest.data
-- local badgesDates = {}
local firstBadge,firstBadgeDate = 0,math.huge
for _,badge in next,badgeData do
local badgeId = badge.badgeId
local awardedDate = tonumber(date.fromISO(badge.awardedDate):toSeconds())
if firstBadgeDate>awardedDate then
firstBadge=badgeId
firstBadgeDate=awardedDate
end
-- badgesDates[badgeId]=awardedDate
end
local userThumbnail = API:GetUserThumbnail(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='Verified Email',value=verificationDate,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,inline=false},
{name='Username History ('..#usernameHistoryTable..(#usernameHistoryTable==50 and '*' or '')..')',value=usernameHistoryString,inline=false},
}
}
if firstBadge and firstBadgeDate~=math.huge then
table.insert(embed.fields,{name='FQG',value=BadgesToName[firstBadge],inline=true})
table.insert(embed.fields,{name='Joined',value='<t:'..round(firstBadgeDate)..':R>',inline=true})
end
message:reply({embed=embed})
end)

View File

@ -1,50 +0,0 @@
local discordia=require('discordia')
local API=require('./../strafes_net.lua')
local commands=require('./../commands.lua')
local pad = API.Pad
discordia.extensions()
-- args: game, style, map
commands:Add('wr', {}, 'get map wr', function(t)
local args = t.args
local message = t.message
if #args < 3 then return message:reply('invalid arguments') end
local game = API.GAMES[args[1]]
local style = API.STYLES[args[2]]
local map = API.MAPS[game][table.concat(args,' ',3)]
if not game then return message:reply('invalid game') end
if not style then return message:reply('invalid style') end
if not map then return message:reply('invalid map') end
local time = API:GetMapWr(map.ID,style)
if not time then return message:reply('No time was found') end
local user = API:GetRobloxInfoFromUserId(time.User)
local username = user.name
local time_formatted = API.FormatTime(time.Time)
local date = os.date("%x", time.Date)
local count = tonumber(API:GetMapCompletionCount(time.Map, style))
local points = tostring(API.CalculatePoint(1, count))
-- Username: | Time: | Points: | Date:
local n_n,t_n,p_n = 20,#time_formatted,#points
local first_line = 'WR Time for map: '..map.DisplayName..' ( 1/'..count..' ) ['..API.GAMES[game]..', '..API.STYLES_LIST[style]..']'
local second_line = pad('Username:', n_n + 1) .. '| '
.. pad('Time:', t_n + 1) .. '| '
.. pad('Points:',p_n + 1).. '| '
.. 'Date:'
local third_line = pad(username, n_n + 1) .. '| '
.. pad(time_formatted, t_n + 1) .. '| '
.. pad(points, p_n + 1) .. '| '
.. date
return message:reply('```' .. first_line .. '\n' .. second_line .. '\n' .. third_line .. '```')
end)