big boy update fr
big boy update
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
using SkyBot.Models;
|
using SkyBot.Models;
|
||||||
using Valour.Sdk.Models;
|
using Valour.Sdk.Models;
|
||||||
|
|
||||||
@@ -16,14 +17,9 @@ namespace SkyBot.Commands
|
|||||||
{
|
{
|
||||||
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
long channelId = ctx.ChannelId;
|
long channelId = ctx.ChannelId;
|
||||||
PlanetMember member = ctx.Member;
|
|
||||||
|
|
||||||
string message = $"";
|
|
||||||
|
|
||||||
if (channelCache.TryGetValue(channelId, out var channel))
|
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||||
{
|
|
||||||
await MessageHelper.ReplyAsync(ctx, channel, message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,29 +3,45 @@ using SkyBot.Helpers;
|
|||||||
using SkyBot.Models;
|
using SkyBot.Models;
|
||||||
using Valour.Sdk.Client;
|
using Valour.Sdk.Client;
|
||||||
using Valour.Sdk.Models;
|
using Valour.Sdk.Models;
|
||||||
|
using Valour.Shared;
|
||||||
|
|
||||||
namespace SkyBot.Commands
|
namespace SkyBot.Commands
|
||||||
{
|
{
|
||||||
public class Test : ICommand
|
public class Test : ICommand
|
||||||
{
|
{
|
||||||
public string Name => "test";
|
public string Name => "edit";
|
||||||
public string[] Aliases => [];
|
public string[] Aliases => [];
|
||||||
public string Description => "Just a test command";
|
public string Description => "Edit the bots message";
|
||||||
public string Section => "Dev";
|
public string Section => "Dev";
|
||||||
public string Usage => "test";
|
public string Usage => "reply -> edit <message>";
|
||||||
|
|
||||||
public async Task Execute(CommandContext ctx)
|
public async Task Execute(CommandContext ctx)
|
||||||
{
|
{
|
||||||
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
long channelId = ctx.ChannelId;
|
|
||||||
ValourClient client = ctx.Client;
|
ValourClient client = ctx.Client;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
PlanetMember member = ctx.Member;
|
PlanetMember member = ctx.Member;
|
||||||
Message message = ctx.Message;
|
Message message = ctx.Message;
|
||||||
Planet planet = ctx.Planet;
|
string[] args = ctx.Args;
|
||||||
|
|
||||||
if (channelCache.TryGetValue(channelId, out var channel))
|
if (channelCache.TryGetValue(channelId, out var channel))
|
||||||
{
|
{
|
||||||
await MessageHelper.ReplyAsync(ctx, channel, "This is a test message");
|
if(!PermissionHelper.IsOwner(member))
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "This is a Dev only command.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.ReplyToId == null)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Please reply to a message.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client.Cache.Messages.TryGet(message.ReplyToId.Value, out var msg))
|
||||||
|
{
|
||||||
|
await MessageHelper.EditAsync(channel, msg, string.Join(" ", args));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
64
SkyBot/Commands/Fun/8ball.cs
Normal file
64
SkyBot/Commands/Fun/8ball.cs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
|
using SkyBot.Models;
|
||||||
|
using Valour.Sdk.Models;
|
||||||
|
using Valour.Shared;
|
||||||
|
|
||||||
|
namespace SkyBot.Commands
|
||||||
|
{
|
||||||
|
public class EightBall : ICommand
|
||||||
|
{
|
||||||
|
public string Name => "8ball";
|
||||||
|
public string[] Aliases => [];
|
||||||
|
public string Description => "Ask the magic 8ball a question.";
|
||||||
|
public string Section => "Fun";
|
||||||
|
public string Usage => "8ball <question>";
|
||||||
|
|
||||||
|
private static readonly string[] Responses =
|
||||||
|
[
|
||||||
|
"It is certain.",
|
||||||
|
"It is decidedly so.",
|
||||||
|
"Without a doubt.",
|
||||||
|
"Yes, definitely.",
|
||||||
|
"You may rely on it.",
|
||||||
|
"As I see it, yes.",
|
||||||
|
"Most likely.",
|
||||||
|
"Outlook good.",
|
||||||
|
"Yes.",
|
||||||
|
"Signs point to yes.",
|
||||||
|
"Reply hazy, try again.",
|
||||||
|
"Ask again later.",
|
||||||
|
"Better not tell you now.",
|
||||||
|
"Cannot predict now.",
|
||||||
|
"Concentrate and ask again.",
|
||||||
|
"Don't count on it.",
|
||||||
|
"My reply is no.",
|
||||||
|
"My sources say no.",
|
||||||
|
"Outlook not so good.",
|
||||||
|
"Very doubtful."
|
||||||
|
];
|
||||||
|
|
||||||
|
public async Task Execute(CommandContext ctx)
|
||||||
|
{
|
||||||
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
|
string[] args = ctx.Args;
|
||||||
|
|
||||||
|
if (channelCache.TryGetValue(channelId, out var channel))
|
||||||
|
{
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Please ask a question.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TaskResult<Message> result = await MessageHelper.ReplyAsync(ctx, channel, $"🎱 Thinking...");
|
||||||
|
await channel.SendIsTyping();
|
||||||
|
await Task.Delay(2000);
|
||||||
|
string response = Responses[Random.Shared.Next(Responses.Length)];
|
||||||
|
await MessageHelper.EditAsync(channel, result.Data, $"🎱 {response}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
38
SkyBot/Commands/Fun/Choose.cs
Normal file
38
SkyBot/Commands/Fun/Choose.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
|
using SkyBot.Models;
|
||||||
|
using Valour.Sdk.Models;
|
||||||
|
using Valour.Shared;
|
||||||
|
|
||||||
|
namespace SkyBot.Commands
|
||||||
|
{
|
||||||
|
public class Choose : ICommand
|
||||||
|
{
|
||||||
|
public string Name => "choose";
|
||||||
|
public string[] Aliases => ["pick"];
|
||||||
|
public string Description => "Picks one of the given options.";
|
||||||
|
public string Section => "Fun";
|
||||||
|
public string Usage => "choose <option1> <option2> ...";
|
||||||
|
|
||||||
|
public async Task Execute(CommandContext ctx)
|
||||||
|
{
|
||||||
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
|
string[] args = ctx.Args;
|
||||||
|
|
||||||
|
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||||
|
|
||||||
|
if (ctx.Args.Length < 2)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Please provide at least two options.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskResult<Message> result = await MessageHelper.ReplyAsync(ctx, channel, "🤔 Choosing...");
|
||||||
|
await Task.Delay(1000);
|
||||||
|
|
||||||
|
string choice = args[Random.Shared.Next(args.Length)];
|
||||||
|
await MessageHelper.EditAsync(channel, result.Data, $"I choose **{choice}**!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
SkyBot/Commands/Fun/CoinFlip.cs
Normal file
32
SkyBot/Commands/Fun/CoinFlip.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
|
using SkyBot.Models;
|
||||||
|
using Valour.Sdk.Models;
|
||||||
|
using Valour.Shared;
|
||||||
|
|
||||||
|
namespace SkyBot.Commands
|
||||||
|
{
|
||||||
|
public class CoinFlip : ICommand
|
||||||
|
{
|
||||||
|
public string Name => "coinflip";
|
||||||
|
public string[] Aliases => ["cf"];
|
||||||
|
public string Description => "Flips a coin.";
|
||||||
|
public string Section => "Fun";
|
||||||
|
public string Usage => "coinflip";
|
||||||
|
|
||||||
|
public async Task Execute(CommandContext ctx)
|
||||||
|
{
|
||||||
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
|
|
||||||
|
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||||
|
|
||||||
|
TaskResult<Message> result = await MessageHelper.ReplyAsync(ctx, channel, "🪙 Flipping...");
|
||||||
|
await channel.SendIsTyping();
|
||||||
|
await Task.Delay(3000);
|
||||||
|
|
||||||
|
string outcome = Random.Shared.Next(2) == 0 ? "Heads" : "Tails";
|
||||||
|
await MessageHelper.EditAsync(channel, result.Data, $"🪙 {outcome}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
60
SkyBot/Commands/Fun/Dice.cs
Normal file
60
SkyBot/Commands/Fun/Dice.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
|
using SkyBot.Helpers;
|
||||||
|
using SkyBot.Models;
|
||||||
|
using Valour.Sdk.Models;
|
||||||
|
using Valour.Shared;
|
||||||
|
|
||||||
|
namespace SkyBot.Commands
|
||||||
|
{
|
||||||
|
public class Dice : ICommand
|
||||||
|
{
|
||||||
|
public string Name => "dice";
|
||||||
|
public string[] Aliases => ["roll"];
|
||||||
|
public string Description => "Rolls dice.";
|
||||||
|
public string Section => "Fun";
|
||||||
|
public string Usage => "roll <dice> (e.g. 2d6, d20, 3d8)";
|
||||||
|
|
||||||
|
public async Task Execute(CommandContext ctx)
|
||||||
|
{
|
||||||
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
|
PlanetMember member = ctx.Member;
|
||||||
|
string[] args = ctx.Args;
|
||||||
|
|
||||||
|
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||||
|
|
||||||
|
string input = args.Length > 0 ? args[0].ToLower() : "1d6";
|
||||||
|
|
||||||
|
string[] parts = input.Split('d');
|
||||||
|
if (parts.Length != 2 || !int.TryParse(parts[1], out int sides) || sides < 2)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Invalid dice format. Use something like `2d6` or `d20`.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = 1;
|
||||||
|
if (!string.IsNullOrWhiteSpace(parts[0]) && !int.TryParse(parts[0], out count))
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Invalid dice format. Use something like `2d6` or `d20`.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < 1 || count > 100)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "You can only roll between 1 and 100 dice at a time.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<int> rolls = Enumerable.Range(0, count).Select(_ => Random.Shared.Next(1, sides+1)).ToList();
|
||||||
|
int total = rolls.Sum();
|
||||||
|
|
||||||
|
TaskResult<Message> rolling = await MessageHelper.ReplyAsync(ctx, channel, "🎲 Rolling...");
|
||||||
|
await channel.SendIsTyping();
|
||||||
|
await Task.Delay(2000);
|
||||||
|
|
||||||
|
string rollDisplay = count > 1 ? $"({string.Join(" + ", rolls)}) = **{total}**" : $"**{total}**";
|
||||||
|
await MessageHelper.EditAsync(channel, rolling.Data, $"🎲 Rolled {input}: {rollDisplay}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Net.NetworkInformation;
|
|
||||||
using SkyBot.Helpers;
|
using SkyBot.Helpers;
|
||||||
using SkyBot.Models;
|
using SkyBot.Models;
|
||||||
using Valour.Sdk.Models;
|
using Valour.Sdk.Models;
|
||||||
@@ -19,24 +18,21 @@ namespace SkyBot.Commands
|
|||||||
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
long channelId = ctx.ChannelId;
|
long channelId = ctx.ChannelId;
|
||||||
PlanetMember member = ctx.Member;
|
PlanetMember member = ctx.Member;
|
||||||
String[] args = ctx.Args;
|
string[] args = ctx.Args;
|
||||||
Message message = ctx.Message;
|
Message message = ctx.Message;
|
||||||
|
|
||||||
string reply = string.Join(" ", args);
|
string reply = string.Join(" ", args);
|
||||||
|
|
||||||
if (channelCache.TryGetValue(channelId, out var channel))
|
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||||
|
if (string.IsNullOrWhiteSpace(reply)) await MessageHelper.ReplyAsync(ctx, channel, $"Enter a message to echo.");
|
||||||
|
|
||||||
|
reply = $"{member.Name} » {reply}";
|
||||||
|
if (reply.Length > 2048)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(reply)) await channel.SendMessageAsync($"{MentionHelper.Mention(member)} Enter a message to echo.");
|
reply = reply.Substring(0, 2048);
|
||||||
|
|
||||||
reply = $"{member.Name} » {reply}";
|
|
||||||
|
|
||||||
if (reply.Length > 2048)
|
|
||||||
{
|
|
||||||
reply = reply.Substring(0, 2048);
|
|
||||||
}
|
|
||||||
|
|
||||||
await MessageHelper.ReplyAsync(ctx, channel, reply);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, reply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
51
SkyBot/Commands/Fun/Mock.cs
Normal file
51
SkyBot/Commands/Fun/Mock.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
|
using SkyBot.Models;
|
||||||
|
using Valour.Sdk.Models;
|
||||||
|
|
||||||
|
namespace SkyBot.Commands
|
||||||
|
{
|
||||||
|
public class Mock : ICommand
|
||||||
|
{
|
||||||
|
public string Name => "mock";
|
||||||
|
public string[] Aliases => [];
|
||||||
|
public string Description => "Mock text";
|
||||||
|
public string Section => "Fun";
|
||||||
|
public string Usage => "mock [text] (Or reply to a message)";
|
||||||
|
|
||||||
|
public async Task Execute(CommandContext ctx)
|
||||||
|
{
|
||||||
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
|
string[] args = ctx.Args;
|
||||||
|
Message message = ctx.Message;
|
||||||
|
|
||||||
|
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||||
|
|
||||||
|
string text;
|
||||||
|
|
||||||
|
if (message.ReplyToId.HasValue)
|
||||||
|
{
|
||||||
|
var replyMessage = await message.FetchReplyMessageAsync();
|
||||||
|
text = replyMessage?.Content ?? "";
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Please provide some text to mock or reply to a message.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
text = string.Join(" ", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "No text to mock.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string mocked = new string(text.Select((c, i) => i % 2 == 0 ? char.ToLower(c) : char.ToUpper(c)).ToArray());
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, mocked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
SkyBot/Commands/Fun/Reverse.cs
Normal file
51
SkyBot/Commands/Fun/Reverse.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
|
using SkyBot.Models;
|
||||||
|
using Valour.Sdk.Models;
|
||||||
|
|
||||||
|
namespace SkyBot.Commands
|
||||||
|
{
|
||||||
|
public class Reverse : ICommand
|
||||||
|
{
|
||||||
|
public string Name => "reverse";
|
||||||
|
public string[] Aliases => [];
|
||||||
|
public string Description => "Reverses yours or a replied text.";
|
||||||
|
public string Section => "Fun";
|
||||||
|
public string Usage => "reverse [text] (Or reply to a message)";
|
||||||
|
|
||||||
|
public async Task Execute(CommandContext ctx)
|
||||||
|
{
|
||||||
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
|
string[] args = ctx.Args;
|
||||||
|
Message message = ctx.Message;
|
||||||
|
|
||||||
|
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||||
|
|
||||||
|
string text;
|
||||||
|
|
||||||
|
if (message.ReplyToId.HasValue)
|
||||||
|
{
|
||||||
|
var replyMessage = await message.FetchReplyMessageAsync();
|
||||||
|
text = replyMessage?.Content ?? "";
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Please provide some text to reverse or reply to a message.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
text = string.Join(" ", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "No text to reverse.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string reversed = new string(text.Reverse().ToArray());
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, $"Reversed: {reversed}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
61
SkyBot/Commands/Fun/RockPaperScissors.cs
Normal file
61
SkyBot/Commands/Fun/RockPaperScissors.cs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
|
using SkyBot.Models;
|
||||||
|
using Valour.Sdk.Models;
|
||||||
|
using Valour.Shared;
|
||||||
|
|
||||||
|
namespace SkyBot.Commands
|
||||||
|
{
|
||||||
|
public class RockPaperScissors : ICommand
|
||||||
|
{
|
||||||
|
public string Name => "rps";
|
||||||
|
public string[] Aliases => [];
|
||||||
|
public string Description => "Play Rock Paper Scissors against the bot.";
|
||||||
|
public string Section => "Fun";
|
||||||
|
public string Usage => "rps <rock|paper|scissors>";
|
||||||
|
|
||||||
|
private static readonly string[] Choices = ["rock", "paper", "scissors"];
|
||||||
|
private static readonly string[] Emojis = ["🪨", "📄", "✂️"];
|
||||||
|
|
||||||
|
public async Task Execute(CommandContext ctx)
|
||||||
|
{
|
||||||
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
|
string[] args = ctx.Args;
|
||||||
|
|
||||||
|
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||||
|
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Please choose `Rock`, `Paper`, or `Scissors`.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string input = args[0].ToLower();
|
||||||
|
int playerIndex = Array.IndexOf(Choices, input);
|
||||||
|
|
||||||
|
if (playerIndex == -1)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Invalid choice. Please choose `Rock`, `Paper`, or `Scissors`.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskResult<Message> result = await MessageHelper.ReplyAsync(ctx, channel, "🤔 Thinking...");
|
||||||
|
await Task.Delay(1000);
|
||||||
|
|
||||||
|
int botIndex = Random.Shared.Next(3);
|
||||||
|
|
||||||
|
string playerChoice = $"{Emojis[playerIndex]} {Choices[playerIndex].ToTitleCase()}";
|
||||||
|
string botChoice = $"{Emojis[botIndex]} {Choices[botIndex].ToTitleCase()}";
|
||||||
|
|
||||||
|
string outcome;
|
||||||
|
if (playerIndex == botIndex) outcome = "It's a tie!";
|
||||||
|
else if ((playerIndex == 0 && botIndex == 2) ||
|
||||||
|
(playerIndex == 1 && botIndex == 0) ||
|
||||||
|
(playerIndex == 2 && botIndex == 1)) outcome = "You win! 🎉";
|
||||||
|
else outcome = "You Lose! 🥲";
|
||||||
|
|
||||||
|
await MessageHelper.EditAsync(channel, result.Data, $"**You**: {playerChoice}\nvs\n**Bot**: {botChoice}\n[]()\n{outcome}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
using SkyBot.Models;
|
using SkyBot.Models;
|
||||||
using Valour.Sdk.Models;
|
using Valour.Sdk.Models;
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@ namespace SkyBot.Commands
|
|||||||
public string[] Aliases => ["dev"];
|
public string[] Aliases => ["dev"];
|
||||||
public string Description => "Sends an invite link to the Dev Central Planet.";
|
public string Description => "Sends an invite link to the Dev Central Planet.";
|
||||||
public string Section => "Info";
|
public string Section => "Info";
|
||||||
public string Usage => "devcentral|dev";
|
public string Usage => "devcentral";
|
||||||
|
|
||||||
public async Task Execute(CommandContext ctx)
|
public async Task Execute(CommandContext ctx)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace SkyBot.Commands
|
|||||||
public string[] Aliases => ["h"];
|
public string[] Aliases => ["h"];
|
||||||
public string Description => "Shows all the commands and their descriptions.";
|
public string Description => "Shows all the commands and their descriptions.";
|
||||||
public string Section => "Info";
|
public string Section => "Info";
|
||||||
public string Usage => "help|h [section] [page]";
|
public string Usage => "help [section] [page]";
|
||||||
private const int PageSize = 5;
|
private const int PageSize = 5;
|
||||||
|
|
||||||
public async Task Execute(CommandContext ctx)
|
public async Task Execute(CommandContext ctx)
|
||||||
@@ -23,8 +23,6 @@ namespace SkyBot.Commands
|
|||||||
string[] args = ctx.Args;
|
string[] args = ctx.Args;
|
||||||
PlanetMember member = ctx.Member;
|
PlanetMember member = ctx.Member;
|
||||||
|
|
||||||
bool isOwner = await PermissionHelper.IsOwner(member);
|
|
||||||
|
|
||||||
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||||
|
|
||||||
// Show all sections.
|
// Show all sections.
|
||||||
@@ -35,8 +33,8 @@ namespace SkyBot.Commands
|
|||||||
foreach (var section in CommandRegistry.Sections.Keys)
|
foreach (var section in CommandRegistry.Sections.Keys)
|
||||||
{
|
{
|
||||||
if (section == "template") continue;
|
if (section == "template") continue;
|
||||||
if (section == "dev" && !isOwner) continue;
|
if (section == "dev" && !PermissionHelper.IsOwner(member)) continue;
|
||||||
if (section == "mod" && !PermissionHelper.HasPermAsync(member, [PlanetPermissions.Kick, PlanetPermissions.Ban, PlanetPermissions.ManageRoles]).Result) continue;
|
if (section == "mod" && !PermissionHelper.HasPerm(member, [PlanetPermissions.Kick, PlanetPermissions.Ban, PlanetPermissions.ManageRoles])) continue;
|
||||||
sb.AppendLine($"- `{section.ToTitleCase()}` ({CommandRegistry.Sections[section].Count})");
|
sb.AppendLine($"- `{section.ToTitleCase()}` ({CommandRegistry.Sections[section].Count})");
|
||||||
}
|
}
|
||||||
sb.AppendLine($"\nUse `{Config.Prefix}help <category>` to see commands in a category.");
|
sb.AppendLine($"\nUse `{Config.Prefix}help <category>` to see commands in a category.");
|
||||||
@@ -52,13 +50,13 @@ namespace SkyBot.Commands
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sectionName == "dev" && !isOwner)
|
if (sectionName == "dev" && !PermissionHelper.IsOwner(member))
|
||||||
{
|
{
|
||||||
await MessageHelper.ReplyAsync(ctx, channel, $"Unknown category `{sectionName}`.");
|
await MessageHelper.ReplyAsync(ctx, channel, $"Unknown category `{sectionName}`.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sectionName == "mod" && !PermissionHelper.HasPermAsync(member, [PlanetPermissions.Kick, PlanetPermissions.Ban, PlanetPermissions.ManageRoles]).Result)
|
if (sectionName == "mod" && !PermissionHelper.HasPerm(member, [PlanetPermissions.Kick, PlanetPermissions.Ban, PlanetPermissions.ManageRoles]))
|
||||||
{
|
{
|
||||||
await MessageHelper.ReplyAsync(ctx, channel, $"Unknown category `{sectionName}`.");
|
await MessageHelper.ReplyAsync(ctx, channel, $"Unknown category `{sectionName}`.");
|
||||||
return;
|
return;
|
||||||
|
|||||||
109
SkyBot/Commands/Info/Info.cs
Normal file
109
SkyBot/Commands/Info/Info.cs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Text;
|
||||||
|
using SkyBot.Helpers;
|
||||||
|
using SkyBot.Models;
|
||||||
|
using Valour.Sdk.Models;
|
||||||
|
|
||||||
|
namespace SkyBot.Commands
|
||||||
|
{
|
||||||
|
public class Info : ICommand
|
||||||
|
{
|
||||||
|
public string Name => "info";
|
||||||
|
public string[] Aliases => [];
|
||||||
|
public string Description => "Shows the info about a User or the Planet.";
|
||||||
|
public string Section => "Info";
|
||||||
|
public string Usage => "info <user|planet> [mention|memberid]";
|
||||||
|
|
||||||
|
public async Task Execute(CommandContext ctx)
|
||||||
|
{
|
||||||
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
|
string[] args = ctx.Args;
|
||||||
|
|
||||||
|
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||||
|
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Please specify `user` or `planet`.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (args[0].ToLower())
|
||||||
|
{
|
||||||
|
case "user":
|
||||||
|
case "u":
|
||||||
|
await HandleUserInfo(ctx, channel);
|
||||||
|
break;
|
||||||
|
case "planet":
|
||||||
|
case "p":
|
||||||
|
await HandlePlanetInfo(ctx, channel);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "invalid option. Use `user` or `planet`.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task HandleUserInfo(CommandContext ctx, Channel channel)
|
||||||
|
{
|
||||||
|
Message message = ctx.Message;
|
||||||
|
Planet planet = ctx.Planet;
|
||||||
|
string[] args = ctx.Args;
|
||||||
|
PlanetMember? target;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (message.Mentions != null && message.Mentions.Any())
|
||||||
|
{
|
||||||
|
target = await planet.FetchMemberAsync(message.Mentions.First().TargetId);
|
||||||
|
}
|
||||||
|
else if (args.Length > 1 && long.TryParse(args[1], out long memberid))
|
||||||
|
{
|
||||||
|
target = await planet.FetchMemberAsync(memberid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target = ctx.Member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Exception: {ex.Message}");
|
||||||
|
target = ctx.Member;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Could not find that member.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine($"**{target.Name}**");
|
||||||
|
sb.AppendLine($"User ID: `{target.UserId}`");
|
||||||
|
sb.AppendLine($"Member ID: `{target.Id}`");
|
||||||
|
sb.AppendLine($"Nickname: `{(string.IsNullOrWhiteSpace(target.Nickname) ? "None" : target.Nickname)}`");
|
||||||
|
sb.AppendLine($"Status: `{(string.IsNullOrWhiteSpace(target.Status) ? "None" : target.Status)}`");
|
||||||
|
sb.AppendLine($"Primary Role: `{target.PrimaryRole?.Name ?? "None"}`");
|
||||||
|
sb.AppendLine($"Roles: `{string.Join(", ", target.Roles.Select(r => r.Name))}`");
|
||||||
|
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task HandlePlanetInfo(CommandContext ctx, Channel channel)
|
||||||
|
{
|
||||||
|
var planet = ctx.Planet;
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine($"**{planet.Name}**");
|
||||||
|
sb.AppendLine($"Planet ID: `{planet.Id}`");
|
||||||
|
sb.AppendLine($"Owner ID: `{planet.OwnerId}`");
|
||||||
|
sb.AppendLine($"Member Count: `{planet.Members?.Count ?? 0}`");
|
||||||
|
sb.AppendLine($"Channel Count: `{planet.Channels?.Count ?? 0}`");
|
||||||
|
sb.AppendLine($"Role Count: `{planet.Roles?.Count ?? 0}`");
|
||||||
|
sb.AppendLine($"Description: `{(string.IsNullOrWhiteSpace(planet.Description) ? "None" : planet.Description)}`");
|
||||||
|
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, sb.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
using SkyBot.Models;
|
using SkyBot.Models;
|
||||||
using Valour.Sdk.Models;
|
using Valour.Sdk.Models;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
using SkyBot.Models;
|
using SkyBot.Models;
|
||||||
using Valour.Sdk.Models;
|
using Valour.Sdk.Models;
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@ namespace SkyBot.Commands
|
|||||||
public string[] Aliases => ["mc"];
|
public string[] Aliases => ["mc"];
|
||||||
public string Description => "Sends the Unofficial ValourSMP IPs";
|
public string Description => "Sends the Unofficial ValourSMP IPs";
|
||||||
public string Section => "Info";
|
public string Section => "Info";
|
||||||
public string Usage => "minecraft|mc";
|
public string Usage => "minecraft";
|
||||||
|
|
||||||
public async Task Execute(CommandContext ctx)
|
public async Task Execute(CommandContext ctx)
|
||||||
{
|
{
|
||||||
|
|||||||
31
SkyBot/Commands/Info/Ping.cs
Normal file
31
SkyBot/Commands/Info/Ping.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
|
using SkyBot.Models;
|
||||||
|
using Valour.Sdk.Models;
|
||||||
|
using Valour.Shared;
|
||||||
|
|
||||||
|
namespace SkyBot.Commands
|
||||||
|
{
|
||||||
|
public class Ping : ICommand
|
||||||
|
{
|
||||||
|
public string Name => "ping";
|
||||||
|
public string[] Aliases => [];
|
||||||
|
public string Description => "Shows the bot's response time.";
|
||||||
|
public string Section => "Info";
|
||||||
|
public string Usage => "ping";
|
||||||
|
|
||||||
|
public async Task Execute(CommandContext ctx)
|
||||||
|
{
|
||||||
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
|
|
||||||
|
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||||
|
|
||||||
|
DateTime start = DateTime.UtcNow;
|
||||||
|
TaskResult<Message> message = await MessageHelper.ReplyAsync(ctx, channel, "🏓 Pinging...");
|
||||||
|
double elapsed = (DateTime.UtcNow - start).TotalMilliseconds;
|
||||||
|
|
||||||
|
await MessageHelper.EditAsync(channel, message.Data, $"🏓 Pong! `{elapsed:F0}ms`");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
using SkyBot.Models;
|
using SkyBot.Models;
|
||||||
using Valour.Sdk.Models;
|
using Valour.Sdk.Models;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
using SkyBot.Models;
|
using SkyBot.Models;
|
||||||
using Valour.Sdk.Models;
|
using Valour.Sdk.Models;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
using SkyBot.Models;
|
using SkyBot.Models;
|
||||||
using Valour.Sdk.Models;
|
using Valour.Sdk.Models;
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@ namespace SkyBot.Commands
|
|||||||
public string[] Aliases => ["api"];
|
public string[] Aliases => ["api"];
|
||||||
public string Description => "Sends a link to the Valour.gg Swagger API.";
|
public string Description => "Sends a link to the Valour.gg Swagger API.";
|
||||||
public string Section => "Info";
|
public string Section => "Info";
|
||||||
public string Usage => "swagger|api";
|
public string Usage => "swagger";
|
||||||
|
|
||||||
public async Task Execute(CommandContext ctx)
|
public async Task Execute(CommandContext ctx)
|
||||||
{
|
{
|
||||||
|
|||||||
30
SkyBot/Commands/Info/Uptime.cs
Normal file
30
SkyBot/Commands/Info/Uptime.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
|
using SkyBot.Models;
|
||||||
|
using Valour.Sdk.Models;
|
||||||
|
using Valour.Shared;
|
||||||
|
|
||||||
|
namespace SkyBot.Commands
|
||||||
|
{
|
||||||
|
public class Uptime : ICommand
|
||||||
|
{
|
||||||
|
public string Name => "uptime";
|
||||||
|
public string[] Aliases => ["up"];
|
||||||
|
public string Description => "Shows how long the bot has been running.";
|
||||||
|
public string Section => "Info";
|
||||||
|
public string Usage => "uptime";
|
||||||
|
|
||||||
|
|
||||||
|
public async Task Execute(CommandContext ctx)
|
||||||
|
{
|
||||||
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
|
|
||||||
|
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||||
|
|
||||||
|
TimeSpan uptime = DateTime.UtcNow - SkyBot.StartTime;
|
||||||
|
string formatted = $"{(int)uptime.TotalDays}d {uptime.Hours}h {uptime.Minutes}m {uptime.Seconds}s";
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, $"⏱️ Uptime: `{formatted}`");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,13 +11,12 @@ namespace SkyBot.Commands
|
|||||||
public string[] Aliases => ["users"];
|
public string[] Aliases => ["users"];
|
||||||
public string Description => "Shows the user count of Valour.";
|
public string Description => "Shows the user count of Valour.";
|
||||||
public string Section => "Info";
|
public string Section => "Info";
|
||||||
public string Usage => "usercount|users";
|
public string Usage => "usercount";
|
||||||
|
|
||||||
public async Task Execute(CommandContext ctx)
|
public async Task Execute(CommandContext ctx)
|
||||||
{
|
{
|
||||||
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
long channelId = ctx.ChannelId;
|
long channelId = ctx.ChannelId;
|
||||||
PlanetMember member = ctx.Member;
|
|
||||||
|
|
||||||
string message = @$"Current Valour user count is: {ValourUsercountHelper.ValourUsercount:N0}
|
string message = @$"Current Valour user count is: {ValourUsercountHelper.ValourUsercount:N0}
|
||||||
You can see a graph of the user count here: /meow";
|
You can see a graph of the user count here: /meow";
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
using SkyBot.Models;
|
using SkyBot.Models;
|
||||||
using Valour.Sdk.Models;
|
using Valour.Sdk.Models;
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@ namespace SkyBot.Commands
|
|||||||
public string[] Aliases => [];
|
public string[] Aliases => [];
|
||||||
public string Description => "Shows the current version of the Bot and Valour.";
|
public string Description => "Shows the current version of the Bot and Valour.";
|
||||||
public string Section => "Info";
|
public string Section => "Info";
|
||||||
public string Usage => "";
|
public string Usage => "version";
|
||||||
|
|
||||||
public async Task Execute(CommandContext ctx)
|
public async Task Execute(CommandContext ctx)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System.Collections.Concurrent;
|
|||||||
using SkyBot.Helpers;
|
using SkyBot.Helpers;
|
||||||
using SkyBot.Models;
|
using SkyBot.Models;
|
||||||
using Valour.Sdk.Models;
|
using Valour.Sdk.Models;
|
||||||
|
using Valour.Shared;
|
||||||
using Valour.Shared.Authorization;
|
using Valour.Shared.Authorization;
|
||||||
|
|
||||||
namespace SkyBot.Commands
|
namespace SkyBot.Commands
|
||||||
@@ -11,26 +12,106 @@ namespace SkyBot.Commands
|
|||||||
public string Name => "ban";
|
public string Name => "ban";
|
||||||
public string[] Aliases => [];
|
public string[] Aliases => [];
|
||||||
public string Description => "Bans a user from the planet.";
|
public string Description => "Bans a user from the planet.";
|
||||||
public string Section => "mod";
|
public string Section => "Mod";
|
||||||
public string Usage => "ban <user> [reason]";
|
public string Usage => "ban <mention|memberid> [reason] [length (y=year, M=month, w=week, d=day, h=hour, m=minute)]";
|
||||||
|
|
||||||
public async Task Execute(CommandContext ctx)
|
public async Task Execute(CommandContext ctx)
|
||||||
{
|
{
|
||||||
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
long channelId = ctx.ChannelId;
|
long channelId = ctx.ChannelId;
|
||||||
|
Planet planet = ctx.Planet;
|
||||||
|
Message message = ctx.Message;
|
||||||
|
string[] args = ctx.Args;
|
||||||
PlanetMember member = ctx.Member;
|
PlanetMember member = ctx.Member;
|
||||||
|
PlanetMember bot = await planet.FetchMemberByUserAsync(ctx.Client.Me.Id);
|
||||||
|
|
||||||
|
|
||||||
if (channelCache.TryGetValue(channelId, out var channel))
|
if (channelCache.TryGetValue(channelId, out var channel))
|
||||||
{
|
{
|
||||||
if (!PermissionHelper.HasPermAsync(member, [PlanetPermissions.Ban]).Result)
|
if (!PermissionHelper.HasPerm(member, [PlanetPermissions.Ban]))
|
||||||
{
|
{
|
||||||
await MessageHelper.ReplyAsync(ctx, channel, $"You don't have permission to use this command.");
|
await MessageHelper.ReplyAsync(ctx, channel, $"You don't have permission to use this command.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string message = $"Work in progress...";
|
if (!PermissionHelper.HasPerm(bot, [PlanetPermissions.Ban]))
|
||||||
await MessageHelper.ReplyAsync(ctx, channel, message);
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, $"I don't have permission to ban members.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!message.Mentions.Any() && args.Length < 1)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Please mention someone or user their id.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long targetId;
|
||||||
|
if (message.Mentions.Any())
|
||||||
|
{
|
||||||
|
targetId = message.Mentions.First().TargetId;
|
||||||
|
}
|
||||||
|
else if (!long.TryParse(args[0], out targetId))
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Invalid member ID.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PlanetMember victim = await planet.FetchMemberAsync(targetId);
|
||||||
|
|
||||||
|
if (victim == null)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Could not find that member.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime? expires = null;
|
||||||
|
List<string> remainingArgs = args[1..].ToList();
|
||||||
|
|
||||||
|
for (int i = 0; i < remainingArgs.Count; i++)
|
||||||
|
{
|
||||||
|
var parsed = MessageHelper.ParseDuration(remainingArgs[i]);
|
||||||
|
if (parsed != null)
|
||||||
|
{
|
||||||
|
expires = parsed;
|
||||||
|
remainingArgs.RemoveAt(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string reason = remainingArgs.Count > 0 ? string.Join(" ", remainingArgs) : "No reason provided.";
|
||||||
|
|
||||||
|
PlanetBan ban = new PlanetBan(ctx.Client)
|
||||||
|
{
|
||||||
|
PlanetId = planet.Id,
|
||||||
|
TargetId = victim.UserId,
|
||||||
|
IssuerId = ctx.Client.Me.Id,
|
||||||
|
Reason = reason,
|
||||||
|
TimeCreated = DateTime.UtcNow,
|
||||||
|
TimeExpires = expires
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TaskResult<PlanetBan> result = await ban.CreateAsync();
|
||||||
|
if (!result.Success)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, $"Failed to ban {victim.Name}: {result.Message}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expires == null)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, $"Permanently Banned `{victim.Name}`. Reason: `{reason}`");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, $"Banned `{victim.Name}` until `{expires}`. Reason: `{reason}`");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
88
SkyBot/Commands/Mod/Bans.cs
Normal file
88
SkyBot/Commands/Mod/Bans.cs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Text;
|
||||||
|
using SkyBot.Helpers;
|
||||||
|
using SkyBot.Models;
|
||||||
|
using Valour.Sdk.Models;
|
||||||
|
using Valour.Shared.Authorization;
|
||||||
|
using Valour.Shared.Models;
|
||||||
|
|
||||||
|
namespace SkyBot.Commands
|
||||||
|
{
|
||||||
|
public class GetBans : ICommand
|
||||||
|
{
|
||||||
|
public string Name => "bans";
|
||||||
|
public string[] Aliases => [""];
|
||||||
|
public string Description => "Lists all bans in the planet.";
|
||||||
|
public string Section => "Mod";
|
||||||
|
public string Usage => "bans [page]";
|
||||||
|
|
||||||
|
private const int PageSize = 10;
|
||||||
|
|
||||||
|
public async Task Execute(CommandContext ctx)
|
||||||
|
{
|
||||||
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
|
Planet planet = ctx.Planet;
|
||||||
|
string[] args = ctx.Args;
|
||||||
|
PlanetMember member = ctx.Member;
|
||||||
|
|
||||||
|
if (channelCache.TryGetValue(channelId, out var channel))
|
||||||
|
{
|
||||||
|
if (!PermissionHelper.HasPerm(member, [PlanetPermissions.Ban]))
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "You don't have permission to use this command.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int page = 1;
|
||||||
|
if (args.Length > 0 && int.TryParse(args[0], out int parsedPage))
|
||||||
|
page = parsedPage;
|
||||||
|
|
||||||
|
int skip = (page - 1) * PageSize;
|
||||||
|
|
||||||
|
var queryResult = await planet.Node.PostAsyncWithResponse<QueryResponse<PlanetBan>>(
|
||||||
|
$"api/planets/{planet.Id}/bans/query",
|
||||||
|
new { skip, take = PageSize, options = new { } }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!queryResult.Success || queryResult.Data?.Items == null)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Failed to fetch bans.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!queryResult.Data.Items.Any())
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "No bans found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int totalPages = (int)Math.Ceiling(queryResult.Data.TotalCount / (double)PageSize);
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine($"**Bans** (Page {page}/{totalPages}):");
|
||||||
|
|
||||||
|
IEnumerable<PlanetBan> activeBans = queryResult.Data.Items.Where(b => b.Permanent || b.TimeExpires > DateTime.UtcNow);
|
||||||
|
|
||||||
|
if (!activeBans.Any())
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "No active bans found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var ban in activeBans)
|
||||||
|
{
|
||||||
|
var user = await ctx.Client.UserService.FetchUserAsync(ban.TargetId);
|
||||||
|
string username = user?.NameAndTag ?? "Unknown";
|
||||||
|
string expires = ban.TimeExpires.HasValue
|
||||||
|
? $"{ban.TimeExpires}"
|
||||||
|
: "Never";
|
||||||
|
sb.AppendLine($"**{username}** `{user?.Id}` - {ban.Reason} (Expires: `{expires}`)");
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.AppendLine($"\nUse `{Config.Prefix}bans <page>` to see more.");
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, sb.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,26 +11,66 @@ namespace SkyBot.Commands
|
|||||||
public string Name => "kick";
|
public string Name => "kick";
|
||||||
public string[] Aliases => [];
|
public string[] Aliases => [];
|
||||||
public string Description => "Kicks a user from the planet.";
|
public string Description => "Kicks a user from the planet.";
|
||||||
public string Section => "mod";
|
public string Section => "Mod";
|
||||||
public string Usage => "kick <user> [reason]";
|
public string Usage => "kick <user> [reason]";
|
||||||
|
|
||||||
public async Task Execute(CommandContext ctx)
|
public async Task Execute(CommandContext ctx)
|
||||||
{
|
{
|
||||||
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
long channelId = ctx.ChannelId;
|
long channelId = ctx.ChannelId;
|
||||||
|
Planet planet = ctx.Planet;
|
||||||
|
Message message = ctx.Message;
|
||||||
|
string[] args = ctx.Args;
|
||||||
PlanetMember member = ctx.Member;
|
PlanetMember member = ctx.Member;
|
||||||
|
PlanetMember bot = await planet.FetchMemberByUserAsync(ctx.Client.Me.Id);
|
||||||
|
|
||||||
if (channelCache.TryGetValue(channelId, out var channel))
|
if (channelCache.TryGetValue(channelId, out var channel))
|
||||||
{
|
{
|
||||||
if (!PermissionHelper.HasPermAsync(member, [PlanetPermissions.Kick]).Result)
|
if (!PermissionHelper.HasPerm(member, [PlanetPermissions.Kick]))
|
||||||
{
|
{
|
||||||
await MessageHelper.ReplyAsync(ctx, channel, $"You don't have permission to use this command.");
|
await MessageHelper.ReplyAsync(ctx, channel, $"You don't have permission to use this command.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string message = $"Work in progress...";
|
if (!PermissionHelper.HasPerm(bot, [PlanetPermissions.Kick]))
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, $"I don't have permission to kick members.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await MessageHelper.ReplyAsync(ctx, channel, message);
|
if (!message.Mentions.Any() && args.Length < 2)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Please mention someone or user their id.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long targetId;
|
||||||
|
if (message.Mentions.Any())
|
||||||
|
{
|
||||||
|
targetId = message.Mentions.First().TargetId;
|
||||||
|
}
|
||||||
|
else if (!long.TryParse(args[1], out targetId))
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Invalid member ID.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PlanetMember victim = await planet.FetchMemberAsync(targetId);
|
||||||
|
|
||||||
|
if (victim == null)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Could not find that member.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string reason = args.Length > 1 && !message.Mentions.Any()
|
||||||
|
? string.Join(" ", args[2..])
|
||||||
|
: args.Length > 1
|
||||||
|
? string.Join(" ", args[1..])
|
||||||
|
: "No reason provided.";
|
||||||
|
|
||||||
|
await victim.DeleteAsync();
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, $"Kicked {victim.Name}. Reason: {reason}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
107
SkyBot/Commands/Mod/Unban.cs
Normal file
107
SkyBot/Commands/Mod/Unban.cs
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using SkyBot.Helpers;
|
||||||
|
using SkyBot.Models;
|
||||||
|
using Valour.Sdk.Models;
|
||||||
|
using Valour.Shared;
|
||||||
|
using Valour.Shared.Authorization;
|
||||||
|
using Valour.Shared.Models;
|
||||||
|
|
||||||
|
namespace SkyBot.Commands
|
||||||
|
{
|
||||||
|
public class Unban : ICommand
|
||||||
|
{
|
||||||
|
public string Name => "unban";
|
||||||
|
public string[] Aliases => [];
|
||||||
|
public string Description => "Unbans a user from the planet.";
|
||||||
|
public string Section => "Mod";
|
||||||
|
public string Usage => "unban <id>";
|
||||||
|
|
||||||
|
// public async Task Execute(CommandContext ctx)
|
||||||
|
// {
|
||||||
|
// ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
// long channelId = ctx.ChannelId;
|
||||||
|
|
||||||
|
// if (channelCache.TryGetValue(channelId, out var channel))
|
||||||
|
// {
|
||||||
|
// await MessageHelper.ReplyAsync(ctx, channel, "Unbanning is currently unavailable due to a Valour server bug.");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
public async Task Execute(CommandContext ctx)
|
||||||
|
{
|
||||||
|
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||||
|
long channelId = ctx.ChannelId;
|
||||||
|
Planet planet = ctx.Planet;
|
||||||
|
Message message = ctx.Message;
|
||||||
|
string[] args = ctx.Args;
|
||||||
|
PlanetMember member = ctx.Member;
|
||||||
|
PlanetMember bot = await planet.FetchMemberByUserAsync(ctx.Client.Me.Id);
|
||||||
|
|
||||||
|
if (channelCache.TryGetValue(channelId, out var channel))
|
||||||
|
{
|
||||||
|
if (!PermissionHelper.HasPerm(member, [PlanetPermissions.Ban]))
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "You don't have permission to use this command.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PermissionHelper.HasPerm(bot, [PlanetPermissions.Ban]))
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "I don't have permission to unban members.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Length < 1)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Please provide a user ID.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!long.TryParse(args[0], out long targetUserId))
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Invalid user ID.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlanetBan? ban = null;
|
||||||
|
int skip = 0;
|
||||||
|
int take = 50;
|
||||||
|
|
||||||
|
while (ban == null)
|
||||||
|
{
|
||||||
|
var queryResult = await planet.Node.PostAsyncWithResponse<QueryResponse<PlanetBan>>(
|
||||||
|
$"api/planets/{planet.Id}/bans/query",
|
||||||
|
new {skip, take, options = new { }}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!queryResult.Success || queryResult.Data?.Items == null || !queryResult.Data.Items.Any())
|
||||||
|
break;
|
||||||
|
|
||||||
|
ban = queryResult.Data.Items.FirstOrDefault(b => b.TargetId == targetUserId && (b.Permanent || b.TimeExpires > DateTime.UtcNow));
|
||||||
|
|
||||||
|
if (queryResult.Data.Items.Count < take)
|
||||||
|
break;
|
||||||
|
|
||||||
|
skip += take;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ban == null)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Could not find a ban for that user.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ban.TimeExpires = DateTime.UtcNow.AddSeconds(-1);
|
||||||
|
TaskResult<PlanetBan> result = await planet.Node.PutAsyncWithResponse<PlanetBan>($"api/bans/{ban.Id}", ban);
|
||||||
|
if (!result.Success)
|
||||||
|
{
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, "Failed to unban.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
User user = await ctx.Client.UserService.FetchUserAsync(targetUserId);
|
||||||
|
await MessageHelper.ReplyAsync(ctx, channel, $"Unbanned `{user?.NameAndTag ?? targetUserId.ToString()}`.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using Valour.Sdk.Models;
|
|
||||||
|
|
||||||
namespace SkyBot.Helpers
|
|
||||||
{
|
|
||||||
public static class MentionHelper
|
|
||||||
{
|
|
||||||
public static string Mention(this PlanetMember member) => $"«@m-{member.Id}»";
|
|
||||||
public static string Mention(this User user) => $"«@u-{user.Id}»";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +1,53 @@
|
|||||||
using SkyBot.Models;
|
using SkyBot.Models;
|
||||||
using Valour.Sdk.Models;
|
using Valour.Sdk.Models;
|
||||||
|
using Valour.Shared;
|
||||||
|
|
||||||
public static class MessageHelper
|
namespace SkyBot.Helpers
|
||||||
{
|
{
|
||||||
public static async Task ReplyAsync(CommandContext ctx, Channel channel, string content)
|
public static class MessageHelper
|
||||||
{
|
{
|
||||||
long? replyToId = ctx.Message.ReplyToId.HasValue ? ctx.Message.ReplyToId : ctx.Message.Id;
|
|
||||||
|
|
||||||
var msg = new Message(ctx.Client)
|
public static string Mention(this PlanetMember member) => $"«@m-{member.Id}»";
|
||||||
|
public static string Mention(this User user) => $"«@u-{user.Id}»";
|
||||||
|
public static string ToTitleCase(this string str) => System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str);
|
||||||
|
public static async Task<TaskResult<Message>> ReplyAsync(CommandContext ctx, Channel channel, string content)
|
||||||
{
|
{
|
||||||
Content = content,
|
long? replyToId = ctx.Message.ReplyToId.HasValue ? ctx.Message.ReplyToId : ctx.Message.Id;
|
||||||
ChannelId = channel.Id,
|
|
||||||
PlanetId = ctx.Planet.Id,
|
|
||||||
AuthorUserId = ctx.Client.Me.Id,
|
|
||||||
AuthorMemberId = channel.Planet?.MyMember.Id,
|
|
||||||
ReplyToId = replyToId,
|
|
||||||
Fingerprint = Guid.NewGuid().ToString()
|
|
||||||
};
|
|
||||||
await ctx.Client.MessageService.SendMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ToTitleCase(this string str) => System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str);
|
var msg = new Message(ctx.Client)
|
||||||
|
{
|
||||||
|
Content = content,
|
||||||
|
ChannelId = channel.Id,
|
||||||
|
PlanetId = ctx.Planet.Id,
|
||||||
|
AuthorUserId = ctx.Client.Me.Id,
|
||||||
|
AuthorMemberId = channel.Planet?.MyMember.Id,
|
||||||
|
ReplyToId = replyToId,
|
||||||
|
Fingerprint = Guid.NewGuid().ToString()
|
||||||
|
};
|
||||||
|
return await ctx.Client.MessageService.SendMessage(msg);
|
||||||
|
}
|
||||||
|
public static async Task<TaskResult<Message>> EditAsync(Channel channel, Message message, string content)
|
||||||
|
{
|
||||||
|
message.Content = content;
|
||||||
|
return await channel.Planet.Node.PutAsyncWithResponse<Message>($"api/messages/{message.Id}", message);
|
||||||
|
}
|
||||||
|
public static DateTime? ParseDuration(string input)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(input)) return null;
|
||||||
|
|
||||||
|
var unit = input[^1];
|
||||||
|
if (!int.TryParse(input[..^1], out int value)) return null;
|
||||||
|
|
||||||
|
return unit switch
|
||||||
|
{
|
||||||
|
'm' => DateTime.UtcNow.AddMinutes(value),
|
||||||
|
'h' => DateTime.UtcNow.AddHours(value),
|
||||||
|
'd' => DateTime.UtcNow.AddDays(value),
|
||||||
|
'w' => DateTime.UtcNow.AddDays(value * 7),
|
||||||
|
'M' => DateTime.UtcNow.AddMonths(value),
|
||||||
|
'y' => DateTime.UtcNow.AddYears(value),
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ namespace SkyBot.Helpers
|
|||||||
{
|
{
|
||||||
public static class PermissionHelper
|
public static class PermissionHelper
|
||||||
{
|
{
|
||||||
public static async Task<bool> HasPermAsync(PlanetMember member, PlanetPermission[] permissions, bool requireAll = false)
|
public static bool HasPerm(PlanetMember member, PlanetPermission[] permissions, bool requireAll = false)
|
||||||
{
|
{
|
||||||
if (member == null) return false;
|
if (member == null) return false;
|
||||||
if (member.HasPermission(PlanetPermissions.FullControl)) return true;
|
if (member.HasPermission(PlanetPermissions.FullControl)) return true;
|
||||||
@@ -16,7 +16,7 @@ namespace SkyBot.Helpers
|
|||||||
: permissions.Any(permission => member.HasPermission(permission));
|
: permissions.Any(permission => member.HasPermission(permission));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<bool> IsOwner(PlanetMember member)
|
public static bool IsOwner(PlanetMember member)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (member == null) return false;
|
if (member == null) return false;
|
||||||
|
|||||||
@@ -29,23 +29,25 @@ namespace SkyBot.Services.Messages
|
|||||||
string command = parts[0].ToLower();
|
string command = parts[0].ToLower();
|
||||||
string[] args = parts[1..];
|
string[] args = parts[1..];
|
||||||
|
|
||||||
|
CommandContext ctx = new CommandContext
|
||||||
|
{
|
||||||
|
ChannelCache = channelCache,
|
||||||
|
ChannelId = channelId,
|
||||||
|
Member = member,
|
||||||
|
Planet = message.Planet,
|
||||||
|
Args = args,
|
||||||
|
Message = message,
|
||||||
|
Client = client
|
||||||
|
};
|
||||||
|
|
||||||
if (CommandRegistry.Commands.TryGetValue(command, out var handler))
|
if (CommandRegistry.Commands.TryGetValue(command, out var handler))
|
||||||
{
|
{
|
||||||
await handler.Execute(new CommandContext
|
await handler.Execute(ctx);
|
||||||
{
|
|
||||||
ChannelCache = channelCache,
|
|
||||||
ChannelId = channelId,
|
|
||||||
Member = member,
|
|
||||||
Planet = message.Planet,
|
|
||||||
Args = args,
|
|
||||||
Message = message,
|
|
||||||
Client = client
|
|
||||||
});
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
if (channelCache.TryGetValue(channelId, out var channel))
|
if (channelCache.TryGetValue(channelId, out var channel))
|
||||||
{
|
{
|
||||||
await channel.SendMessageAsync($"{MentionHelper.Mention(member)} Unknown command.");
|
await MessageHelper.ReplyAsync(ctx, channel, $"Unknown command `{command}`.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace SkyBot
|
|||||||
private readonly ValourClient _client;
|
private readonly ValourClient _client;
|
||||||
private readonly ConcurrentDictionary<long, Channel> _channelCache = new();
|
private readonly ConcurrentDictionary<long, Channel> _channelCache = new();
|
||||||
private readonly ConcurrentDictionary<long, bool> _initializedPlanets = new();
|
private readonly ConcurrentDictionary<long, bool> _initializedPlanets = new();
|
||||||
|
public static DateTime StartTime;
|
||||||
|
|
||||||
public SkyBot()
|
public SkyBot()
|
||||||
{
|
{
|
||||||
@@ -19,6 +20,7 @@ namespace SkyBot
|
|||||||
|
|
||||||
public async Task StartAsync()
|
public async Task StartAsync()
|
||||||
{
|
{
|
||||||
|
StartTime = DateTime.UtcNow;
|
||||||
await BotService.InitializeBotAsync(_client, _channelCache, _initializedPlanets);
|
await BotService.InitializeBotAsync(_client, _channelCache, _initializedPlanets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,6 +34,7 @@ namespace SkyBot
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await new SkyBot().StartAsync();
|
await new SkyBot().StartAsync();
|
||||||
|
|
||||||
|
|
||||||
Console.WriteLine("Ready and listening...");
|
Console.WriteLine("Ready and listening...");
|
||||||
await Task.Delay(Timeout.Infinite);
|
await Task.Delay(Timeout.Infinite);
|
||||||
|
|||||||
Reference in New Issue
Block a user