diff --git a/src/Nadeko.Common/Nadeko.Common.csproj b/src/Nadeko.Common/Nadeko.Common.csproj
index 1a829c83e..205c08172 100644
--- a/src/Nadeko.Common/Nadeko.Common.csproj
+++ b/src/Nadeko.Common/Nadeko.Common.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/src/NadekoBot.Coordinator/NadekoBot.Coordinator.csproj b/src/NadekoBot.Coordinator/NadekoBot.Coordinator.csproj
index bbd01309d..6489f7819 100644
--- a/src/NadekoBot.Coordinator/NadekoBot.Coordinator.csproj
+++ b/src/NadekoBot.Coordinator/NadekoBot.Coordinator.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/src/NadekoBot.Generators/Command/CommandAttributesGenerator.cs b/src/NadekoBot.Generators/Command/CommandAttributesGenerator.cs
index 2410ec9b7..ca18bb71d 100644
--- a/src/NadekoBot.Generators/Command/CommandAttributesGenerator.cs
+++ b/src/NadekoBot.Generators/Command/CommandAttributesGenerator.cs
@@ -1,336 +1,336 @@
-#nullable enable
-using System;
-using System.CodeDom.Compiler;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.CodeAnalysis.Text;
-
-namespace NadekoBot.Generators.Command;
-
-[Generator]
-public class CommandAttributesGenerator : IIncrementalGenerator
-{
- public const string ATTRIBUTE = @"//
-
-namespace NadekoBot.Common;
-
-[System.AttributeUsage(System.AttributeTargets.Method)]
-public class CmdAttribute : System.Attribute
-{
-
-}";
-
- public class MethodModel
- {
- public string? Namespace { get; }
- public IReadOnlyCollection Classes { get; }
- public string ReturnType { get; }
- public string MethodName { get; }
- public IEnumerable Params { get; }
-
- public MethodModel(string? ns, IReadOnlyCollection classes, string returnType, string methodName, IEnumerable @params)
- {
- Namespace = ns;
- Classes = classes;
- ReturnType = returnType;
- MethodName = methodName;
- Params = @params;
- }
- }
-
- public class FileModel
- {
- public string? Namespace { get; }
- public IReadOnlyCollection ClassHierarchy { get; }
- public IReadOnlyCollection Methods { get; }
-
- public FileModel(string? ns, IReadOnlyCollection classHierarchy, IReadOnlyCollection methods)
- {
- Namespace = ns;
- ClassHierarchy = classHierarchy;
- Methods = methods;
- }
- }
-
- public void Initialize(IncrementalGeneratorInitializationContext context)
- {
-// #if DEBUG
-// if (!Debugger.IsAttached)
-// Debugger.Launch();
-// // SpinWait.SpinUntil(() => Debugger.IsAttached);
-// #endif
- context.RegisterPostInitializationOutput(static ctx => ctx.AddSource(
- "CmdAttribute.g.cs",
- SourceText.From(ATTRIBUTE, Encoding.UTF8)));
-
- var methods = context.SyntaxProvider
- .CreateSyntaxProvider(
- static (node, _) => node is MethodDeclarationSyntax { AttributeLists.Count: > 0 },
- static (ctx, cancel) => Transform(ctx, cancel))
- .Where(static m => m is not null)
- .Where(static m => m?.ChildTokens().Any(static x => x.IsKind(SyntaxKind.PublicKeyword)) ?? false);
-
- var compilationMethods = context.CompilationProvider.Combine(methods.Collect());
-
- context.RegisterSourceOutput(compilationMethods,
- static (ctx, tuple) => RegisterAction(in ctx, tuple.Left, in tuple.Right));
- }
-
- private static void RegisterAction(in SourceProductionContext ctx,
- Compilation comp,
- in ImmutableArray methods)
- {
- if (methods is { IsDefaultOrEmpty: true })
- return;
-
- var models = GetModels(comp, methods, ctx.CancellationToken);
-
- foreach (var model in models)
- {
- var name = $"{model.Namespace}.{string.Join(".", model.ClassHierarchy)}.g.cs";
- try
- {
- var source = GetSourceText(model);
- ctx.AddSource(name, SourceText.From(source, Encoding.UTF8));
- }
- catch (Exception ex)
- {
- Console.WriteLine($"Error writing source file {name}\n" + ex);
- }
- }
- }
-
- private static string GetSourceText(FileModel model)
- {
- using var sw = new StringWriter();
- using var tw = new IndentedTextWriter(sw);
-
- tw.WriteLine("// ");
- tw.WriteLine("#pragma warning disable CS1066");
-
- if (model.Namespace is not null)
- {
- tw.WriteLine($"namespace {model.Namespace};");
- tw.WriteLine();
- }
-
- foreach (var className in model.ClassHierarchy)
- {
- tw.WriteLine($"public partial class {className}");
- tw.WriteLine("{");
- tw.Indent ++;
- }
-
- foreach (var method in model.Methods)
- {
- tw.WriteLine("[NadekoCommand]");
- tw.WriteLine("[NadekoDescription]");
- tw.WriteLine("[Aliases]");
- tw.WriteLine($"public partial {method.ReturnType} {method.MethodName}({string.Join(", ", method.Params)});");
- }
-
- foreach (var _ in model.ClassHierarchy)
- {
- tw.Indent --;
- tw.WriteLine("}");
- }
-
- tw.Flush();
- return sw.ToString();
- }
-
- private static IReadOnlyCollection GetModels(Compilation compilation,
- in ImmutableArray inputMethods,
- CancellationToken cancel)
- {
- var models = new List();
-
- var methods = inputMethods
- .Where(static x => x is not null)
- .Distinct();
-
- var methodModels = methods
- .Select(x => MethodDeclarationToMethodModel(compilation, x!))
- .Where(static x => x is not null)
- .Cast();
-
- var groups = methodModels
- .GroupBy(static x => $"{x.Namespace}.{string.Join(".", x.Classes)}");
-
- foreach (var group in groups)
- {
- if (cancel.IsCancellationRequested)
- return new Collection();
-
- if (group is null)
- continue;
-
- var elems = group.ToList();
- if (elems.Count is 0)
- continue;
-
- var model = new FileModel(
- methods: elems,
- ns: elems[0].Namespace,
- classHierarchy: elems![0].Classes
- );
-
- models.Add(model);
- }
-
-
- return models;
- }
-
- private static MethodModel? MethodDeclarationToMethodModel(Compilation comp, MethodDeclarationSyntax decl)
- {
- // SpinWait.SpinUntil(static () => Debugger.IsAttached);
-
- SemanticModel semanticModel;
- try
- {
- semanticModel = comp.GetSemanticModel(decl.SyntaxTree);
- }
- catch
- {
- // for some reason this method can throw "Not part of this compilation" argument exception
- return null;
- }
-
- var methodModel = new MethodModel(
- @params: decl.ParameterList.Parameters
- .Where(p => p.Type is not null)
- .Select(p =>
- {
- var prefix = p.Modifiers.Any(static x => x.IsKind(SyntaxKind.ParamsKeyword))
- ? "params "
- : string.Empty;
-
- var type = semanticModel
- .GetTypeInfo(p.Type!)
- .Type
- ?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
-
-
- var name = p.Identifier.Text;
-
- var suffix = string.Empty;
- if (p.Default is not null)
- {
- if (p.Default.Value is LiteralExpressionSyntax)
- {
- suffix = " = " + p.Default.Value;
- }
- else if (p.Default.Value is MemberAccessExpressionSyntax maes)
- {
- var maesSemModel = comp.GetSemanticModel(maes.SyntaxTree);
- var sym = maesSemModel.GetSymbolInfo(maes.Name);
- if (sym.Symbol is null)
- {
- suffix = " = " + p.Default.Value;
- }
- else
- {
- suffix = " = " + sym.Symbol.ToDisplayString();
- }
- }
- }
-
- return $"{prefix}{type} {name}{suffix}";
- })
- .ToList(),
- methodName: decl.Identifier.Text,
- returnType: decl.ReturnType.ToString(),
- ns: GetNamespace(decl),
- classes: GetClasses(decl)
- );
-
- return methodModel;
- }
-
- //https://github.com/andrewlock/NetEscapades.EnumGenerators/blob/main/src/NetEscapades.EnumGenerators/EnumGenerator.cs
- static string? GetNamespace(MethodDeclarationSyntax declarationSyntax)
- {
- // determine the namespace the class is declared in, if any
- string? nameSpace = null;
- var parentOfInterest = declarationSyntax.Parent;
- while (parentOfInterest is not null)
- {
- parentOfInterest = parentOfInterest.Parent;
-
- if (parentOfInterest is BaseNamespaceDeclarationSyntax ns)
- {
- nameSpace = ns.Name.ToString();
- while (true)
- {
- if (ns.Parent is not NamespaceDeclarationSyntax parent)
- {
- break;
- }
-
- ns = parent;
- nameSpace = $"{ns.Name}.{nameSpace}";
- }
-
- return nameSpace;
- }
-
- }
-
- return nameSpace;
- }
-
- static IReadOnlyCollection GetClasses(MethodDeclarationSyntax declarationSyntax)
- {
- // determine the namespace the class is declared in, if any
- var classes = new LinkedList();
- var parentOfInterest = declarationSyntax.Parent;
- while (parentOfInterest is not null)
- {
- if (parentOfInterest is ClassDeclarationSyntax cds)
- {
- classes.AddFirst(cds.Identifier.ToString());
- }
-
- parentOfInterest = parentOfInterest.Parent;
- }
-
- Debug.WriteLine($"Method {declarationSyntax.Identifier.Text} has {classes.Count} classes");
-
- return classes;
- }
-
- private static MethodDeclarationSyntax? Transform(GeneratorSyntaxContext ctx, CancellationToken cancel)
- {
- var methodDecl = ctx.Node as MethodDeclarationSyntax;
- if (methodDecl is null)
- return default;
-
- foreach (var attListSyntax in methodDecl.AttributeLists)
- {
- foreach (var attSyntax in attListSyntax.Attributes)
- {
- if (cancel.IsCancellationRequested)
- return default;
-
- var symbol = ctx.SemanticModel.GetSymbolInfo(attSyntax).Symbol;
- if (symbol is not IMethodSymbol attSymbol)
- continue;
-
- if (attSymbol.ContainingType.ToDisplayString() == "NadekoBot.Common.CmdAttribute")
- return methodDecl;
- }
- }
-
- return default;
- }
-}
\ No newline at end of file
+// #nullable enable
+// using System;
+// using System.CodeDom.Compiler;
+// using System.Collections.Generic;
+// using System.Collections.Immutable;
+// using System.Collections.ObjectModel;
+// using System.Diagnostics;
+// using System.IO;
+// using System.Linq;
+// using System.Text;
+// using System.Threading;
+// using Microsoft.CodeAnalysis;
+// using Microsoft.CodeAnalysis.CSharp;
+// using Microsoft.CodeAnalysis.CSharp.Syntax;
+// using Microsoft.CodeAnalysis.Text;
+//
+// namespace NadekoBot.Generators.Command;
+//
+// [Generator]
+// public class CommandAttributesGenerator : IIncrementalGenerator
+// {
+// public const string ATTRIBUTE = @"//
+//
+// namespace NadekoBot.Common;
+//
+// [System.AttributeUsage(System.AttributeTargets.Method)]
+// public class CmdAttribute : System.Attribute
+// {
+//
+// }";
+//
+// public class MethodModel
+// {
+// public string? Namespace { get; }
+// public IReadOnlyCollection Classes { get; }
+// public string ReturnType { get; }
+// public string MethodName { get; }
+// public IEnumerable Params { get; }
+//
+// public MethodModel(string? ns, IReadOnlyCollection classes, string returnType, string methodName, IEnumerable @params)
+// {
+// Namespace = ns;
+// Classes = classes;
+// ReturnType = returnType;
+// MethodName = methodName;
+// Params = @params;
+// }
+// }
+//
+// public class FileModel
+// {
+// public string? Namespace { get; }
+// public IReadOnlyCollection ClassHierarchy { get; }
+// public IReadOnlyCollection Methods { get; }
+//
+// public FileModel(string? ns, IReadOnlyCollection classHierarchy, IReadOnlyCollection methods)
+// {
+// Namespace = ns;
+// ClassHierarchy = classHierarchy;
+// Methods = methods;
+// }
+// }
+//
+// public void Initialize(IncrementalGeneratorInitializationContext context)
+// {
+// // #if DEBUG
+// // if (!Debugger.IsAttached)
+// // Debugger.Launch();
+// // // SpinWait.SpinUntil(() => Debugger.IsAttached);
+// // #endif
+// context.RegisterPostInitializationOutput(static ctx => ctx.AddSource(
+// "CmdAttribute.g.cs",
+// SourceText.From(ATTRIBUTE, Encoding.UTF8)));
+//
+// var methods = context.SyntaxProvider
+// .CreateSyntaxProvider(
+// static (node, _) => node is MethodDeclarationSyntax { AttributeLists.Count: > 0 },
+// static (ctx, cancel) => Transform(ctx, cancel))
+// .Where(static m => m is not null)
+// .Where(static m => m?.ChildTokens().Any(static x => x.IsKind(SyntaxKind.PublicKeyword)) ?? false);
+//
+// var compilationMethods = context.CompilationProvider.Combine(methods.Collect());
+//
+// context.RegisterSourceOutput(compilationMethods,
+// static (ctx, tuple) => RegisterAction(in ctx, tuple.Left, in tuple.Right));
+// }
+//
+// private static void RegisterAction(in SourceProductionContext ctx,
+// Compilation comp,
+// in ImmutableArray methods)
+// {
+// if (methods is { IsDefaultOrEmpty: true })
+// return;
+//
+// var models = GetModels(comp, methods, ctx.CancellationToken);
+//
+// foreach (var model in models)
+// {
+// var name = $"{model.Namespace}.{string.Join(".", model.ClassHierarchy)}.g.cs";
+// try
+// {
+// var source = GetSourceText(model);
+// ctx.AddSource(name, SourceText.From(source, Encoding.UTF8));
+// }
+// catch (Exception ex)
+// {
+// Console.WriteLine($"Error writing source file {name}\n" + ex);
+// }
+// }
+// }
+//
+// private static string GetSourceText(FileModel model)
+// {
+// using var sw = new StringWriter();
+// using var tw = new IndentedTextWriter(sw);
+//
+// tw.WriteLine("// ");
+// tw.WriteLine("#pragma warning disable CS1066");
+//
+// if (model.Namespace is not null)
+// {
+// tw.WriteLine($"namespace {model.Namespace};");
+// tw.WriteLine();
+// }
+//
+// foreach (var className in model.ClassHierarchy)
+// {
+// tw.WriteLine($"public partial class {className}");
+// tw.WriteLine("{");
+// tw.Indent ++;
+// }
+//
+// foreach (var method in model.Methods)
+// {
+// tw.WriteLine("[NadekoCommand]");
+// tw.WriteLine("[NadekoDescription]");
+// tw.WriteLine("[Aliases]");
+// tw.WriteLine($"public partial {method.ReturnType} {method.MethodName}({string.Join(", ", method.Params)});");
+// }
+//
+// foreach (var _ in model.ClassHierarchy)
+// {
+// tw.Indent --;
+// tw.WriteLine("}");
+// }
+//
+// tw.Flush();
+// return sw.ToString();
+// }
+//
+// private static IReadOnlyCollection GetModels(Compilation compilation,
+// in ImmutableArray inputMethods,
+// CancellationToken cancel)
+// {
+// var models = new List();
+//
+// var methods = inputMethods
+// .Where(static x => x is not null)
+// .Distinct();
+//
+// var methodModels = methods
+// .Select(x => MethodDeclarationToMethodModel(compilation, x!))
+// .Where(static x => x is not null)
+// .Cast();
+//
+// var groups = methodModels
+// .GroupBy(static x => $"{x.Namespace}.{string.Join(".", x.Classes)}");
+//
+// foreach (var group in groups)
+// {
+// if (cancel.IsCancellationRequested)
+// return new Collection();
+//
+// if (group is null)
+// continue;
+//
+// var elems = group.ToList();
+// if (elems.Count is 0)
+// continue;
+//
+// var model = new FileModel(
+// methods: elems,
+// ns: elems[0].Namespace,
+// classHierarchy: elems![0].Classes
+// );
+//
+// models.Add(model);
+// }
+//
+//
+// return models;
+// }
+//
+// private static MethodModel? MethodDeclarationToMethodModel(Compilation comp, MethodDeclarationSyntax decl)
+// {
+// // SpinWait.SpinUntil(static () => Debugger.IsAttached);
+//
+// SemanticModel semanticModel;
+// try
+// {
+// semanticModel = comp.GetSemanticModel(decl.SyntaxTree);
+// }
+// catch
+// {
+// // for some reason this method can throw "Not part of this compilation" argument exception
+// return null;
+// }
+//
+// var methodModel = new MethodModel(
+// @params: decl.ParameterList.Parameters
+// .Where(p => p.Type is not null)
+// .Select(p =>
+// {
+// var prefix = p.Modifiers.Any(static x => x.IsKind(SyntaxKind.ParamsKeyword))
+// ? "params "
+// : string.Empty;
+//
+// var type = semanticModel
+// .GetTypeInfo(p.Type!)
+// .Type
+// ?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
+//
+//
+// var name = p.Identifier.Text;
+//
+// var suffix = string.Empty;
+// if (p.Default is not null)
+// {
+// if (p.Default.Value is LiteralExpressionSyntax)
+// {
+// suffix = " = " + p.Default.Value;
+// }
+// else if (p.Default.Value is MemberAccessExpressionSyntax maes)
+// {
+// var maesSemModel = comp.GetSemanticModel(maes.SyntaxTree);
+// var sym = maesSemModel.GetSymbolInfo(maes.Name);
+// if (sym.Symbol is null)
+// {
+// suffix = " = " + p.Default.Value;
+// }
+// else
+// {
+// suffix = " = " + sym.Symbol.ToDisplayString();
+// }
+// }
+// }
+//
+// return $"{prefix}{type} {name}{suffix}";
+// })
+// .ToList(),
+// methodName: decl.Identifier.Text,
+// returnType: decl.ReturnType.ToString(),
+// ns: GetNamespace(decl),
+// classes: GetClasses(decl)
+// );
+//
+// return methodModel;
+// }
+//
+// //https://github.com/andrewlock/NetEscapades.EnumGenerators/blob/main/src/NetEscapades.EnumGenerators/EnumGenerator.cs
+// static string? GetNamespace(MethodDeclarationSyntax declarationSyntax)
+// {
+// // determine the namespace the class is declared in, if any
+// string? nameSpace = null;
+// var parentOfInterest = declarationSyntax.Parent;
+// while (parentOfInterest is not null)
+// {
+// parentOfInterest = parentOfInterest.Parent;
+//
+// if (parentOfInterest is BaseNamespaceDeclarationSyntax ns)
+// {
+// nameSpace = ns.Name.ToString();
+// while (true)
+// {
+// if (ns.Parent is not NamespaceDeclarationSyntax parent)
+// {
+// break;
+// }
+//
+// ns = parent;
+// nameSpace = $"{ns.Name}.{nameSpace}";
+// }
+//
+// return nameSpace;
+// }
+//
+// }
+//
+// return nameSpace;
+// }
+//
+// static IReadOnlyCollection GetClasses(MethodDeclarationSyntax declarationSyntax)
+// {
+// // determine the namespace the class is declared in, if any
+// var classes = new LinkedList();
+// var parentOfInterest = declarationSyntax.Parent;
+// while (parentOfInterest is not null)
+// {
+// if (parentOfInterest is ClassDeclarationSyntax cds)
+// {
+// classes.AddFirst(cds.Identifier.ToString());
+// }
+//
+// parentOfInterest = parentOfInterest.Parent;
+// }
+//
+// Debug.WriteLine($"Method {declarationSyntax.Identifier.Text} has {classes.Count} classes");
+//
+// return classes;
+// }
+//
+// private static MethodDeclarationSyntax? Transform(GeneratorSyntaxContext ctx, CancellationToken cancel)
+// {
+// var methodDecl = ctx.Node as MethodDeclarationSyntax;
+// if (methodDecl is null)
+// return default;
+//
+// foreach (var attListSyntax in methodDecl.AttributeLists)
+// {
+// foreach (var attSyntax in attListSyntax.Attributes)
+// {
+// if (cancel.IsCancellationRequested)
+// return default;
+//
+// var symbol = ctx.SemanticModel.GetSymbolInfo(attSyntax).Symbol;
+// if (symbol is not IMethodSymbol attSymbol)
+// continue;
+//
+// if (attSymbol.ContainingType.ToDisplayString() == "NadekoBot.Common.CmdAttribute")
+// return methodDecl;
+// }
+// }
+//
+// return default;
+// }
+// }
\ No newline at end of file
diff --git a/src/NadekoBot.Tests/BotStringsTests.cs b/src/NadekoBot.Tests/BotStringsTests.cs
index 31b4cbc34..b9b39cab6 100644
--- a/src/NadekoBot.Tests/BotStringsTests.cs
+++ b/src/NadekoBot.Tests/BotStringsTests.cs
@@ -47,7 +47,7 @@ namespace NadekoBot.Tests
|| !(type.GetCustomAttribute(true) is null)) // or a submodule
.SelectMany(x => x.GetMethods()
.Where(mi => mi.CustomAttributes
- .Any(ca => ca.AttributeType == typeof(NadekoCommandAttribute))))
+ .Any(ca => ca.AttributeType == typeof(CmdAttribute))))
.Select(x => x.Name.ToLowerInvariant())
.ToArray();
diff --git a/src/NadekoBot.VotesApi/NadekoBot.VotesApi.csproj b/src/NadekoBot.VotesApi/NadekoBot.VotesApi.csproj
index 1ce2cc51f..61b68b3aa 100644
--- a/src/NadekoBot.VotesApi/NadekoBot.VotesApi.csproj
+++ b/src/NadekoBot.VotesApi/NadekoBot.VotesApi.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/src/NadekoBot/Modules/Xp/XpService.cs b/src/NadekoBot/Modules/Xp/XpService.cs
index 696776f50..f196d402a 100644
--- a/src/NadekoBot/Modules/Xp/XpService.cs
+++ b/src/NadekoBot/Modules/Xp/XpService.cs
@@ -1,4 +1,3 @@
-#nullable disable warnings
using LinqToDB;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Common.ModuleBehaviors;
@@ -342,7 +341,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
}
else // channel
{
- await ch.SendConfirmAsync(_eb,
+ await ch?.SendConfirmAsync(_eb,
_strings.GetText(strs.level_up_channel(user.Mention,
Format.Bold(newLevel.ToString())),
guild.Id));
@@ -494,7 +493,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
{
Level = level,
RoleId = roleId,
- Remove = remove
+ Remove = remove,
});
}
@@ -654,6 +653,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
Guild = channel.Guild,
User = user,
XpAmount = actualXp,
+ Channel = channel
});
}
}
@@ -862,7 +862,15 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
public Task<(Stream Image, IImageFormat Format)> GenerateXpImageAsync(FullUserStats stats)
=> Task.Run(async () =>
{
- using var img = Image.Load(await GetXpBackgroundAsync(stats.User.UserId), out var imageFormat);
+ var bgBytes = await GetXpBackgroundAsync(stats.User.UserId);
+
+ if (bgBytes is null)
+ {
+ Log.Warning("Xp background image could not be loaded");
+ throw new ArgumentNullException(nameof(bgBytes));
+ }
+
+ using var img = Image.Load(bgBytes, out var imageFormat);
if (template.User.Name.Show)
{
var fontSize = (int)(template.User.Name.FontSize * 0.9);
@@ -1113,7 +1121,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
return output;
});
- private async Task GetXpBackgroundAsync(ulong userId)
+ private async Task GetXpBackgroundAsync(ulong _)
{
var img = await _images.GetXpBackgroundImageAsync();
return img;
@@ -1123,7 +1131,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
private async Task DrawFrame(Image img, ulong userId)
{
var patron = await _ps.GetPatronAsync(userId);
- Image frame = null;
+ Image? frame = null;
if (patron.Tier == PatronTier.V)
frame = Image.Load(File.OpenRead("data/images/frame_silver.png"));
else if (patron.Tier >= PatronTier.X || _creds.IsOwner(userId))
diff --git a/src/NadekoBot/Modules/Xp/_Common/UserCacheItem.cs b/src/NadekoBot/Modules/Xp/_Common/UserCacheItem.cs
index a5e18f373..90cbdfd8d 100644
--- a/src/NadekoBot/Modules/Xp/_Common/UserCacheItem.cs
+++ b/src/NadekoBot/Modules/Xp/_Common/UserCacheItem.cs
@@ -1,4 +1,4 @@
-#nullable disable
+#nullable disable warnings
using Cloneable;
namespace NadekoBot.Modules.Xp.Services;
@@ -6,8 +6,8 @@ namespace NadekoBot.Modules.Xp.Services;
[Cloneable]
public sealed partial class UserXpGainData : ICloneable
{
- public IGuildUser User { get; set; }
- public IGuild Guild { get; set; }
- public IMessageChannel Channel { get; set; }
+ public IGuildUser User { get; init; }
+ public IGuild Guild { get; init; }
+ public IMessageChannel Channel { get; init; }
public int XpAmount { get; set; }
}
\ No newline at end of file