Make new commands and examples
This commit is contained in:
parent
319c00f90b
commit
dc90da36df
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
|
||||||
|
}
|
175
src/SlashCommands/User.lua
Normal file
175
src/SlashCommands/User.lua
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
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
|
||||||
|
'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
|
||||||
|
|
||||||
|
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 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
|
||||||
|
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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user