Merge pull request #11 from dowoge/global-slash-commands
Global slash commands
This commit is contained in:
commit
c9bdd6a8b7
@ -1,3 +1,3 @@
|
||||
.\exes\lit.exe install SinisterRectus/discordia
|
||||
.\exes\lit.exe install GitSparTV/discordia-slash
|
||||
git clone https://github.com/Bilal2453/discordia-interactions.git ./deps/discordia-interactions
|
||||
git clone git@github.com:GitSparTV/discordia-slash.git ./deps/discordia-slash
|
||||
git clone git@github.com:Bilal2453/discordia-interactions.git ./deps/discordia-interactions
|
15
src/MessageCommands/_Example.lua
Normal file
15
src/MessageCommands/_Example.lua
Normal file
@ -0,0 +1,15 @@
|
||||
local SlashCommandTools = require('discordia-slash').util.tools()
|
||||
|
||||
local GetProfilePictureCommand = SlashCommandTools.messageCommand('Copy message', 'Says the same exact message (text only)')
|
||||
|
||||
local function Callback(Interaction, Command, Message)
|
||||
local MessageContent = Message.content
|
||||
if MessageContent then
|
||||
return Interaction:reply(MessageContent)
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
Command = GetProfilePictureCommand,
|
||||
Callback = Callback
|
||||
}
|
139
src/SlashCommands/Minecraft.lua
Normal file
139
src/SlashCommands/Minecraft.lua
Normal file
@ -0,0 +1,139 @@
|
||||
local Discordia = require('discordia')
|
||||
local json = require('json')
|
||||
local http_request = require('../Modules/http.lua')
|
||||
Discordia.extensions()
|
||||
|
||||
local ApplicationCommandOptionTypes = Discordia.enums.appCommandOptionType
|
||||
|
||||
local SlashCommandTools = require('discordia-slash').util.tools()
|
||||
|
||||
local MinecraftMainCommand = SlashCommandTools.slashCommand('minecraft', 'Minecraft server related commands')
|
||||
|
||||
local MinecraftStatusSubCommand = SlashCommandTools.subCommand('status', 'Get the Minecraft server status according to the preferred IP address set for this server')
|
||||
local MinecraftSetIpSubCommand = SlashCommandTools.subCommand('setip', 'Set the preferred Minecraft server IP address for this server')
|
||||
|
||||
local MinecraftSetIpOptions = SlashCommandTools.string('ip', 'The IP address of the server')
|
||||
MinecraftSetIpOptions:setRequired(true)
|
||||
MinecraftSetIpSubCommand:addOption(MinecraftSetIpOptions)
|
||||
|
||||
MinecraftMainCommand:addOption(MinecraftSetIpSubCommand)
|
||||
MinecraftMainCommand:addOption(MinecraftStatusSubCommand)
|
||||
|
||||
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
|
||||
|
||||
local SubCommandCallbacks = {}
|
||||
local function Status(Interaction, Command, Args)
|
||||
local GuildId = Interaction.guild and Interaction.guild.id
|
||||
if not GuildId then
|
||||
return Interaction:reply('You cannot use this command outside of a Discord server', true)
|
||||
end
|
||||
|
||||
local GlobalMinecraftData = json.decode(io.open('minecraft_data.json', 'r'):read('*a'))
|
||||
if not GlobalMinecraftData then
|
||||
return Interaction:reply('Could not read server data', true)
|
||||
end
|
||||
|
||||
local ServerMinecraftData = GlobalMinecraftData[GuildId]
|
||||
if not ServerMinecraftData then
|
||||
return Interaction:reply('There is no data for this Discord server', true)
|
||||
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 Interaction:reply({embed = EmbedData})
|
||||
end
|
||||
|
||||
local function SetIp(Interaction, Command, Args)
|
||||
local ServerIPStr = Args.ip
|
||||
|
||||
local GuildId = Interaction.guild and Interaction.guild.id
|
||||
if not GuildId then
|
||||
return Interaction:reply('You cannot use this command outside of a Discord server')
|
||||
end
|
||||
|
||||
local ServerIP = ServerIPStr:match("(%d+%.%d+%.%d+%.%d+)") or ServerIPStr:match("(%w*%.?%w+%.%w+)")
|
||||
if not ServerIP then
|
||||
return Interaction:reply('Invalid server IP')
|
||||
end
|
||||
local ServerPort = ServerIPStr:match(ServerIP..':(%d+)') or 25565
|
||||
|
||||
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 Interaction:reply('Successfully added `'..ServerIP..':'..ServerPort..'` for ServerId='..GuildId)
|
||||
end
|
||||
SubCommandCallbacks.status = Status
|
||||
SubCommandCallbacks.setip = SetIp
|
||||
|
||||
|
||||
|
||||
local function Callback(Interaction, Command, Args)
|
||||
local SubCommandOption = Command.options[1]
|
||||
if SubCommandOption.type == ApplicationCommandOptionTypes.subCommand then
|
||||
local SubCommandName = SubCommandOption.name
|
||||
local SubCommandCallback = SubCommandCallbacks[SubCommandName]
|
||||
local SubCommandArgs = Args[SubCommandName]
|
||||
if SubCommandCallback then
|
||||
SubCommandCallback(Interaction, Command, SubCommandArgs)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return {
|
||||
Command = MinecraftMainCommand,
|
||||
Callback = Callback
|
||||
}
|
@ -1,30 +1,21 @@
|
||||
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 SlashCommandTools = require('discordia-slash').util.tools()
|
||||
|
||||
local Discordia = require('discordia')
|
||||
local Date = Discordia.Date
|
||||
Discordia.extensions()
|
||||
|
||||
local API = require('../Modules/strafes_net.lua')
|
||||
|
||||
local UserCommand = SlashCommandTools.slashCommand('user', 'Looks up specified user on Roblox')
|
||||
|
||||
local UsernameOption = SlashCommandTools.string('username', 'Username to look up')
|
||||
local UserIdOption = SlashCommandTools.integer('user_id', 'User ID to look up')
|
||||
local MemberOption = SlashCommandTools.user('member', 'User to look up')
|
||||
|
||||
UserCommand:addOption(UsernameOption)
|
||||
UserCommand:addOption(UserIdOption)
|
||||
UserCommand:addOption(MemberOption)
|
||||
|
||||
Badges = {
|
||||
'275640532', --Bhop, pre-group
|
||||
'363928432', --Surf, pre-group
|
||||
@ -42,7 +33,7 @@ local function round(x,n)
|
||||
end
|
||||
|
||||
local function FromYMD(ymd)
|
||||
return date.fromISO(ymd.."T00:00:00")[1]
|
||||
return Date.fromISO(ymd.."T00:00:00")[1]
|
||||
end
|
||||
local function leftpad(s,n,p)
|
||||
return string.rep(p,n-#tostring(s))..s
|
||||
@ -84,18 +75,30 @@ local function GuessDateFromAssetID(AssetID)
|
||||
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 function Callback(Interaction, Command, Args)
|
||||
local user_info
|
||||
if Args then
|
||||
local username = Args.username
|
||||
local user_id = Args.user_id
|
||||
local member = Args.member
|
||||
if username then
|
||||
user_info = API:GetRobloxInfoFromUsername(username)
|
||||
elseif user_id then
|
||||
user_info = API:GetRobloxInfoFromUserId(user_id)
|
||||
elseif member then
|
||||
user_info = API:GetRobloxInfoFromDiscordId(member.id)
|
||||
end
|
||||
else
|
||||
local user = Interaction.member or Interaction.user
|
||||
if user then
|
||||
user_info = API:GetRobloxInfoFromDiscordId(user.id)
|
||||
end
|
||||
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 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
|
||||
@ -114,7 +117,7 @@ commands:Add('user',{},'user <username|mention|"me">', function(t)
|
||||
|
||||
local LastLocation = onlineStatus_info.lastLocation
|
||||
if onlineStatus_info.userPresenceType==2 then LastLocation="Ingame" end
|
||||
local LastOnline = date.fromISO(onlineStatus_info.lastOnline):toSeconds()
|
||||
local LastOnline = Date.fromISO(onlineStatus_info.lastOnline):toSeconds()
|
||||
|
||||
local verificationAssetId = API:GetVerificationItemID(id)
|
||||
local verificationDate = "Not verified"
|
||||
@ -132,7 +135,7 @@ commands:Add('user',{},'user <username|mention|"me">', function(t)
|
||||
local firstBadge,firstBadgeDate = 0,math.huge
|
||||
for _,badge in next,badgeData do
|
||||
local badgeId = badge.badgeId
|
||||
local awardedDate = tonumber(date.fromISO(badge.awardedDate):toSeconds())
|
||||
local awardedDate = tonumber(Date.fromISO(badge.awardedDate):toSeconds())
|
||||
if firstBadgeDate>awardedDate then
|
||||
firstBadge=badgeId
|
||||
firstBadgeDate=awardedDate
|
||||
@ -163,5 +166,10 @@ commands:Add('user',{},'user <username|mention|"me">', function(t)
|
||||
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)
|
||||
Interaction:reply({embed=embed})
|
||||
end
|
||||
|
||||
return {
|
||||
Command = UserCommand,
|
||||
Callback = Callback
|
||||
}
|
17
src/SlashCommands/_Example.lua
Normal file
17
src/SlashCommands/_Example.lua
Normal file
@ -0,0 +1,17 @@
|
||||
local SlashCommandTools = require('discordia-slash').util.tools()
|
||||
|
||||
local PongCommand = SlashCommandTools.slashCommand('ping', 'Replies with pong')
|
||||
|
||||
local MessageOption = SlashCommandTools.string('message', 'What the bot will append to the message')
|
||||
|
||||
PongCommand:addOption(MessageOption)
|
||||
|
||||
local function Callback(Interaction, Command, Args)
|
||||
local Message = Args.message
|
||||
return Interaction:reply('Pong! '..Message)
|
||||
end
|
||||
|
||||
return {
|
||||
Command = PongCommand,
|
||||
Callback = Callback
|
||||
}
|
15
src/UserCommands/GetProfilePicture.lua
Normal file
15
src/UserCommands/GetProfilePicture.lua
Normal file
@ -0,0 +1,15 @@
|
||||
local SlashCommandTools = require('discordia-slash').util.tools()
|
||||
|
||||
local GetProfilePictureCommand = SlashCommandTools.userCommand('Get profile picture', 'Gets user avatar')
|
||||
|
||||
local function Callback(Interaction, Command, Member)
|
||||
local AvatarURL = Member:getAvatarURL(1024)
|
||||
if AvatarURL then
|
||||
return Interaction:reply(AvatarURL, true)
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
Command = GetProfilePictureCommand,
|
||||
Callback = Callback
|
||||
}
|
111
src/main.lua
111
src/main.lua
@ -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)
|
73
src/modules/CommandCollector.lua
Normal file
73
src/modules/CommandCollector.lua
Normal file
@ -0,0 +1,73 @@
|
||||
local RELATIVE_PATH_TO_COMMANDS = '../' --this is because the require function will call to a path relative to this current file :D
|
||||
local IGNORE_STARTING_FILE_NAME = '_'
|
||||
|
||||
local CommandCollector = {}
|
||||
CommandCollector.__index = CommandCollector
|
||||
|
||||
function CommandCollector.new(Prefix)
|
||||
local self = setmetatable({}, CommandCollector)
|
||||
|
||||
self.Prefix = Prefix
|
||||
self.Collected = false
|
||||
self.Collection = {}
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function CommandCollector:Get(CommandName)
|
||||
for CommandIndex, CommandData in next, self.Collection do
|
||||
if CommandName == CommandData.Command.name then
|
||||
return CommandData
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CommandCollector:Collect()
|
||||
if self.Collected then
|
||||
print('Command collector for', self.Prefix, 'commands was already collected')
|
||||
return
|
||||
end
|
||||
|
||||
local CommandsContainerPath = self.Prefix..'Commands/'
|
||||
|
||||
for File in io.popen('dir "./src/'..CommandsContainerPath..'" /b'):lines() do
|
||||
if File:sub(1, 1) ~= IGNORE_STARTING_FILE_NAME then
|
||||
local Success, Return = pcall(require, RELATIVE_PATH_TO_COMMANDS..CommandsContainerPath..File)
|
||||
if Success then
|
||||
if not Return.Command or not Return.Callback then
|
||||
print('Malformed command data in', CommandsContainerPath..File, 'Reason: returned command data table is missing a Command or Callback field')
|
||||
return
|
||||
end
|
||||
print('Loaded', CommandsContainerPath..File)
|
||||
table.insert(self.Collection, {Command = Return.Command, Callback = Return.Callback})
|
||||
else
|
||||
print('Error loading', CommandsContainerPath..File, 'Error:', Return)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
print('Loaded a total of '..#self.Collection..' '..self.Prefix..' command'..(#self.Collection ~= 1 and 's' or ''))
|
||||
|
||||
self.Collected = true
|
||||
return self
|
||||
end
|
||||
|
||||
function CommandCollector:Publish(Client)
|
||||
if not Client.createGlobalApplicationCommand then
|
||||
print('Client does not have the method \'createGlobalApplicationCommand\'')
|
||||
return
|
||||
end
|
||||
|
||||
for CommandIndex, CommandData in next, self.Collection do
|
||||
local Success, Return = pcall(Client.createGlobalApplicationCommand, Client, CommandData.Command)
|
||||
if Success then
|
||||
print('Published command', CommandData.Command.name)
|
||||
else
|
||||
print('Failed to publish command', CommandData.Command.name, 'Error:', Return)
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return CommandCollector
|
@ -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
|
@ -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)
|
@ -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)
|
@ -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)
|
@ -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
|
@ -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)
|
@ -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)
|
@ -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)
|
@ -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)
|
@ -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 )
|
@ -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)
|
Loading…
Reference in New Issue
Block a user