Merge branch 'develop' into 'master'
Develop See merge request discord-bots/chaosbot!1
This commit is contained in:
commit
3ea10e5395
@ -6,6 +6,7 @@ using System.Text;
|
||||
using ChaosBot.Discord.PreConditions;
|
||||
using ChaosBot.Models;
|
||||
using ChaosBot.Repositories;
|
||||
using ChaosBot.Services;
|
||||
using Discord;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
@ -79,6 +80,8 @@ namespace ChaosBot.Discord.Modules.Admin
|
||||
try
|
||||
{
|
||||
if ((key != null) && (value != null) )
|
||||
{
|
||||
if(await RestrictedConfig.IsAllowed(key))
|
||||
{
|
||||
using (ChaosbotContext dbContext = new ChaosbotContext())
|
||||
{
|
||||
@ -94,6 +97,7 @@ namespace ChaosBot.Discord.Modules.Admin
|
||||
await ConfigGet(key, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await ConfigHelp();
|
||||
@ -111,7 +115,7 @@ namespace ChaosBot.Discord.Modules.Admin
|
||||
{
|
||||
try
|
||||
{
|
||||
if (key != null)
|
||||
if ((key != null) && (await RestrictedConfig.IsAllowed(key)))
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
EmbedBuilder embed = new EmbedBuilder();
|
||||
|
||||
110
ChaosBot/Discord/Modules/Admin/RankCheck.cs
Normal file
110
ChaosBot/Discord/Modules/Admin/RankCheck.cs
Normal file
@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Antlr4.Runtime.Misc;
|
||||
using ChaosBot.Discord.PreConditions;
|
||||
using ChaosBot.Lodestone;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
|
||||
namespace ChaosBot.Discord.Modules.Admin
|
||||
{
|
||||
public class RankCheck : ModuleBase
|
||||
{
|
||||
private static readonly ILogger _logger = Program.Logger;
|
||||
|
||||
[Command("rankCheck")]
|
||||
[Alias("rc")]
|
||||
[CheckCommandPerm("Admin")]
|
||||
public async Task rankCheck()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<LodestoneRank> ranks = await GetRank();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
var embed = new EmbedBuilder();
|
||||
|
||||
embed.WithColor(new Color(255, 255, 0));
|
||||
embed.Title = $"Pending Promotions";
|
||||
sb.AppendLine();
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendLine($"**Recruits Pending Promotion to Initiate**");
|
||||
if(ranks.FindAll(x => x.IngameRole == ERole.Recruit).Any())
|
||||
{
|
||||
foreach (var lsID in ranks.FindAll(x => x.IngameRole == ERole.Recruit))
|
||||
{
|
||||
if ((lsID.ShouldBeRole != lsID.IngameRole) && (lsID.ShouldBeRole != null))
|
||||
sb.AppendLine(string.Format("{0} {1}", lsID.DisplayName, $"linked to <@{lsID.DiscordId}>"));
|
||||
}
|
||||
}
|
||||
else
|
||||
sb.AppendLine($"None at this time.");
|
||||
|
||||
sb.AppendLine();
|
||||
sb.AppendLine($"**Initiates Pending Promotion to Member**");
|
||||
if (ranks.FindAll(x => x.IngameRole == ERole.Initiate).Any())
|
||||
{
|
||||
foreach (var lsID in ranks.FindAll(x => x.IngameRole == ERole.Initiate))
|
||||
{
|
||||
if ((lsID.ShouldBeRole != lsID.IngameRole) && (lsID.ShouldBeRole != null))
|
||||
sb.AppendLine(string.Format("{0} {1}", lsID.DisplayName, $"linked to <@{lsID.DiscordId}>"));
|
||||
}
|
||||
}
|
||||
else
|
||||
sb.AppendLine($"None at this time.");
|
||||
|
||||
sb.AppendLine();
|
||||
sb.AppendLine($"Report Generated by {Context.User.Mention} at {DateTime.Now.ToString("dddd, dd MMMM yyyy h:mm tt")}.");
|
||||
|
||||
/*
|
||||
* Add the string to the Embed
|
||||
*/
|
||||
embed.Description = sb.ToString();
|
||||
|
||||
/*
|
||||
* Reply with the Embed created above
|
||||
*/
|
||||
await ReplyAsync(null, false, embed.Build());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"{MethodBase.GetCurrentMethod().ReflectedType.FullName}: Exception [{ex}] thrown, <[{ex.Message}]>.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<LodestoneRank>> GetRank()
|
||||
{
|
||||
string response = null;
|
||||
|
||||
try
|
||||
{
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
|
||||
|
||||
var result = await client.GetAsync("https://www.ffxivhelix.com/rapi/clogiclodestone/v1/users");
|
||||
result.EnsureSuccessStatusCode();
|
||||
|
||||
response = await result.Content.ReadAsStringAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(
|
||||
$"{MethodBase.GetCurrentMethod().ReflectedType.FullName}: Exception [{ex}] thrown, <[{ex.Message}]>.");
|
||||
}
|
||||
|
||||
return JsonConvert.DeserializeObject<List<LodestoneRank>>(JsonConvert.SerializeObject(JsonConvert.DeserializeObject<LodestoneRankApi>(response).Data));
|
||||
}
|
||||
}
|
||||
}
|
||||
49
ChaosBot/Discord/Modules/User/Info.cs
Normal file
49
ChaosBot/Discord/Modules/User/Info.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ChaosBot.Discord.PreConditions;
|
||||
using ChaosBot.Repositories;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using NLog;
|
||||
|
||||
namespace ChaosBot.Discord.Modules.User
|
||||
{
|
||||
public class Info : ModuleBase
|
||||
{
|
||||
private static readonly ILogger Logger = Program.Logger;
|
||||
|
||||
[Command("info")]
|
||||
[Alias("version")]
|
||||
[CheckCommandPerm("User")]
|
||||
public async Task ShowInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var embed = new EmbedBuilder();
|
||||
|
||||
embed.WithColor(new Color(255, 255, 0));
|
||||
embed.Title = $"Information {Program.AppSettingsHandler.GetValue<string>("Bot:Name")} v{Program.AppSettingsHandler.GetValue<string>("Bot:Version")}";
|
||||
sb.AppendLine($"Prefix: {ConfigurationRepository.GetValue<string>("Discord:Prefix", Context.Guild.Id)}");
|
||||
|
||||
/*
|
||||
* Add the string to the Embed
|
||||
*/
|
||||
embed.Description = sb.ToString();
|
||||
|
||||
/*
|
||||
* Reply with the Embed created above
|
||||
*/
|
||||
await ReplyAsync(null, false, embed.Build());
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Logger.Error(
|
||||
$"{MethodBase.GetCurrentMethod().ReflectedType.FullName}: Exception [{ex}] thrown, <[{ex.Message}]>.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -56,8 +56,15 @@ namespace ChaosBot.Discord.Services
|
||||
int argPos = 0;
|
||||
|
||||
string prefix = ConfigurationRepository.GetValue<string>("Discord:Prefix", context.Guild.Id, "!");
|
||||
if (!(message.HasMentionPrefix(_client.CurrentUser, ref argPos) || message.HasStringPrefix(prefix, ref argPos)))
|
||||
if (!(message.HasMentionPrefix(_client.CurrentUser, ref argPos) ||
|
||||
message.HasStringPrefix(prefix, ref argPos)))
|
||||
{
|
||||
ExperienceHandler.addXP(context.Guild.Id, context.User.Id);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Convert.ToBoolean(ConfigurationRepository.GetValue<string>("Experience:Commands", context.Guild.Id, "false")))
|
||||
ExperienceHandler.addXP(context.Guild.Id, context.User.Id);
|
||||
|
||||
await _commands.ExecuteAsync(context, argPos, _services);
|
||||
}
|
||||
|
||||
51
ChaosBot/Discord/Services/ExperienceHandler.cs
Normal file
51
ChaosBot/Discord/Services/ExperienceHandler.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using ChaosBot.Models;
|
||||
using ChaosBot.Repositories;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NLog;
|
||||
|
||||
namespace ChaosBot.Discord.Services
|
||||
{
|
||||
public class ExperienceHandler
|
||||
{
|
||||
private static readonly ILogger _logger = Program.Logger;
|
||||
|
||||
public static async void addXP(ulong DiscordGuildId, ulong DiscordUserId)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (ChaosbotContext dbContext = new ChaosbotContext())
|
||||
{
|
||||
IQueryable<Experience> ctxUser = dbContext.ExperiencePoints;
|
||||
IQueryable<Experience> usrXp = ctxUser
|
||||
.Where(p => p.DiscordGuildId.Equals(DiscordGuildId))
|
||||
.Where(p => p.DiscordUserId.Equals(DiscordUserId));
|
||||
|
||||
Experience usrNewXp;
|
||||
if (usrXp.Any())
|
||||
{
|
||||
usrNewXp = usrXp.First();
|
||||
usrNewXp.Amount = usrNewXp.Amount + Convert.ToUInt64(ConfigurationRepository.GetValue<string>("Experience:PerMsg", DiscordGuildId, "0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
usrNewXp = new Experience();
|
||||
usrNewXp.Amount = Convert.ToUInt64(ConfigurationRepository.GetValue<string>("Experience:PerMsg", DiscordGuildId, "0"));
|
||||
}
|
||||
usrNewXp.DiscordGuildId = DiscordGuildId;
|
||||
usrNewXp.DiscordUserId = DiscordUserId;
|
||||
|
||||
await dbContext.ExperiencePoints.Upsert(usrNewXp)
|
||||
.On(x => new { x.DiscordGuildId, x.DiscordUserId}).RunAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(
|
||||
$"{MethodBase.GetCurrentMethod().ReflectedType.FullName}: Exception [{ex}] thrown, <[{ex.Message}]>.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
155
ChaosBot/Lodestone/LodestoneRank.cs
Normal file
155
ChaosBot/Lodestone/LodestoneRank.cs
Normal file
@ -0,0 +1,155 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace ChaosBot.Lodestone
|
||||
{
|
||||
public partial class LodestoneRankApi
|
||||
{
|
||||
[JsonProperty("success")]
|
||||
public bool Success { get; set; }
|
||||
|
||||
[JsonProperty("error")]
|
||||
public object Error { get; set; }
|
||||
|
||||
[JsonProperty("data")]
|
||||
public List<LodestoneRank> Data { get; set; }
|
||||
}
|
||||
|
||||
public partial class LodestoneRank
|
||||
{
|
||||
[JsonProperty("lodestoneId")]
|
||||
[JsonConverter(typeof(ParseStringConverter))]
|
||||
public long LodestoneId { get; set; }
|
||||
|
||||
[JsonProperty("ingameRole")]
|
||||
public ERole IngameRole { get; set; }
|
||||
|
||||
[JsonProperty("firstSeen")]
|
||||
public DateTimeOffset FirstSeen { get; set; }
|
||||
|
||||
[JsonProperty("displayName")]
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
[JsonProperty("shouldBeRole")]
|
||||
public ERole? ShouldBeRole { get; set; }
|
||||
|
||||
[JsonProperty("discordId")]
|
||||
public string DiscordId { get; set; }
|
||||
}
|
||||
|
||||
public enum ERole { Council, Initiate, Member, Mentor, Recruit };
|
||||
|
||||
public partial class LodestoneRankApi
|
||||
{
|
||||
public static LodestoneRankApi FromJson(string json) => JsonConvert.DeserializeObject<LodestoneRankApi>(json, ChaosBot.Lodestone.Converter.Settings);
|
||||
}
|
||||
|
||||
public static class Serialize
|
||||
{
|
||||
public static string ToJson(this LodestoneRankApi self) => JsonConvert.SerializeObject(self, ChaosBot.Lodestone.Converter.Settings);
|
||||
}
|
||||
|
||||
internal static class Converter
|
||||
{
|
||||
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
|
||||
{
|
||||
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
|
||||
DateParseHandling = DateParseHandling.None,
|
||||
Converters =
|
||||
{
|
||||
ERoleConverter.Singleton,
|
||||
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
internal class ERoleConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type t) => t == typeof(ERole) || t == typeof(ERole?);
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null) return null;
|
||||
var value = serializer.Deserialize<string>(reader);
|
||||
switch (value)
|
||||
{
|
||||
case "Council":
|
||||
return ERole.Council;
|
||||
case "Initiate":
|
||||
return ERole.Initiate;
|
||||
case "Member":
|
||||
return ERole.Member;
|
||||
case "Mentor":
|
||||
return ERole.Mentor;
|
||||
case "Recruit":
|
||||
return ERole.Recruit;
|
||||
}
|
||||
throw new Exception("Cannot unmarshal type ERole");
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
|
||||
{
|
||||
if (untypedValue == null)
|
||||
{
|
||||
serializer.Serialize(writer, null);
|
||||
return;
|
||||
}
|
||||
var value = (ERole)untypedValue;
|
||||
switch (value)
|
||||
{
|
||||
case ERole.Council:
|
||||
serializer.Serialize(writer, "Council");
|
||||
return;
|
||||
case ERole.Initiate:
|
||||
serializer.Serialize(writer, "Initiate");
|
||||
return;
|
||||
case ERole.Member:
|
||||
serializer.Serialize(writer, "Member");
|
||||
return;
|
||||
case ERole.Mentor:
|
||||
serializer.Serialize(writer, "Mentor");
|
||||
return;
|
||||
case ERole.Recruit:
|
||||
serializer.Serialize(writer, "Recruit");
|
||||
return;
|
||||
}
|
||||
throw new Exception("Cannot marshal type ERole");
|
||||
}
|
||||
|
||||
public static readonly ERoleConverter Singleton = new ERoleConverter();
|
||||
}
|
||||
|
||||
internal class ParseStringConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null) return null;
|
||||
var value = serializer.Deserialize<string>(reader);
|
||||
long l;
|
||||
if (Int64.TryParse(value, out l))
|
||||
{
|
||||
return l;
|
||||
}
|
||||
throw new Exception("Cannot unmarshal type long");
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
|
||||
{
|
||||
if (untypedValue == null)
|
||||
{
|
||||
serializer.Serialize(writer, null);
|
||||
return;
|
||||
}
|
||||
var value = (long)untypedValue;
|
||||
serializer.Serialize(writer, value.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
public static readonly ParseStringConverter Singleton = new ParseStringConverter();
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,7 @@ namespace ChaosBot.Models
|
||||
public DbSet<Raffle> Raffles { get; set; }
|
||||
public DbSet<CommandPermission> CommandPermissions { get; set; }
|
||||
public DbSet<Configuration> Configuration { get; set; }
|
||||
public DbSet<Experience> ExperiencePoints { get; set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
@ -41,6 +42,8 @@ namespace ChaosBot.Models
|
||||
.HasKey(x => new {x.DiscordGuildId, x.LodestoneId});
|
||||
modelBuilder.Entity<Point>()
|
||||
.HasKey(x => new {x.DiscordGuildId, x.DiscordUserId});
|
||||
modelBuilder.Entity<Experience>()
|
||||
.HasKey(x => new {x.DiscordGuildId, x.DiscordUserId});
|
||||
modelBuilder.Entity<Configuration>()
|
||||
.HasKey(x => new {x.DiscordGuildId, x.Key});
|
||||
}
|
||||
|
||||
15
ChaosBot/Models/Experience.cs
Normal file
15
ChaosBot/Models/Experience.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace ChaosBot.Models
|
||||
{
|
||||
#region Required
|
||||
public class Experience
|
||||
{
|
||||
[Required]
|
||||
public ulong DiscordUserId { get; set; }
|
||||
[Required]
|
||||
public ulong DiscordGuildId { get; set; }
|
||||
public ulong Amount { get; set; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
27
ChaosBot/Services/RestrictedConfig.cs
Normal file
27
ChaosBot/Services/RestrictedConfig.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ChaosBot.Models;
|
||||
using ChaosBot.Repositories;
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
using NLog;
|
||||
|
||||
namespace ChaosBot.Services
|
||||
{
|
||||
public class RestrictedConfig
|
||||
{
|
||||
private static ILogger _logger = Program.Logger;
|
||||
|
||||
public static async Task<Boolean> IsAllowed(string key)
|
||||
{
|
||||
List<string> restrictedCfg = new List<string> {"Database:Host", "Database:Port", "Database:Name", "Database:User", "Database:Pass", "Bot:Version", "NLog", "WebServer", "Discord:Token"};
|
||||
|
||||
if (restrictedCfg.Contains(key))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user