yes.
This commit is contained in:
@@ -7,7 +7,7 @@ using Valour.Shared;
|
||||
|
||||
namespace SkyBot.Commands
|
||||
{
|
||||
public class Test : ICommand
|
||||
public class Edit : ICommand
|
||||
{
|
||||
public string Name => "edit";
|
||||
public string[] Aliases => [];
|
||||
@@ -29,6 +29,7 @@ namespace SkyBot.Commands
|
||||
if(!PermissionHelper.IsOwner(member))
|
||||
{
|
||||
await MessageHelper.ReplyAsync(ctx, channel, "This is a Dev only command.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.ReplyToId == null)
|
||||
103
SkyBot/Commands/Mod/SetWelcome.cs
Normal file
103
SkyBot/Commands/Mod/SetWelcome.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System.Collections.Concurrent;
|
||||
using SkyBot.Helpers;
|
||||
using SkyBot.Models;
|
||||
using SkyBot.Services;
|
||||
using Valour.Sdk.Models;
|
||||
using Valour.Shared.Authorization;
|
||||
using Valour.Shared.Models;
|
||||
|
||||
namespace SkyBot.Commands
|
||||
{
|
||||
public class SetWelcome : ICommand
|
||||
{
|
||||
public string Name => "setwelcome";
|
||||
public string[] Aliases => [];
|
||||
public string Description => "Sets the welcome channel, message or active.";
|
||||
public string Section => "Mod";
|
||||
public string Usage => "set <channel|message|active [value]";
|
||||
|
||||
public async Task Execute(CommandContext ctx)
|
||||
{
|
||||
ConcurrentDictionary<long, Channel> channelCache = ctx.ChannelCache;
|
||||
long channelId = ctx.ChannelId;
|
||||
Message message = ctx.Message;
|
||||
PlanetMember member = ctx.Member;
|
||||
Planet planet = ctx.Planet;
|
||||
string[] args = ctx.Args;
|
||||
|
||||
if (!channelCache.TryGetValue(channelId, out var channel)) return;
|
||||
|
||||
if (!PermissionHelper.HasPerm(member, [PlanetPermissions.Manage]) && !PermissionHelper.IsOwner(member))
|
||||
{
|
||||
await MessageHelper.ReplyAsync(ctx, channel, "You don't have permission to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Length == 0)
|
||||
{
|
||||
await MessageHelper.ReplyAsync(ctx, channel, "Please specify `channel` or `message`.");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (args[0].ToLower())
|
||||
{
|
||||
case "channel":
|
||||
case "c":
|
||||
long targetChannelId;
|
||||
if (message.Mentions != null && message.Mentions.Any(m => m.Type == MentionType.Channel)) {targetChannelId = message.Mentions.First(m => m.Type == MentionType.Channel).TargetId;}
|
||||
else if (args.Length > 1 && long.TryParse(args[1], out long parsedChannelId)) {targetChannelId = parsedChannelId;}
|
||||
else {targetChannelId = channelId;}
|
||||
|
||||
if (!channelCache.ContainsKey(targetChannelId)) {await MessageHelper.ReplyAsync(ctx, channel, "Could not find that channel."); return;}
|
||||
|
||||
await WelcomeService.SetWelcomeChannel(planet.Id, targetChannelId);
|
||||
await MessageHelper.ReplyAsync(ctx, channel, $"Welcome channel set to «@c-{targetChannelId}».");
|
||||
break;
|
||||
|
||||
case "message":
|
||||
case "m":
|
||||
if (args.Length < 2)
|
||||
{
|
||||
await MessageHelper.ReplyAsync(ctx, channel, "Please provide a message. Valid variables: {username} {nickname} {fulluser} {mention} {id}");
|
||||
return;
|
||||
}
|
||||
string msg = string.Join(" ", args[1..]);
|
||||
await WelcomeService.SetWelcomeMessage( planet.Id, msg);
|
||||
await MessageHelper.ReplyAsync(ctx, channel, $"Welcome message set to: `{msg}`");
|
||||
break;
|
||||
|
||||
case "active":
|
||||
case "a":
|
||||
if (args.Length < 2)
|
||||
{
|
||||
await MessageHelper.ReplyAsync(ctx, channel, "Please provide a value. Use `true`, `false`, or `toggle`.");
|
||||
return;
|
||||
}
|
||||
string value = args[1].ToLower();
|
||||
if (value != "toggle" && value != "true" && value != "false")
|
||||
{
|
||||
await MessageHelper.ReplyAsync(ctx, channel, "Invalid value. Use `true`, `false`, `toggle`");
|
||||
return;
|
||||
}
|
||||
|
||||
if (value == "toggle")
|
||||
{
|
||||
var toggle = await WelcomeService.SetActive(planet.Id);
|
||||
await MessageHelper.ReplyAsync(ctx, channel, toggle.Value ? "Welcome messages enabled." : "Welcome messages disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
bool.TryParse(value, out var active);
|
||||
|
||||
await WelcomeService.SetActive(planet.Id, active);
|
||||
await MessageHelper.ReplyAsync(ctx, channel, active ? "Welcome messages enabled." : "Welcome messages disabled.");
|
||||
break;
|
||||
|
||||
default:
|
||||
await MessageHelper.ReplyAsync(ctx, channel, "Invalid option. Use `channel`, `message` or `active`.");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
32
SkyBot/Models/DatabaseHelper.cs
Normal file
32
SkyBot/Models/DatabaseHelper.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
||||
namespace SkyBot.Helpers
|
||||
{
|
||||
public static class DatabaseHelper
|
||||
{
|
||||
private const string ConnectionString = "Data Source=database.db";
|
||||
|
||||
public static SqliteConnection GetConnection()
|
||||
{
|
||||
SqliteConnection connection = new SqliteConnection(ConnectionString);
|
||||
connection.Open();
|
||||
return connection;
|
||||
}
|
||||
|
||||
public static async Task InitializeAsync()
|
||||
{
|
||||
using SqliteConnection connection = GetConnection();
|
||||
using SqliteCommand cmd = connection.CreateCommand();
|
||||
cmd.CommandText = @"
|
||||
CREATE TABLE IF NOT EXISTS WelcomeConfigs (
|
||||
PlanetId INTEGER PRIMARY KEY,
|
||||
ChannelId INTEGER NOT NULL DEFAULT 0,
|
||||
Message TEXT NOT NULL DEFAULT 'Welcome to the planet, {username}!',
|
||||
Active INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
";
|
||||
await cmd.ExecuteNonQueryAsync();
|
||||
Console.WriteLine("Database initialized.");
|
||||
}
|
||||
}
|
||||
}
|
||||
7
SkyBot/Models/WelcomeConfig.cs
Normal file
7
SkyBot/Models/WelcomeConfig.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
public class WelcomeConfig
|
||||
{
|
||||
public long PlanetId { get; set; }
|
||||
public long ChannelId { get; set; }
|
||||
public string Message { get; set; } = "Welcome to the planet, {username}!";
|
||||
public bool Active { get; set; } = false;
|
||||
}
|
||||
@@ -5,10 +5,14 @@ using SkyBot.Models;
|
||||
using Valour.Sdk.Client;
|
||||
using Valour.Sdk.Models;
|
||||
|
||||
|
||||
|
||||
namespace SkyBot.Services.Messages
|
||||
{
|
||||
public static class Create
|
||||
{
|
||||
private static readonly ConcurrentDictionary<long, DateTime> _cooldowns = new();
|
||||
private static readonly TimeSpan _cooldown = TimeSpan.FromSeconds(2);
|
||||
public static async Task MessageAsync(
|
||||
ValourClient client,
|
||||
ConcurrentDictionary<long, Channel> channelCache,
|
||||
@@ -40,6 +44,11 @@ namespace SkyBot.Services.Messages
|
||||
Client = client
|
||||
};
|
||||
|
||||
if (_cooldowns.TryGetValue(message.AuthorUserId, out var lastUsed) && DateTime.UtcNow - lastUsed < _cooldown)
|
||||
return;
|
||||
|
||||
_cooldowns[message.AuthorUserId] = DateTime.UtcNow;
|
||||
|
||||
if (CommandRegistry.Commands.TryGetValue(command, out var handler))
|
||||
{
|
||||
await handler.Execute(ctx);
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
using System.Collections.Concurrent;
|
||||
using SkyBot.Services;
|
||||
using Valour.Sdk.Client;
|
||||
using Valour.Sdk.ModelLogic;
|
||||
using Valour.Sdk.Models;
|
||||
using Valour.Sdk.Models.Messages.Embeds;
|
||||
|
||||
|
||||
namespace SkyBot.Services
|
||||
{
|
||||
public static class PlanetService
|
||||
{
|
||||
private static readonly DateTime _startTime = DateTime.UtcNow;
|
||||
public static async Task InitializePlanetsAsync(
|
||||
ValourClient client,
|
||||
ConcurrentDictionary<long, Channel> channelCache,
|
||||
@@ -19,15 +18,27 @@ namespace SkyBot.Services
|
||||
.Select(async planet =>
|
||||
{
|
||||
Console.WriteLine($"Initializing Planet: {planet.Name}");
|
||||
|
||||
await planet.EnsureReadyAsync();
|
||||
await planet.FetchInitialDataAsync();
|
||||
await ChannelService.InitializeChannelsAsync(channelCache, planet);
|
||||
|
||||
planet.Channels.Changed += async (channelEvent) => {
|
||||
planet.Channels.Changed += async _ =>
|
||||
{
|
||||
await ChannelService.InitializeChannelsAsync(channelCache, planet);
|
||||
};
|
||||
});
|
||||
|
||||
planet.Members.Changed += async memberEvent =>
|
||||
{
|
||||
if ((DateTime.UtcNow - _startTime).TotalSeconds < 10) return;
|
||||
if (memberEvent is ModelAddedEvent<PlanetMember> addedEvent)
|
||||
{
|
||||
await WelcomeService.OnMemberJoin(addedEvent.Model, channelCache);
|
||||
}
|
||||
};
|
||||
|
||||
initializedPlanets.TryAdd(planet.Id, true);
|
||||
});
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
}
|
||||
|
||||
137
SkyBot/Services/WelcomeService.cs
Normal file
137
SkyBot/Services/WelcomeService.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using SkyBot.Helpers;
|
||||
using Valour.Sdk.Models;
|
||||
|
||||
namespace SkyBot.Services
|
||||
{
|
||||
public static class WelcomeService
|
||||
{
|
||||
private static readonly ConcurrentDictionary<long, WelcomeConfig> _cache = new();
|
||||
|
||||
public static async Task InitializeAsync()
|
||||
{
|
||||
using SqliteConnection connection = DatabaseHelper.GetConnection();
|
||||
using SqliteCommand cmd = connection.CreateCommand();
|
||||
cmd.CommandText = "SELECT * FROM WelcomeConfigs";
|
||||
using SqliteDataReader reader = await cmd.ExecuteReaderAsync();
|
||||
while (await reader.ReadAsync())
|
||||
{
|
||||
var config = new WelcomeConfig
|
||||
{
|
||||
PlanetId = (long)reader["PlanetId"],
|
||||
ChannelId = (long)reader["ChannelId"],
|
||||
Message = (string)reader["Message"],
|
||||
Active = (long)reader["Active"] == 1
|
||||
};
|
||||
_cache[config.PlanetId] = config;
|
||||
}
|
||||
Console.WriteLine("WelcomeService initialized.");
|
||||
Console.WriteLine($"Loaded {_cache.Count} welcome configs from database.");
|
||||
}
|
||||
|
||||
public static async Task OnMemberJoin(PlanetMember member, ConcurrentDictionary<long, Channel> channelCache)
|
||||
{
|
||||
if (!_cache.TryGetValue(member.PlanetId, out var config)) { Console.WriteLine("No config found"); return; }
|
||||
if (!config.Active) { Console.WriteLine("Not active"); return; }
|
||||
|
||||
Channel? channel = null;
|
||||
|
||||
if (config.ChannelId != 0 && channelCache.TryGetValue(config.ChannelId, out var configChannel))
|
||||
{
|
||||
channel = configChannel;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel = channelCache.Values.FirstOrDefault(c => c.PlanetId == member.PlanetId && c.IsDefault);
|
||||
}
|
||||
|
||||
if (channel == null) { Console.WriteLine("No channel found"); return; }
|
||||
|
||||
|
||||
string message = config.Message
|
||||
.Replace("{username}", member.Name)
|
||||
.Replace("{fulluser}", member.User.NameAndTag)
|
||||
.Replace("{nickname}", string.IsNullOrWhiteSpace(member.Nickname) ? member.Name : member.Nickname)
|
||||
.Replace("{mention}", MessageHelper.Mention(member))
|
||||
.Replace("{id}", $"{member.Id}");
|
||||
|
||||
await channel.SendMessageAsync(message);
|
||||
}
|
||||
|
||||
public static async Task SetWelcomeChannel(long planetId, long channelId)
|
||||
{
|
||||
using SqliteConnection connection = DatabaseHelper.GetConnection();
|
||||
using SqliteCommand cmd = connection.CreateCommand();
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO WelcomeConfigs (PlanetId, ChannelId) VALUES ($planetId, $channelId)
|
||||
ON CONFLICT(PlanetId) DO UPDATE SET ChannelId = $channelId;
|
||||
";
|
||||
cmd.Parameters.AddWithValue("$planetId", planetId);
|
||||
cmd.Parameters.AddWithValue("$channelId", channelId);
|
||||
await cmd.ExecuteNonQueryAsync();
|
||||
|
||||
if (_cache.TryGetValue(planetId, out var config))
|
||||
{
|
||||
config.ChannelId = channelId;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cache[planetId] = new WelcomeConfig{PlanetId = planetId, ChannelId = channelId};
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task SetWelcomeMessage(long planetId, string message)
|
||||
{
|
||||
using SqliteConnection connection = DatabaseHelper.GetConnection();
|
||||
using SqliteCommand cmd = connection.CreateCommand();
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO WelcomeConfigs (PlanetId, Message) VALUES ($planetId, $message)
|
||||
ON CONFLICT(PlanetId) DO UPDATE SET Message = $message;
|
||||
";
|
||||
cmd.Parameters.AddWithValue("$planetId", planetId);
|
||||
cmd.Parameters.AddWithValue("$message", message);
|
||||
await cmd.ExecuteNonQueryAsync();
|
||||
|
||||
if (_cache.TryGetValue(planetId, out var config))
|
||||
{
|
||||
config.Message = message;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cache[planetId] = new WelcomeConfig{PlanetId = planetId, Message = message};
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task SetActive(long planetId, bool active)
|
||||
{
|
||||
using SqliteConnection connection = DatabaseHelper.GetConnection();
|
||||
using SqliteCommand cmd = connection.CreateCommand();
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO WelcomeConfigs (PlanetId, Active) VALUES ($planetId, $active)
|
||||
ON CONFLICT(PlanetId) DO UPDATE SET Active = $active;
|
||||
";
|
||||
cmd.Parameters.AddWithValue("$planetId", planetId);
|
||||
cmd.Parameters.AddWithValue("$active", active ? 1 : 0);
|
||||
await cmd.ExecuteNonQueryAsync();
|
||||
|
||||
if (_cache.TryGetValue(planetId, out var config))
|
||||
{
|
||||
config.Active = active;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cache[planetId] = new WelcomeConfig{PlanetId = planetId, Active = active};
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<bool?> SetActive(long planetId)
|
||||
{
|
||||
if (!_cache.TryGetValue(planetId, out var config)) return null;
|
||||
|
||||
bool newActive = !config.Active;
|
||||
await SetActive(planetId, newActive);
|
||||
return newActive;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using Valour.Sdk.Client;
|
||||
using Valour.Sdk.Models;
|
||||
using SkyBot.Services;
|
||||
using System.Collections.Concurrent;
|
||||
using SkyBot.Helpers;
|
||||
|
||||
namespace SkyBot
|
||||
{
|
||||
@@ -21,6 +22,8 @@ namespace SkyBot
|
||||
public async Task StartAsync()
|
||||
{
|
||||
StartTime = DateTime.UtcNow;
|
||||
await DatabaseHelper.InitializeAsync();
|
||||
await WelcomeService.InitializeAsync();
|
||||
await BotService.InitializeBotAsync(_client, _channelCache, _initializedPlanets);
|
||||
}
|
||||
}
|
||||
@@ -35,7 +38,6 @@ namespace SkyBot
|
||||
{
|
||||
await new SkyBot().StartAsync();
|
||||
|
||||
|
||||
Console.WriteLine("Ready and listening...");
|
||||
await Task.Delay(Timeout.Infinite);
|
||||
} catch (Exception ex)
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>0.2.0.0</Version>
|
||||
<Version>0.2.1.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DotNetEnv" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="10.0.5" />
|
||||
<PackageReference Include="Valour.Sdk" Version="0.5.19" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user