mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 09:18:27 -04:00
Killed history
This commit is contained in:
20
NadekoBot.Core/Common/AsyncLazy.cs
Normal file
20
NadekoBot.Core/Common/AsyncLazy.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Common
|
||||
{
|
||||
public class AsyncLazy<T> : Lazy<Task<T>>
|
||||
{
|
||||
public AsyncLazy(Func<T> valueFactory) :
|
||||
base(() => Task.Run(valueFactory))
|
||||
{ }
|
||||
|
||||
public AsyncLazy(Func<Task<T>> taskFactory) :
|
||||
base(() => Task.Run(taskFactory))
|
||||
{ }
|
||||
|
||||
public TaskAwaiter<T> GetAwaiter() { return Value.GetAwaiter(); }
|
||||
}
|
||||
|
||||
}
|
18
NadekoBot.Core/Common/Attributes/Aliases.cs
Normal file
18
NadekoBot.Core/Common/Attributes/Aliases.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Core.Services.Impl;
|
||||
namespace NadekoBot.Common.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class AliasesAttribute : AliasAttribute
|
||||
{
|
||||
public AliasesAttribute([CallerMemberName] string memberName = "")
|
||||
: base(CommandNameLoadHelper.GetAliasesFor(memberName))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
15
NadekoBot.Core/Common/Attributes/BotPerm.cs
Normal file
15
NadekoBot.Core/Common/Attributes/BotPerm.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Discord.Commands;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public class BotPermAttribute : RequireBotPermissionAttribute
|
||||
{
|
||||
public BotPermAttribute(GuildPerm permission) : base((GuildPermission)permission)
|
||||
{
|
||||
}
|
||||
|
||||
public BotPermAttribute(ChannelPerm permission) : base((ChannelPermission)permission)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
36
NadekoBot.Core/Common/Attributes/CommandNameLoadHelper.cs
Normal file
36
NadekoBot.Core/Common/Attributes/CommandNameLoadHelper.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace NadekoBot.Common.Attributes
|
||||
{
|
||||
public static class CommandNameLoadHelper
|
||||
{
|
||||
|
||||
private static YamlDotNet.Serialization.IDeserializer _deserializer
|
||||
= new YamlDotNet.Serialization.Deserializer();
|
||||
|
||||
public static Lazy<Dictionary<string, string[]>> LazyCommandAliases
|
||||
= new Lazy<Dictionary<string, string[]>>(() => LoadCommandNames());
|
||||
public static Dictionary<string, string[]> LoadCommandNames(string aliasesFilePath = "data/aliases.yml")
|
||||
{
|
||||
var text = File.ReadAllText(aliasesFilePath);
|
||||
return _deserializer.Deserialize<Dictionary<string, string[]>>(text);
|
||||
}
|
||||
|
||||
public static string[] GetAliasesFor(string methodName)
|
||||
=> LazyCommandAliases.Value.TryGetValue(methodName.ToLowerInvariant(), out var aliases) && aliases.Length > 1
|
||||
? aliases.Skip(1).ToArray()
|
||||
: Array.Empty<string>();
|
||||
|
||||
public static string GetCommandNameFor(string methodName)
|
||||
{
|
||||
methodName = methodName.ToLowerInvariant();
|
||||
var toReturn = LazyCommandAliases.Value.TryGetValue(methodName, out var aliases) && aliases.Length > 0
|
||||
? aliases[0]
|
||||
: methodName;
|
||||
return toReturn;
|
||||
}
|
||||
}
|
||||
}
|
16
NadekoBot.Core/Common/Attributes/Description.cs
Normal file
16
NadekoBot.Core/Common/Attributes/Description.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Core.Services.Impl;
|
||||
|
||||
namespace NadekoBot.Common.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class DescriptionAttribute : SummaryAttribute
|
||||
{
|
||||
// Localization.LoadCommand(memberName.ToLowerInvariant()).Desc
|
||||
public DescriptionAttribute(string text = "") : base(text)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
9
NadekoBot.Core/Common/Attributes/LeftoverAttribute.cs
Normal file
9
NadekoBot.Core/Common/Attributes/LeftoverAttribute.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Discord.Commands
|
||||
{
|
||||
public class LeftoverAttribute : RemainderAttribute
|
||||
{
|
||||
public LeftoverAttribute()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
19
NadekoBot.Core/Common/Attributes/NadekoCommand.cs
Normal file
19
NadekoBot.Core/Common/Attributes/NadekoCommand.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Core.Services.Impl;
|
||||
|
||||
namespace NadekoBot.Common.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class NadekoCommandAttribute : CommandAttribute
|
||||
{
|
||||
public NadekoCommandAttribute([CallerMemberName] string memberName="")
|
||||
: base(CommandNameLoadHelper.GetCommandNameFor(memberName))
|
||||
{
|
||||
this.MethodName = memberName.ToLowerInvariant();
|
||||
}
|
||||
|
||||
public string MethodName { get; }
|
||||
}
|
||||
}
|
14
NadekoBot.Core/Common/Attributes/NadekoModuleAttribute.cs
Normal file
14
NadekoBot.Core/Common/Attributes/NadekoModuleAttribute.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace NadekoBot.Common.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
sealed class NadekoModuleAttribute : GroupAttribute
|
||||
{
|
||||
public NadekoModuleAttribute(string moduleName) : base(moduleName)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
NadekoBot.Core/Common/Attributes/NadekoOptions.cs
Normal file
15
NadekoBot.Core/Common/Attributes/NadekoOptions.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace NadekoBot.Common.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class NadekoOptionsAttribute : Attribute
|
||||
{
|
||||
public Type OptionType { get; set; }
|
||||
|
||||
public NadekoOptionsAttribute(Type t)
|
||||
{
|
||||
this.OptionType = t;
|
||||
}
|
||||
}
|
||||
}
|
19
NadekoBot.Core/Common/Attributes/OwnerOnlyAttribute.cs
Normal file
19
NadekoBot.Core/Common/Attributes/OwnerOnlyAttribute.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Core.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace NadekoBot.Common.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
|
||||
public sealed class OwnerOnlyAttribute : PreconditionAttribute
|
||||
{
|
||||
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo executingCommand, IServiceProvider services)
|
||||
{
|
||||
var creds = services.GetService<IBotCredentials>();
|
||||
|
||||
return Task.FromResult((creds.IsOwner(context.User) || context.Client.CurrentUser.Id == context.User.Id ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner")));
|
||||
}
|
||||
}
|
||||
}
|
38
NadekoBot.Core/Common/Attributes/Ratelimit.cs
Normal file
38
NadekoBot.Core/Common/Attributes/Ratelimit.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Core.Services;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace NadekoBot.Core.Common.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class RatelimitAttribute : PreconditionAttribute
|
||||
{
|
||||
public int Seconds { get; }
|
||||
|
||||
public RatelimitAttribute(int seconds)
|
||||
{
|
||||
if (seconds <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(seconds));
|
||||
|
||||
Seconds = seconds;
|
||||
}
|
||||
|
||||
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
|
||||
{
|
||||
if (Seconds == 0)
|
||||
return Task.FromResult(PreconditionResult.FromSuccess());
|
||||
|
||||
var cache = services.GetService<IDataCache>();
|
||||
var rem = cache.TryAddRatelimit(context.User.Id, command.Name, Seconds);
|
||||
|
||||
if(rem == null)
|
||||
return Task.FromResult(PreconditionResult.FromSuccess());
|
||||
|
||||
var msgContent = $"You can use this command again in {rem.Value.TotalSeconds:F1}s.";
|
||||
|
||||
return Task.FromResult(PreconditionResult.FromError(msgContent));
|
||||
}
|
||||
}
|
||||
}
|
21
NadekoBot.Core/Common/Attributes/Usage.cs
Normal file
21
NadekoBot.Core/Common/Attributes/Usage.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Core.Services.Impl;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace NadekoBot.Common.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class UsageAttribute : RemarksAttribute
|
||||
{
|
||||
// public static string GetUsage(string memberName)
|
||||
// {
|
||||
// var usage = Localization.LoadCommand(memberName.ToLowerInvariant()).Usage;
|
||||
// return JsonConvert.SerializeObject(usage);
|
||||
// }
|
||||
public UsageAttribute(string text = "") : base(text)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
33
NadekoBot.Core/Common/Attributes/UserPerm.cs
Normal file
33
NadekoBot.Core/Common/Attributes/UserPerm.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NadekoBot.Modules.Administration.Services;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
||||
public class UserPermAttribute : PreconditionAttribute
|
||||
{
|
||||
public RequireUserPermissionAttribute UserPermissionAttribute { get; }
|
||||
|
||||
public UserPermAttribute(GuildPerm permission)
|
||||
{
|
||||
UserPermissionAttribute = new RequireUserPermissionAttribute((GuildPermission)permission);
|
||||
}
|
||||
|
||||
public UserPermAttribute(ChannelPerm permission)
|
||||
{
|
||||
UserPermissionAttribute = new RequireUserPermissionAttribute((ChannelPermission)permission);
|
||||
}
|
||||
|
||||
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
|
||||
{
|
||||
var permService = services.GetService<DiscordPermOverrideService>();
|
||||
if (permService.TryGetOverrides(context.Guild?.Id ?? 0, command.Name.ToUpperInvariant(), out var _))
|
||||
return Task.FromResult(PreconditionResult.FromSuccess());
|
||||
|
||||
return UserPermissionAttribute.CheckPermissionsAsync(context, command, services);
|
||||
}
|
||||
}
|
||||
}
|
26
NadekoBot.Core/Common/BotConfigEditType.cs
Normal file
26
NadekoBot.Core/Common/BotConfigEditType.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
namespace NadekoBot.Common
|
||||
{
|
||||
public enum BotConfigEditType
|
||||
{
|
||||
/// <summary>
|
||||
/// The amount of currency awarded to the winner of the trivia game.
|
||||
/// Default is 0.
|
||||
/// </summary>
|
||||
TriviaCurrencyReward,
|
||||
/// <summary>
|
||||
/// Users can't start trivia games which have smaller win requirement than specified by this setting.
|
||||
/// Default is 0.
|
||||
/// </summary>
|
||||
MinimumTriviaWinReq,
|
||||
/// <summary>
|
||||
/// The amount of XP the user receives when they send a message (which is not too short).
|
||||
/// Default is 3.
|
||||
/// </summary>
|
||||
XpPerMessage,
|
||||
/// <summary>
|
||||
/// This value represents how often the user can receive XP from sending messages.
|
||||
/// Default is 5.
|
||||
/// </summary>
|
||||
XpMinutesTimeout,
|
||||
}
|
||||
}
|
126
NadekoBot.Core/Common/CREmbed.cs
Normal file
126
NadekoBot.Core/Common/CREmbed.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using Discord;
|
||||
using NadekoBot.Extensions;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace NadekoBot.Common
|
||||
{
|
||||
public class CREmbed
|
||||
{
|
||||
public CREmbedAuthor Author { get; set; }
|
||||
public string PlainText { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Url { get; set; }
|
||||
public CREmbedFooter Footer { get; set; }
|
||||
public string Thumbnail { get; set; }
|
||||
public string Image { get; set; }
|
||||
public CREmbedField[] Fields { get; set; }
|
||||
public uint Color { get; set; } = 7458112;
|
||||
|
||||
public bool IsValid =>
|
||||
IsEmbedValid || !string.IsNullOrWhiteSpace(PlainText);
|
||||
public bool IsEmbedValid =>
|
||||
!string.IsNullOrWhiteSpace(Title) ||
|
||||
!string.IsNullOrWhiteSpace(Description) ||
|
||||
!string.IsNullOrWhiteSpace(Url) ||
|
||||
!string.IsNullOrWhiteSpace(Thumbnail) ||
|
||||
!string.IsNullOrWhiteSpace(Image) ||
|
||||
(Footer != null && (!string.IsNullOrWhiteSpace(Footer.Text) || !string.IsNullOrWhiteSpace(Footer.IconUrl))) ||
|
||||
(Fields != null && Fields.Length > 0);
|
||||
|
||||
public EmbedBuilder ToEmbed()
|
||||
{
|
||||
var embed = new EmbedBuilder();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Title))
|
||||
embed.WithTitle(Title);
|
||||
if (!string.IsNullOrWhiteSpace(Description))
|
||||
embed.WithDescription(Description);
|
||||
if (Url != null && Uri.IsWellFormedUriString(Url, UriKind.Absolute))
|
||||
embed.WithUrl(Url);
|
||||
embed.WithColor(new Discord.Color(Color));
|
||||
if (Footer != null)
|
||||
embed.WithFooter(efb =>
|
||||
{
|
||||
efb.WithText(Footer.Text);
|
||||
if (Uri.IsWellFormedUriString(Footer.IconUrl, UriKind.Absolute))
|
||||
efb.WithIconUrl(Footer.IconUrl);
|
||||
});
|
||||
|
||||
if (Thumbnail != null && Uri.IsWellFormedUriString(Thumbnail, UriKind.Absolute))
|
||||
embed.WithThumbnailUrl(Thumbnail);
|
||||
if (Image != null && Uri.IsWellFormedUriString(Image, UriKind.Absolute))
|
||||
embed.WithImageUrl(Image);
|
||||
if (Author != null && !string.IsNullOrWhiteSpace(Author.Name))
|
||||
{
|
||||
if (!Uri.IsWellFormedUriString(Author.IconUrl, UriKind.Absolute))
|
||||
Author.IconUrl = null;
|
||||
if (!Uri.IsWellFormedUriString(Author.Url, UriKind.Absolute))
|
||||
Author.Url = null;
|
||||
|
||||
embed.WithAuthor(Author.Name, Author.IconUrl, Author.Url);
|
||||
}
|
||||
|
||||
if (Fields != null)
|
||||
foreach (var f in Fields)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(f.Name) && !string.IsNullOrWhiteSpace(f.Value))
|
||||
embed.AddField(efb => efb.WithName(f.Name).WithValue(f.Value).WithIsInline(f.Inline));
|
||||
}
|
||||
|
||||
return embed;
|
||||
}
|
||||
|
||||
public static bool TryParse(string input, out CREmbed embed)
|
||||
{
|
||||
embed = null;
|
||||
if (string.IsNullOrWhiteSpace(input) || !input.Trim().StartsWith('{'))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
var crembed = JsonConvert.DeserializeObject<CREmbed>(input);
|
||||
|
||||
if (crembed.Fields != null && crembed.Fields.Length > 0)
|
||||
foreach (var f in crembed.Fields)
|
||||
{
|
||||
f.Name = f.Name.TrimTo(256);
|
||||
f.Value = f.Value.TrimTo(1024);
|
||||
}
|
||||
if (!crembed.IsValid)
|
||||
return false;
|
||||
|
||||
embed = crembed;
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CREmbedField
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Value { get; set; }
|
||||
public bool Inline { get; set; }
|
||||
}
|
||||
|
||||
public class CREmbedFooter
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public string IconUrl { get; set; }
|
||||
[JsonProperty("icon_url")]
|
||||
private string Icon_Url { set => IconUrl = value; }
|
||||
}
|
||||
public class CREmbedAuthor
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string IconUrl { get; set; }
|
||||
[JsonProperty("icon_url")]
|
||||
private string Icon_Url { set => IconUrl = value; }
|
||||
public string Url { get; set; }
|
||||
}
|
||||
}
|
20
NadekoBot.Core/Common/CmdStrings.cs
Normal file
20
NadekoBot.Core/Common/CmdStrings.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public class CmdStrings
|
||||
{
|
||||
public string[] Usages { get; }
|
||||
public string Description { get; }
|
||||
|
||||
[JsonConstructor]
|
||||
public CmdStrings(
|
||||
[JsonProperty("args")]string[] usages,
|
||||
[JsonProperty("desc")]string description
|
||||
)
|
||||
{
|
||||
Usages = usages;
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
}
|
772
NadekoBot.Core/Common/Collections/ConcurrentHashSet.cs
Normal file
772
NadekoBot.Core/Common/Collections/ConcurrentHashSet.cs
Normal file
@@ -0,0 +1,772 @@
|
||||
// License MIT
|
||||
// Source: https://github.com/i3arnon/ConcurrentHashSet
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace NadekoBot.Common.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a thread-safe hash-based unique collection.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the items in the collection.</typeparam>
|
||||
/// <remarks>
|
||||
/// All public members of <see cref="ConcurrentHashSet{T}"/> are thread-safe and may be used
|
||||
/// concurrently from multiple threads.
|
||||
/// </remarks>
|
||||
[DebuggerDisplay("Count = {Count}")]
|
||||
public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ICollection<T>
|
||||
{
|
||||
private const int DefaultCapacity = 31;
|
||||
private const int MaxLockNumber = 1024;
|
||||
|
||||
private readonly IEqualityComparer<T> _comparer;
|
||||
private readonly bool _growLockArray;
|
||||
|
||||
private int _budget;
|
||||
private volatile Tables _tables;
|
||||
|
||||
private static int DefaultConcurrencyLevel => PlatformHelper.ProcessorCount;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of items contained in the <see
|
||||
/// cref="ConcurrentHashSet{T}"/>.
|
||||
/// </summary>
|
||||
/// <value>The number of items contained in the <see
|
||||
/// cref="ConcurrentHashSet{T}"/>.</value>
|
||||
/// <remarks>Count has snapshot semantics and represents the number of items in the <see
|
||||
/// cref="ConcurrentHashSet{T}"/>
|
||||
/// at the moment when Count was accessed.</remarks>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
var count = 0;
|
||||
var acquiredLocks = 0;
|
||||
try
|
||||
{
|
||||
AcquireAllLocks(ref acquiredLocks);
|
||||
|
||||
for (var i = 0; i < _tables.CountPerLock.Length; i++)
|
||||
{
|
||||
count += _tables.CountPerLock[i];
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseLocks(0, acquiredLocks);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the <see cref="ConcurrentHashSet{T}"/> is empty.
|
||||
/// </summary>
|
||||
/// <value>true if the <see cref="ConcurrentHashSet{T}"/> is empty; otherwise,
|
||||
/// false.</value>
|
||||
public bool IsEmpty
|
||||
{
|
||||
get
|
||||
{
|
||||
var acquiredLocks = 0;
|
||||
try
|
||||
{
|
||||
AcquireAllLocks(ref acquiredLocks);
|
||||
|
||||
for (var i = 0; i < _tables.CountPerLock.Length; i++)
|
||||
{
|
||||
if (_tables.CountPerLock[i] != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseLocks(0, acquiredLocks);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see
|
||||
/// cref="ConcurrentHashSet{T}"/>
|
||||
/// class that is empty, has the default concurrency level, has the default initial capacity, and
|
||||
/// uses the default comparer for the item type.
|
||||
/// </summary>
|
||||
public ConcurrentHashSet()
|
||||
: this(DefaultConcurrencyLevel, DefaultCapacity, true, EqualityComparer<T>.Default)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see
|
||||
/// cref="ConcurrentHashSet{T}"/>
|
||||
/// class that is empty, has the specified concurrency level and capacity, and uses the default
|
||||
/// comparer for the item type.
|
||||
/// </summary>
|
||||
/// <param name="concurrencyLevel">The estimated number of threads that will update the
|
||||
/// <see cref="ConcurrentHashSet{T}"/> concurrently.</param>
|
||||
/// <param name="capacity">The initial number of elements that the <see
|
||||
/// cref="ConcurrentHashSet{T}"/>
|
||||
/// can contain.</param>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="concurrencyLevel"/> is
|
||||
/// less than 1.</exception>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException"> <paramref name="capacity"/> is less than
|
||||
/// 0.</exception>
|
||||
public ConcurrentHashSet(int concurrencyLevel, int capacity)
|
||||
: this(concurrencyLevel, capacity, false, EqualityComparer<T>.Default)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConcurrentHashSet{T}"/>
|
||||
/// class that contains elements copied from the specified <see
|
||||
/// cref="T:System.Collections.IEnumerable{T}"/>, has the default concurrency
|
||||
/// level, has the default initial capacity, and uses the default comparer for the item type.
|
||||
/// </summary>
|
||||
/// <param name="collection">The <see
|
||||
/// cref="T:System.Collections.IEnumerable{T}"/> whose elements are copied to
|
||||
/// the new
|
||||
/// <see cref="ConcurrentHashSet{T}"/>.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException"><paramref name="collection"/> is a null reference.</exception>
|
||||
public ConcurrentHashSet(IEnumerable<T> collection)
|
||||
: this(collection, EqualityComparer<T>.Default)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConcurrentHashSet{T}"/>
|
||||
/// class that is empty, has the specified concurrency level and capacity, and uses the specified
|
||||
/// <see cref="T:System.Collections.Generic.IEqualityComparer{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{T}"/>
|
||||
/// implementation to use when comparing items.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException"><paramref name="comparer"/> is a null reference.</exception>
|
||||
public ConcurrentHashSet(IEqualityComparer<T> comparer)
|
||||
: this(DefaultConcurrencyLevel, DefaultCapacity, true, comparer)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConcurrentHashSet{T}"/>
|
||||
/// class that contains elements copied from the specified <see
|
||||
/// cref="T:System.Collections.IEnumerable"/>, has the default concurrency level, has the default
|
||||
/// initial capacity, and uses the specified
|
||||
/// <see cref="T:System.Collections.Generic.IEqualityComparer{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="collection">The <see
|
||||
/// cref="T:System.Collections.IEnumerable{T}"/> whose elements are copied to
|
||||
/// the new
|
||||
/// <see cref="ConcurrentHashSet{T}"/>.</param>
|
||||
/// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{T}"/>
|
||||
/// implementation to use when comparing items.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException"><paramref name="collection"/> is a null reference
|
||||
/// (Nothing in Visual Basic). -or-
|
||||
/// <paramref name="comparer"/> is a null reference (Nothing in Visual Basic).
|
||||
/// </exception>
|
||||
public ConcurrentHashSet(IEnumerable<T> collection, IEqualityComparer<T> comparer)
|
||||
: this(comparer)
|
||||
{
|
||||
if (collection == null) throw new ArgumentNullException(nameof(collection));
|
||||
|
||||
InitializeFromCollection(collection);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConcurrentHashSet{T}"/>
|
||||
/// class that contains elements copied from the specified <see cref="T:System.Collections.IEnumerable"/>,
|
||||
/// has the specified concurrency level, has the specified initial capacity, and uses the specified
|
||||
/// <see cref="T:System.Collections.Generic.IEqualityComparer{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="concurrencyLevel">The estimated number of threads that will update the
|
||||
/// <see cref="ConcurrentHashSet{T}"/> concurrently.</param>
|
||||
/// <param name="collection">The <see cref="T:System.Collections.IEnumerable{T}"/> whose elements are copied to the new
|
||||
/// <see cref="ConcurrentHashSet{T}"/>.</param>
|
||||
/// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{T}"/> implementation to use
|
||||
/// when comparing items.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException">
|
||||
/// <paramref name="collection"/> is a null reference.
|
||||
/// -or-
|
||||
/// <paramref name="comparer"/> is a null reference.
|
||||
/// </exception>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="concurrencyLevel"/> is less than 1.
|
||||
/// </exception>
|
||||
public ConcurrentHashSet(int concurrencyLevel, IEnumerable<T> collection, IEqualityComparer<T> comparer)
|
||||
: this(concurrencyLevel, DefaultCapacity, false, comparer)
|
||||
{
|
||||
if (collection == null) throw new ArgumentNullException(nameof(collection));
|
||||
if (comparer == null) throw new ArgumentNullException(nameof(comparer));
|
||||
|
||||
InitializeFromCollection(collection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConcurrentHashSet{T}"/>
|
||||
/// class that is empty, has the specified concurrency level, has the specified initial capacity, and
|
||||
/// uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="concurrencyLevel">The estimated number of threads that will update the
|
||||
/// <see cref="ConcurrentHashSet{T}"/> concurrently.</param>
|
||||
/// <param name="capacity">The initial number of elements that the <see
|
||||
/// cref="ConcurrentHashSet{T}"/>
|
||||
/// can contain.</param>
|
||||
/// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{T}"/>
|
||||
/// implementation to use when comparing items.</param>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="concurrencyLevel"/> is less than 1. -or-
|
||||
/// <paramref name="capacity"/> is less than 0.
|
||||
/// </exception>
|
||||
/// <exception cref="T:System.ArgumentNullException"><paramref name="comparer"/> is a null reference.</exception>
|
||||
public ConcurrentHashSet(int concurrencyLevel, int capacity, IEqualityComparer<T> comparer)
|
||||
: this(concurrencyLevel, capacity, false, comparer)
|
||||
{
|
||||
}
|
||||
|
||||
private ConcurrentHashSet(int concurrencyLevel, int capacity, bool growLockArray, IEqualityComparer<T> comparer)
|
||||
{
|
||||
if (concurrencyLevel < 1) throw new ArgumentOutOfRangeException(nameof(concurrencyLevel));
|
||||
if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity));
|
||||
|
||||
// The capacity should be at least as large as the concurrency level. Otherwise, we would have locks that don't guard
|
||||
// any buckets.
|
||||
if (capacity < concurrencyLevel)
|
||||
{
|
||||
capacity = concurrencyLevel;
|
||||
}
|
||||
|
||||
var locks = new object[concurrencyLevel];
|
||||
for (var i = 0; i < locks.Length; i++)
|
||||
{
|
||||
locks[i] = new object();
|
||||
}
|
||||
|
||||
var countPerLock = new int[locks.Length];
|
||||
var buckets = new Node[capacity];
|
||||
_tables = new Tables(buckets, locks, countPerLock);
|
||||
|
||||
_growLockArray = growLockArray;
|
||||
_budget = buckets.Length / locks.Length;
|
||||
_comparer = comparer ?? throw new ArgumentNullException(nameof(comparer));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified item to the <see cref="ConcurrentHashSet{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="item">The item to add.</param>
|
||||
/// <returns>true if the items was added to the <see cref="ConcurrentHashSet{T}"/>
|
||||
/// successfully; false if it already exists.</returns>
|
||||
/// <exception cref="T:System.OverflowException">The <see cref="ConcurrentHashSet{T}"/>
|
||||
/// contains too many items.</exception>
|
||||
public bool Add(T item) =>
|
||||
AddInternal(item, _comparer.GetHashCode(item), true);
|
||||
|
||||
/// <summary>
|
||||
/// Removes all items from the <see cref="ConcurrentHashSet{T}"/>.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
var locksAcquired = 0;
|
||||
try
|
||||
{
|
||||
AcquireAllLocks(ref locksAcquired);
|
||||
|
||||
var newTables = new Tables(new Node[DefaultCapacity], _tables.Locks, new int[_tables.CountPerLock.Length]);
|
||||
_tables = newTables;
|
||||
_budget = Math.Max(1, newTables.Buckets.Length / newTables.Locks.Length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseLocks(0, locksAcquired);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the <see cref="ConcurrentHashSet{T}"/> contains the specified
|
||||
/// item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item to locate in the <see cref="ConcurrentHashSet{T}"/>.</param>
|
||||
/// <returns>true if the <see cref="ConcurrentHashSet{T}"/> contains the item; otherwise, false.</returns>
|
||||
public bool Contains(T item)
|
||||
{
|
||||
var hashcode = _comparer.GetHashCode(item);
|
||||
|
||||
// We must capture the _buckets field in a local variable. It is set to a new table on each table resize.
|
||||
var tables = _tables;
|
||||
|
||||
var bucketNo = GetBucket(hashcode, tables.Buckets.Length);
|
||||
|
||||
// We can get away w/out a lock here.
|
||||
// The Volatile.Read ensures that the load of the fields of 'n' doesn't move before the load from buckets[i].
|
||||
var current = Volatile.Read(ref tables.Buckets[bucketNo]);
|
||||
|
||||
while (current != null)
|
||||
{
|
||||
if (hashcode == current.Hashcode && _comparer.Equals(current.Item, item))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
current = current.Next;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to remove the item from the <see cref="ConcurrentHashSet{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="item">The item to remove.</param>
|
||||
/// <returns>true if an item was removed successfully; otherwise, false.</returns>
|
||||
public bool TryRemove(T item)
|
||||
{
|
||||
var hashcode = _comparer.GetHashCode(item);
|
||||
while (true)
|
||||
{
|
||||
var tables = _tables;
|
||||
|
||||
GetBucketAndLockNo(hashcode, out var bucketNo, out var lockNo, tables.Buckets.Length, tables.Locks.Length);
|
||||
|
||||
lock (tables.Locks[lockNo])
|
||||
{
|
||||
// If the table just got resized, we may not be holding the right lock, and must retry.
|
||||
// This should be a rare occurrence.
|
||||
if (tables != _tables)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Node previous = null;
|
||||
for (var current = tables.Buckets[bucketNo]; current != null; current = current.Next)
|
||||
{
|
||||
Debug.Assert((previous == null && current == tables.Buckets[bucketNo]) || previous.Next == current);
|
||||
|
||||
if (hashcode == current.Hashcode && _comparer.Equals(current.Item, item))
|
||||
{
|
||||
if (previous == null)
|
||||
{
|
||||
Volatile.Write(ref tables.Buckets[bucketNo], current.Next);
|
||||
}
|
||||
else
|
||||
{
|
||||
previous.Next = current.Next;
|
||||
}
|
||||
|
||||
tables.CountPerLock[lockNo]--;
|
||||
return true;
|
||||
}
|
||||
previous = current;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
/// <summary>Returns an enumerator that iterates through the <see
|
||||
/// cref="ConcurrentHashSet{T}"/>.</summary>
|
||||
/// <returns>An enumerator for the <see cref="ConcurrentHashSet{T}"/>.</returns>
|
||||
/// <remarks>
|
||||
/// The enumerator returned from the collection is safe to use concurrently with
|
||||
/// reads and writes to the collection, however it does not represent a moment-in-time snapshot
|
||||
/// of the collection. The contents exposed through the enumerator may contain modifications
|
||||
/// made to the collection after <see cref="GetEnumerator"/> was called.
|
||||
/// </remarks>
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
var buckets = _tables.Buckets;
|
||||
|
||||
for (var i = 0; i < buckets.Length; i++)
|
||||
{
|
||||
// The Volatile.Read ensures that the load of the fields of 'current' doesn't move before the load from buckets[i].
|
||||
var current = Volatile.Read(ref buckets[i]);
|
||||
|
||||
while (current != null)
|
||||
{
|
||||
yield return current.Item;
|
||||
current = current.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ICollection<T>.Add(T item) => Add(item);
|
||||
|
||||
bool ICollection<T>.IsReadOnly => false;
|
||||
|
||||
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
if (array == null) throw new ArgumentNullException(nameof(array));
|
||||
if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
||||
|
||||
var locksAcquired = 0;
|
||||
try
|
||||
{
|
||||
AcquireAllLocks(ref locksAcquired);
|
||||
|
||||
var count = 0;
|
||||
|
||||
for (var i = 0; i < _tables.Locks.Length && count >= 0; i++)
|
||||
{
|
||||
count += _tables.CountPerLock[i];
|
||||
}
|
||||
|
||||
if (array.Length - count < arrayIndex || count < 0) //"count" itself or "count + arrayIndex" can overflow
|
||||
{
|
||||
throw new ArgumentException("The index is equal to or greater than the length of the array, or the number of elements in the set is greater than the available space from index to the end of the destination array.");
|
||||
}
|
||||
|
||||
CopyToItems(array, arrayIndex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseLocks(0, locksAcquired);
|
||||
}
|
||||
}
|
||||
|
||||
bool ICollection<T>.Remove(T item) => TryRemove(item);
|
||||
|
||||
private void InitializeFromCollection(IEnumerable<T> collection)
|
||||
{
|
||||
foreach (var item in collection)
|
||||
{
|
||||
AddInternal(item, _comparer.GetHashCode(item), false);
|
||||
}
|
||||
|
||||
if (_budget == 0)
|
||||
{
|
||||
_budget = _tables.Buckets.Length / _tables.Locks.Length;
|
||||
}
|
||||
}
|
||||
|
||||
private bool AddInternal(T item, int hashcode, bool acquireLock)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var tables = _tables;
|
||||
GetBucketAndLockNo(hashcode, out var bucketNo, out var lockNo, tables.Buckets.Length, tables.Locks.Length);
|
||||
|
||||
var resizeDesired = false;
|
||||
var lockTaken = false;
|
||||
try
|
||||
{
|
||||
if (acquireLock)
|
||||
Monitor.Enter(tables.Locks[lockNo], ref lockTaken);
|
||||
|
||||
// If the table just got resized, we may not be holding the right lock, and must retry.
|
||||
// This should be a rare occurrence.
|
||||
if (tables != _tables)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to find this item in the bucket
|
||||
Node previous = null;
|
||||
for (var current = tables.Buckets[bucketNo]; current != null; current = current.Next)
|
||||
{
|
||||
Debug.Assert((previous == null && current == tables.Buckets[bucketNo]) || previous.Next == current);
|
||||
if (hashcode == current.Hashcode && _comparer.Equals(current.Item, item))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
previous = current;
|
||||
}
|
||||
|
||||
// The item was not found in the bucket. Insert the new item.
|
||||
Volatile.Write(ref tables.Buckets[bucketNo], new Node(item, hashcode, tables.Buckets[bucketNo]));
|
||||
checked
|
||||
{
|
||||
tables.CountPerLock[lockNo]++;
|
||||
}
|
||||
|
||||
//
|
||||
// If the number of elements guarded by this lock has exceeded the budget, resize the bucket table.
|
||||
// It is also possible that GrowTable will increase the budget but won't resize the bucket table.
|
||||
// That happens if the bucket table is found to be poorly utilized due to a bad hash function.
|
||||
//
|
||||
if (tables.CountPerLock[lockNo] > _budget)
|
||||
{
|
||||
resizeDesired = true;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockTaken)
|
||||
Monitor.Exit(tables.Locks[lockNo]);
|
||||
}
|
||||
|
||||
//
|
||||
// The fact that we got here means that we just performed an insertion. If necessary, we will grow the table.
|
||||
//
|
||||
// Concurrency notes:
|
||||
// - Notice that we are not holding any locks at when calling GrowTable. This is necessary to prevent deadlocks.
|
||||
// - As a result, it is possible that GrowTable will be called unnecessarily. But, GrowTable will obtain lock 0
|
||||
// and then verify that the table we passed to it as the argument is still the current table.
|
||||
//
|
||||
if (resizeDesired)
|
||||
{
|
||||
GrowTable(tables);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetBucket(int hashcode, int bucketCount)
|
||||
{
|
||||
var bucketNo = (hashcode & 0x7fffffff) % bucketCount;
|
||||
Debug.Assert(bucketNo >= 0 && bucketNo < bucketCount);
|
||||
return bucketNo;
|
||||
}
|
||||
|
||||
private static void GetBucketAndLockNo(int hashcode, out int bucketNo, out int lockNo, int bucketCount, int lockCount)
|
||||
{
|
||||
bucketNo = (hashcode & 0x7fffffff) % bucketCount;
|
||||
lockNo = bucketNo % lockCount;
|
||||
|
||||
Debug.Assert(bucketNo >= 0 && bucketNo < bucketCount);
|
||||
Debug.Assert(lockNo >= 0 && lockNo < lockCount);
|
||||
}
|
||||
|
||||
private void GrowTable(Tables tables)
|
||||
{
|
||||
const int maxArrayLength = 0X7FEFFFFF;
|
||||
var locksAcquired = 0;
|
||||
try
|
||||
{
|
||||
// The thread that first obtains _locks[0] will be the one doing the resize operation
|
||||
AcquireLocks(0, 1, ref locksAcquired);
|
||||
|
||||
// Make sure nobody resized the table while we were waiting for lock 0:
|
||||
if (tables != _tables)
|
||||
{
|
||||
// We assume that since the table reference is different, it was already resized (or the budget
|
||||
// was adjusted). If we ever decide to do table shrinking, or replace the table for other reasons,
|
||||
// we will have to revisit this logic.
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute the (approx.) total size. Use an Int64 accumulation variable to avoid an overflow.
|
||||
long approxCount = 0;
|
||||
for (var i = 0; i < tables.CountPerLock.Length; i++)
|
||||
{
|
||||
approxCount += tables.CountPerLock[i];
|
||||
}
|
||||
|
||||
//
|
||||
// If the bucket array is too empty, double the budget instead of resizing the table
|
||||
//
|
||||
if (approxCount < tables.Buckets.Length / 4)
|
||||
{
|
||||
_budget = 2 * _budget;
|
||||
if (_budget < 0)
|
||||
{
|
||||
_budget = int.MaxValue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute the new table size. We find the smallest integer larger than twice the previous table size, and not divisible by
|
||||
// 2,3,5 or 7. We can consider a different table-sizing policy in the future.
|
||||
var newLength = 0;
|
||||
var maximizeTableSize = false;
|
||||
try
|
||||
{
|
||||
checked
|
||||
{
|
||||
// Double the size of the buckets table and add one, so that we have an odd integer.
|
||||
newLength = tables.Buckets.Length * 2 + 1;
|
||||
|
||||
// Now, we only need to check odd integers, and find the first that is not divisible
|
||||
// by 3, 5 or 7.
|
||||
while (newLength % 3 == 0 || newLength % 5 == 0 || newLength % 7 == 0)
|
||||
{
|
||||
newLength += 2;
|
||||
}
|
||||
|
||||
Debug.Assert(newLength % 2 != 0);
|
||||
|
||||
if (newLength > maxArrayLength)
|
||||
{
|
||||
maximizeTableSize = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
maximizeTableSize = true;
|
||||
}
|
||||
|
||||
if (maximizeTableSize)
|
||||
{
|
||||
newLength = maxArrayLength;
|
||||
|
||||
// We want to make sure that GrowTable will not be called again, since table is at the maximum size.
|
||||
// To achieve that, we set the budget to int.MaxValue.
|
||||
//
|
||||
// (There is one special case that would allow GrowTable() to be called in the future:
|
||||
// calling Clear() on the ConcurrentHashSet will shrink the table and lower the budget.)
|
||||
_budget = int.MaxValue;
|
||||
}
|
||||
|
||||
// Now acquire all other locks for the table
|
||||
AcquireLocks(1, tables.Locks.Length, ref locksAcquired);
|
||||
|
||||
var newLocks = tables.Locks;
|
||||
|
||||
// Add more locks
|
||||
if (_growLockArray && tables.Locks.Length < MaxLockNumber)
|
||||
{
|
||||
newLocks = new object[tables.Locks.Length * 2];
|
||||
Array.Copy(tables.Locks, 0, newLocks, 0, tables.Locks.Length);
|
||||
for (var i = tables.Locks.Length; i < newLocks.Length; i++)
|
||||
{
|
||||
newLocks[i] = new object();
|
||||
}
|
||||
}
|
||||
|
||||
var newBuckets = new Node[newLength];
|
||||
var newCountPerLock = new int[newLocks.Length];
|
||||
|
||||
// Copy all data into a new table, creating new nodes for all elements
|
||||
for (var i = 0; i < tables.Buckets.Length; i++)
|
||||
{
|
||||
var current = tables.Buckets[i];
|
||||
while (current != null)
|
||||
{
|
||||
var next = current.Next;
|
||||
GetBucketAndLockNo(current.Hashcode, out var newBucketNo, out var newLockNo, newBuckets.Length, newLocks.Length);
|
||||
|
||||
newBuckets[newBucketNo] = new Node(current.Item, current.Hashcode, newBuckets[newBucketNo]);
|
||||
|
||||
checked
|
||||
{
|
||||
newCountPerLock[newLockNo]++;
|
||||
}
|
||||
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust the budget
|
||||
_budget = Math.Max(1, newBuckets.Length / newLocks.Length);
|
||||
|
||||
// Replace tables with the new versions
|
||||
_tables = new Tables(newBuckets, newLocks, newCountPerLock);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Release all locks that we took earlier
|
||||
ReleaseLocks(0, locksAcquired);
|
||||
}
|
||||
}
|
||||
|
||||
public int RemoveWhere(Func<T, bool> predicate)
|
||||
{
|
||||
var elems = this.Where(predicate);
|
||||
var removed = 0;
|
||||
foreach (var elem in elems)
|
||||
{
|
||||
if (this.TryRemove(elem))
|
||||
removed++;
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
private void AcquireAllLocks(ref int locksAcquired)
|
||||
{
|
||||
// First, acquire lock 0
|
||||
AcquireLocks(0, 1, ref locksAcquired);
|
||||
|
||||
// Now that we have lock 0, the _locks array will not change (i.e., grow),
|
||||
// and so we can safely read _locks.Length.
|
||||
AcquireLocks(1, _tables.Locks.Length, ref locksAcquired);
|
||||
Debug.Assert(locksAcquired == _tables.Locks.Length);
|
||||
}
|
||||
|
||||
private void AcquireLocks(int fromInclusive, int toExclusive, ref int locksAcquired)
|
||||
{
|
||||
Debug.Assert(fromInclusive <= toExclusive);
|
||||
var locks = _tables.Locks;
|
||||
|
||||
for (var i = fromInclusive; i < toExclusive; i++)
|
||||
{
|
||||
var lockTaken = false;
|
||||
try
|
||||
{
|
||||
Monitor.Enter(locks[i], ref lockTaken);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockTaken)
|
||||
{
|
||||
locksAcquired++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ReleaseLocks(int fromInclusive, int toExclusive)
|
||||
{
|
||||
Debug.Assert(fromInclusive <= toExclusive);
|
||||
|
||||
for (var i = fromInclusive; i < toExclusive; i++)
|
||||
{
|
||||
Monitor.Exit(_tables.Locks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyToItems(T[] array, int index)
|
||||
{
|
||||
var buckets = _tables.Buckets;
|
||||
for (var i = 0; i < buckets.Length; i++)
|
||||
{
|
||||
for (var current = buckets[i]; current != null; current = current.Next)
|
||||
{
|
||||
array[index] = current.Item;
|
||||
index++; //this should never flow, CopyToItems is only called when there's no overflow risk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class Tables
|
||||
{
|
||||
public readonly Node[] Buckets;
|
||||
public readonly object[] Locks;
|
||||
|
||||
public volatile int[] CountPerLock;
|
||||
|
||||
public Tables(Node[] buckets, object[] locks, int[] countPerLock)
|
||||
{
|
||||
Buckets = buckets;
|
||||
Locks = locks;
|
||||
CountPerLock = countPerLock;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class Node
|
||||
{
|
||||
public readonly T Item;
|
||||
public readonly int Hashcode;
|
||||
|
||||
public volatile Node Next;
|
||||
|
||||
public Node(T item, int hashcode, Node next)
|
||||
{
|
||||
Item = item;
|
||||
Hashcode = hashcode;
|
||||
Next = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
77
NadekoBot.Core/Common/Collections/DisposableImutableList.cs
Normal file
77
NadekoBot.Core/Common/Collections/DisposableImutableList.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NadekoBot.Common.Collections
|
||||
{
|
||||
public static class DisposableReadOnlyListExtensions
|
||||
{
|
||||
public static IDisposableReadOnlyList<T> AsDisposable<T>(this IReadOnlyList<T> arr) where T : IDisposable
|
||||
=> new DisposableReadOnlyList<T>(arr);
|
||||
|
||||
public static IDisposableReadOnlyList<KeyValuePair<TKey, TValue>> AsDisposable<TKey, TValue>(this IReadOnlyList<KeyValuePair<TKey, TValue>> arr) where TValue : IDisposable
|
||||
=> new DisposableReadOnlyList<TKey, TValue>(arr);
|
||||
}
|
||||
|
||||
public interface IDisposableReadOnlyList<T> : IReadOnlyList<T>, IDisposable
|
||||
{
|
||||
}
|
||||
|
||||
public sealed class DisposableReadOnlyList<T> : IDisposableReadOnlyList<T>
|
||||
where T : IDisposable
|
||||
{
|
||||
private readonly IReadOnlyList<T> _arr;
|
||||
|
||||
public int Count => _arr.Count;
|
||||
|
||||
public T this[int index] => _arr[index];
|
||||
|
||||
public DisposableReadOnlyList(IReadOnlyList<T> arr)
|
||||
{
|
||||
this._arr = arr;
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
=> _arr.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
=> _arr.GetEnumerator();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var item in _arr)
|
||||
{
|
||||
item.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class DisposableReadOnlyList<T, U> : IDisposableReadOnlyList<KeyValuePair<T, U>>
|
||||
where U : IDisposable
|
||||
{
|
||||
private readonly IReadOnlyList<KeyValuePair<T, U>> _arr;
|
||||
|
||||
public int Count => _arr.Count;
|
||||
|
||||
KeyValuePair<T, U> IReadOnlyList<KeyValuePair<T, U>>.this[int index] => _arr[index];
|
||||
|
||||
public DisposableReadOnlyList(IReadOnlyList<KeyValuePair<T, U>> arr)
|
||||
{
|
||||
this._arr = arr;
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<T, U>> GetEnumerator() =>
|
||||
_arr.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() =>
|
||||
_arr.GetEnumerator();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var item in _arr)
|
||||
{
|
||||
item.Value.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
141
NadekoBot.Core/Common/Collections/IndexedCollection.cs
Normal file
141
NadekoBot.Core/Common/Collections/IndexedCollection.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NadekoBot.Core.Services.Database.Models;
|
||||
|
||||
namespace NadekoBot.Common.Collections
|
||||
{
|
||||
public class IndexedCollection<T> : IList<T> where T : class, IIndexed
|
||||
{
|
||||
public List<T> Source { get; }
|
||||
private readonly object _locker = new object();
|
||||
|
||||
public int Count => Source.Count;
|
||||
public bool IsReadOnly => false;
|
||||
public int IndexOf(T item) => item.Index;
|
||||
|
||||
public IndexedCollection()
|
||||
{
|
||||
Source = new List<T>();
|
||||
}
|
||||
|
||||
public IndexedCollection(IEnumerable<T> source)
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
Source = source.OrderBy(x => x.Index).ToList();
|
||||
UpdateIndexes();
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateIndexes()
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
for (var i = 0; i < Source.Count; i++)
|
||||
{
|
||||
if (Source[i].Index != i)
|
||||
Source[i].Index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator List<T>(IndexedCollection<T> x) =>
|
||||
x.Source;
|
||||
|
||||
public List<T> ToList() => Source.ToList();
|
||||
|
||||
public IEnumerator<T> GetEnumerator() =>
|
||||
Source.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() =>
|
||||
Source.GetEnumerator();
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
item.Index = Source.Count;
|
||||
Source.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
Source.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
return Source.Contains(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
Source.CopyTo(array, arrayIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Remove(T item)
|
||||
{
|
||||
bool removed;
|
||||
lock (_locker)
|
||||
{
|
||||
if (removed = Source.Remove(item))
|
||||
{
|
||||
for (int i = 0; i < Source.Count; i++)
|
||||
{
|
||||
if (Source[i].Index != i)
|
||||
Source[i].Index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
public virtual void Insert(int index, T item)
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
Source.Insert(index, item);
|
||||
for (int i = index; i < Source.Count; i++)
|
||||
{
|
||||
Source[i].Index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void RemoveAt(int index)
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
Source.RemoveAt(index);
|
||||
for (int i = index; i < Source.Count; i++)
|
||||
{
|
||||
Source[i].Index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual T this[int index]
|
||||
{
|
||||
get { return Source[index]; }
|
||||
set
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
value.Index = index;
|
||||
Source[index] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
NadekoBot.Core/Common/CommandData.cs
Normal file
9
NadekoBot.Core/Common/CommandData.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace NadekoBot.Common
|
||||
{
|
||||
public class CommandData
|
||||
{
|
||||
public string Cmd { get; set; }
|
||||
public string Desc { get; set; }
|
||||
public string[] Usage { get; set; }
|
||||
}
|
||||
}
|
166
NadekoBot.Core/Common/Configs/BotConfig.cs
Normal file
166
NadekoBot.Core/Common/Configs/BotConfig.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using NadekoBot.Common.Yml;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace NadekoBot.Core.Common.Configs
|
||||
{
|
||||
public sealed class BotConfig
|
||||
{
|
||||
[Comment(@"DO NOT CHANGE")]
|
||||
public int Version { get; set; }
|
||||
|
||||
[Comment(@"Most commands, when executed, have a small colored line
|
||||
next to the response. The color depends whether the command
|
||||
is completed, errored or in progress (pending)
|
||||
Color settings below are for the color of those lines.
|
||||
To get color's hex, you can go here https://htmlcolorcodes.com/
|
||||
and copy the hex code fo your selected color (marked as #)")]
|
||||
public ColorConfig Color { get; set; }
|
||||
|
||||
[Comment("Default bot language. It has to be in the list of supported languages (.langli)")]
|
||||
public CultureInfo DefaultLocale { get; set; }
|
||||
|
||||
[Comment(@"Style in which executed commands will show up in the console.
|
||||
Allowed values: Simple, Normal, None")]
|
||||
public ConsoleOutputType ConsoleOutputType { get; set; }
|
||||
|
||||
// [Comment(@"For what kind of updates will the bot check.
|
||||
// Allowed values: Release, Commit, None")]
|
||||
// public UpdateCheckType CheckForUpdates { get; set; }
|
||||
|
||||
// [Comment(@"How often will the bot check for updates, in hours")]
|
||||
// public int CheckUpdateInterval { get; set; }
|
||||
|
||||
[Comment(@"Do you want any messages sent by users in Bot's DM to be forwarded to the owner(s)?")]
|
||||
public bool ForwardMessages { get; set; }
|
||||
|
||||
[Comment(@"Do you want the message to be forwarded only to the first owner specified in the list of owners (in creds.yml),
|
||||
or all owners? (this might cause the bot to lag if there's a lot of owners specified)")]
|
||||
public bool ForwardToAllOwners { get; set; }
|
||||
|
||||
[Comment(@"When a user DMs the bot with a message which is not a command
|
||||
they will receive this message. Leave empty for no response. The string which will be sent whenever someone DMs the bot.
|
||||
Supports embeds. How it looks: https://puu.sh/B0BLV.png")]
|
||||
[YamlMember(ScalarStyle = ScalarStyle.Literal)]
|
||||
public string DmHelpText { get; set; }
|
||||
|
||||
[Comment(@"This is the response for the .h command")]
|
||||
[YamlMember(ScalarStyle = ScalarStyle.Literal)]
|
||||
public string HelpText { get; set; }
|
||||
[Comment(@"List of modules and commands completely blocked on the bot")]
|
||||
public BlockedConfig Blocked { get; set; }
|
||||
|
||||
[Comment(@"Which string will be used to recognize the commands")]
|
||||
public string Prefix { get; set; }
|
||||
|
||||
[Comment(@"Toggles whether your bot will group greet/bye messages into a single message every 5 seconds.
|
||||
1st user who joins will get greeted immediately
|
||||
If more users join within the next 5 seconds, they will be greeted in groups of 5.
|
||||
This will cause %user.mention% and other placeholders to be replaced with multiple users.
|
||||
Keep in mind this might break some of your embeds - for example if you have %user.avatar% in the thumbnail,
|
||||
it will become invalid, as it will resolve to a list of avatars of grouped users.
|
||||
note: This setting is primarily used if you're afraid of raids, or you're running medium/large bots where some
|
||||
servers might get hundreds of people join at once. This is used to prevent the bot from getting ratelimited,
|
||||
and (slightly) reduce the greet spam in those servers.")]
|
||||
public bool GroupGreets { get; set; }
|
||||
[Comment(@"Whether the bot will rotate through all specified statuses.
|
||||
This setting can be changed via .rots command.
|
||||
See RotatingStatuses submodule in Administration.")]
|
||||
public bool RotateStatuses { get; set; }
|
||||
|
||||
// [Comment(@"Whether the prefix will be a suffix, or prefix.
|
||||
// For example, if your prefix is ! you will run a command called 'cash' by typing either
|
||||
// '!cash @Someone' if your prefixIsSuffix: false or
|
||||
// 'cash @Someone!' if your prefixIsSuffix: true")]
|
||||
// public bool PrefixIsSuffix { get; set; }
|
||||
|
||||
// public string Prefixed(string text) => PrefixIsSuffix
|
||||
// ? text + Prefix
|
||||
// : Prefix + text;
|
||||
|
||||
public string Prefixed(string text)
|
||||
=> Prefix + text;
|
||||
|
||||
public BotConfig()
|
||||
{
|
||||
Version = 1;
|
||||
var color = new ColorConfig();
|
||||
Color = color;
|
||||
DefaultLocale = new CultureInfo("en-US");
|
||||
ConsoleOutputType = ConsoleOutputType.Normal;
|
||||
ForwardMessages = false;
|
||||
ForwardToAllOwners = false;
|
||||
DmHelpText = @"{""description"": ""Type `%prefix%h` for help.""}";
|
||||
HelpText = @"{
|
||||
""title"": ""To invite me to your server, use this link"",
|
||||
""description"": ""https://discordapp.com/oauth2/authorize?client_id={0}&scope=bot&permissions=66186303"",
|
||||
""color"": 53380,
|
||||
""thumbnail"": ""https://i.imgur.com/nKYyqMK.png"",
|
||||
""fields"": [
|
||||
{
|
||||
""name"": ""Useful help commands"",
|
||||
""value"": ""`%bot.prefix%modules` Lists all bot modules.
|
||||
`%prefix%h CommandName` Shows some help about a specific command.
|
||||
`%prefix%commands ModuleName` Lists all commands in a module."",
|
||||
""inline"": false
|
||||
},
|
||||
{
|
||||
""name"": ""List of all Commands"",
|
||||
""value"": ""https://nadeko.bot/commands"",
|
||||
""inline"": false
|
||||
},
|
||||
{
|
||||
""name"": ""Nadeko Support Server"",
|
||||
""value"": ""https://discord.nadeko.bot/ "",
|
||||
""inline"": true
|
||||
}
|
||||
]
|
||||
}";
|
||||
var blocked = new BlockedConfig();
|
||||
Blocked = blocked;
|
||||
Prefix = ".";
|
||||
RotateStatuses = false;
|
||||
GroupGreets = false;
|
||||
}
|
||||
}
|
||||
|
||||
public class BlockedConfig
|
||||
{
|
||||
public HashSet<string> Commands { get; set; }
|
||||
public HashSet<string> Modules { get; set; }
|
||||
|
||||
public BlockedConfig()
|
||||
{
|
||||
Modules = new HashSet<string>();
|
||||
Commands = new HashSet<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public class ColorConfig
|
||||
{
|
||||
[Comment(@"Color used for embed responses when command successfully executes")]
|
||||
public Rgba32 Ok { get; set; }
|
||||
|
||||
[Comment(@"Color used for embed responses when command has an error")]
|
||||
public Rgba32 Error { get; set; }
|
||||
|
||||
[Comment(@"Color used for embed responses while command is doing work or is in progress")]
|
||||
public Rgba32 Pending { get; set; }
|
||||
|
||||
public ColorConfig()
|
||||
{
|
||||
Ok = Rgba32.ParseHex("00e584");
|
||||
Error = Rgba32.ParseHex("ee281f");
|
||||
Pending = Rgba32.ParseHex("faa61a");
|
||||
}
|
||||
}
|
||||
public enum ConsoleOutputType
|
||||
{
|
||||
Normal = 0,
|
||||
Simple = 1,
|
||||
None = 2,
|
||||
}
|
||||
}
|
18
NadekoBot.Core/Common/Configs/IConfigSeria.cs
Normal file
18
NadekoBot.Core/Common/Configs/IConfigSeria.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace NadekoBot.Core.Common.Configs
|
||||
{
|
||||
/// <summary>
|
||||
/// Base interface for available config serializers
|
||||
/// </summary>
|
||||
public interface IConfigSeria
|
||||
{
|
||||
/// <summary>
|
||||
/// Serialize the object to string
|
||||
/// </summary>
|
||||
public string Serialize<T>(T obj);
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize string data into an object of the specified type
|
||||
/// </summary>
|
||||
public T Deserialize<T>(string data);
|
||||
}
|
||||
}
|
43
NadekoBot.Core/Common/DownloadTracker.cs
Normal file
43
NadekoBot.Core/Common/DownloadTracker.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using NadekoBot.Core.Services;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public class DownloadTracker : INService
|
||||
{
|
||||
private ConcurrentDictionary<ulong, DateTime> LastDownloads { get; } = new ConcurrentDictionary<ulong, DateTime>();
|
||||
private SemaphoreSlim downloadUsersSemaphore = new SemaphoreSlim(1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// Ensures all users on the specified guild were downloaded within the last hour.
|
||||
/// </summary>
|
||||
/// <param name="guild">Guild to check and potentially download users from</param>
|
||||
/// <returns>Task representing download state</returns>
|
||||
public async Task EnsureUsersDownloadedAsync(IGuild guild)
|
||||
{
|
||||
await downloadUsersSemaphore.WaitAsync();
|
||||
try
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
// download once per hour at most
|
||||
var added = LastDownloads.AddOrUpdate(
|
||||
guild.Id,
|
||||
now,
|
||||
(key, old) => (now - old) > TimeSpan.FromHours(1) ? now : old);
|
||||
|
||||
// means that this entry was just added - download the users
|
||||
if (added == now)
|
||||
await guild.DownloadUsersAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
downloadUsersSemaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NadekoBot.Core.Common;
|
||||
using NadekoBot.Core.Modules.Music;
|
||||
using NadekoBot.Core.Services;
|
||||
using NadekoBot.Modules.Administration.Services;
|
||||
using NadekoBot.Modules.Music.Resolvers;
|
||||
using NadekoBot.Modules.Music.Services;
|
||||
|
||||
namespace NadekoBot.Extensions
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddBotStringsServices(this IServiceCollection services)
|
||||
=> services
|
||||
.AddSingleton<IStringsSource, LocalFileStringsSource>()
|
||||
.AddSingleton<IBotStringsProvider, LocalBotStringsProvider>()
|
||||
.AddSingleton<IBotStrings, BotStrings>();
|
||||
|
||||
public static IServiceCollection AddConfigServices(this IServiceCollection services)
|
||||
{
|
||||
var baseType = typeof(ConfigServiceBase<>);
|
||||
|
||||
foreach (var type in Assembly.GetCallingAssembly().ExportedTypes.Where(x => x.IsSealed))
|
||||
{
|
||||
if (type.BaseType?.IsGenericType == true && type.BaseType.GetGenericTypeDefinition() == baseType)
|
||||
{
|
||||
services.AddSingleton(type);
|
||||
services.AddSingleton(x => (IConfigService)x.GetRequiredService(type));
|
||||
}
|
||||
}
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddConfigMigrators(this IServiceCollection services)
|
||||
=> services.AddSealedSubclassesOf(typeof(IConfigMigrator));
|
||||
|
||||
public static IServiceCollection AddMusic(this IServiceCollection services)
|
||||
=> services
|
||||
.AddSingleton<IMusicService, MusicService>()
|
||||
.AddSingleton<ITrackResolveProvider, TrackResolveProvider>()
|
||||
.AddSingleton<IYoutubeResolver, YtdlYoutubeResolver>()
|
||||
.AddSingleton<ISoundcloudResolver, SoundcloudResolver>()
|
||||
.AddSingleton<ILocalTrackResolver, LocalTrackResolver>()
|
||||
.AddSingleton<IRadioResolver, RadioResolver>()
|
||||
.AddSingleton<ITrackCacher, RedisTrackCacher>()
|
||||
.AddSingleton<YtLoader>()
|
||||
.AddSingleton<IPlaceholderProvider>(svc => svc.GetService<IMusicService>());
|
||||
|
||||
// consider using scrutor, because slightly different versions
|
||||
// of this might be needed in several different places
|
||||
public static IServiceCollection AddSealedSubclassesOf(this IServiceCollection services, Type baseType)
|
||||
{
|
||||
var subTypes = Assembly.GetCallingAssembly()
|
||||
.ExportedTypes
|
||||
.Where(type => type.IsSealed && baseType.IsAssignableFrom(type));
|
||||
|
||||
foreach (var subType in subTypes)
|
||||
{
|
||||
services.AddSingleton(baseType, subType);
|
||||
}
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
255
NadekoBot.Core/Common/GuildPerm.cs
Normal file
255
NadekoBot.Core/Common/GuildPerm.cs
Normal file
@@ -0,0 +1,255 @@
|
||||
using System;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
// just a copy paste from discord.net in order to rename it, for compatibility iwth v3 which is gonna use custom lib
|
||||
|
||||
|
||||
// Summary:
|
||||
// Defines the available permissions for a channel.
|
||||
[Flags]
|
||||
public enum GuildPerm : ulong
|
||||
{
|
||||
//
|
||||
// Summary:
|
||||
// Allows creation of instant invites.
|
||||
CreateInstantInvite = 1,
|
||||
//
|
||||
// Summary:
|
||||
// Allows kicking members.
|
||||
//
|
||||
// Remarks:
|
||||
// This permission requires the owner account to use two-factor authentication when
|
||||
// used on a guild that has server-wide 2FA enabled.
|
||||
KickMembers = 2,
|
||||
//
|
||||
// Summary:
|
||||
// Allows banning members.
|
||||
//
|
||||
// Remarks:
|
||||
// This permission requires the owner account to use two-factor authentication when
|
||||
// used on a guild that has server-wide 2FA enabled.
|
||||
BanMembers = 4,
|
||||
//
|
||||
// Summary:
|
||||
// Allows all permissions and bypasses channel permission overwrites.
|
||||
//
|
||||
// Remarks:
|
||||
// This permission requires the owner account to use two-factor authentication when
|
||||
// used on a guild that has server-wide 2FA enabled.
|
||||
Administrator = 8,
|
||||
//
|
||||
// Summary:
|
||||
// Allows management and editing of channels.
|
||||
//
|
||||
// Remarks:
|
||||
// This permission requires the owner account to use two-factor authentication when
|
||||
// used on a guild that has server-wide 2FA enabled.
|
||||
ManageChannels = 16,
|
||||
//
|
||||
// Summary:
|
||||
// Allows management and editing of the guild.
|
||||
//
|
||||
// Remarks:
|
||||
// This permission requires the owner account to use two-factor authentication when
|
||||
// used on a guild that has server-wide 2FA enabled.
|
||||
ManageGuild = 32,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for the addition of reactions to messages.
|
||||
AddReactions = 64,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for viewing of audit logs.
|
||||
ViewAuditLog = 128,
|
||||
PrioritySpeaker = 256,
|
||||
ReadMessages = 1024,
|
||||
ViewChannel = 1024,
|
||||
SendMessages = 2048,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for sending of text-to-speech messages.
|
||||
SendTTSMessages = 4096,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for deletion of other users messages.
|
||||
//
|
||||
// Remarks:
|
||||
// This permission requires the owner account to use two-factor authentication when
|
||||
// used on a guild that has server-wide 2FA enabled.
|
||||
ManageMessages = 8192,
|
||||
//
|
||||
// Summary:
|
||||
// Allows links sent by users with this permission will be auto-embedded.
|
||||
EmbedLinks = 16384,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for uploading images and files.
|
||||
AttachFiles = 32768,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for reading of message history.
|
||||
ReadMessageHistory = 65536,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for using the @everyone tag to notify all users in a channel, and the
|
||||
// @here tag to notify all online users in a channel.
|
||||
MentionEveryone = 131072,
|
||||
//
|
||||
// Summary:
|
||||
// Allows the usage of custom emojis from other servers.
|
||||
UseExternalEmojis = 262144,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for joining of a voice channel.
|
||||
Connect = 1048576,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for speaking in a voice channel.
|
||||
Speak = 2097152,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for muting members in a voice channel.
|
||||
MuteMembers = 4194304,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for deafening of members in a voice channel.
|
||||
DeafenMembers = 8388608,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for moving of members between voice channels.
|
||||
MoveMembers = 16777216,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for using voice-activity-detection in a voice channel.
|
||||
UseVAD = 33554432,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for modification of own nickname.
|
||||
ChangeNickname = 67108864,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for modification of other users nicknames.
|
||||
ManageNicknames = 134217728,
|
||||
//
|
||||
// Summary:
|
||||
// Allows management and editing of roles.
|
||||
//
|
||||
// Remarks:
|
||||
// This permission requires the owner account to use two-factor authentication when
|
||||
// used on a guild that has server-wide 2FA enabled.
|
||||
ManageRoles = 268435456,
|
||||
//
|
||||
// Summary:
|
||||
// Allows management and editing of webhooks.
|
||||
//
|
||||
// Remarks:
|
||||
// This permission requires the owner account to use two-factor authentication when
|
||||
// used on a guild that has server-wide 2FA enabled.
|
||||
ManageWebhooks = 536870912,
|
||||
//
|
||||
// Summary:
|
||||
// Allows management and editing of emojis.
|
||||
//
|
||||
// Remarks:
|
||||
// This permission requires the owner account to use two-factor authentication when
|
||||
// used on a guild that has server-wide 2FA enabled.
|
||||
ManageEmojis = 1073741824
|
||||
}
|
||||
|
||||
//
|
||||
// Summary:
|
||||
// Defines the available permissions for a channel.
|
||||
[Flags]
|
||||
public enum ChannelPerm : ulong
|
||||
{
|
||||
//
|
||||
// Summary:
|
||||
// Allows creation of instant invites.
|
||||
CreateInstantInvite = 1,
|
||||
//
|
||||
// Summary:
|
||||
// Allows management and editing of channels.
|
||||
ManageChannel = 16,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for the addition of reactions to messages.
|
||||
AddReactions = 64,
|
||||
PrioritySpeaker = 256,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for reading of messages. This flag is obsolete, use Discord.ChannelPermission.ViewChannel
|
||||
// instead.
|
||||
ReadMessages = 1024,
|
||||
//
|
||||
// Summary:
|
||||
// Allows guild members to view a channel, which includes reading messages in text
|
||||
// channels.
|
||||
ViewChannel = 1024,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for sending messages in a channel.
|
||||
SendMessages = 2048,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for sending of text-to-speech messages.
|
||||
SendTTSMessages = 4096,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for deletion of other users messages.
|
||||
ManageMessages = 8192,
|
||||
//
|
||||
// Summary:
|
||||
// Allows links sent by users with this permission will be auto-embedded.
|
||||
EmbedLinks = 16384,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for uploading images and files.
|
||||
AttachFiles = 32768,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for reading of message history.
|
||||
ReadMessageHistory = 65536,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for using the @everyone tag to notify all users in a channel, and the
|
||||
// @here tag to notify all online users in a channel.
|
||||
MentionEveryone = 131072,
|
||||
//
|
||||
// Summary:
|
||||
// Allows the usage of custom emojis from other servers.
|
||||
UseExternalEmojis = 262144,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for joining of a voice channel.
|
||||
Connect = 1048576,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for speaking in a voice channel.
|
||||
Speak = 2097152,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for muting members in a voice channel.
|
||||
MuteMembers = 4194304,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for deafening of members in a voice channel.
|
||||
DeafenMembers = 8388608,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for moving of members between voice channels.
|
||||
MoveMembers = 16777216,
|
||||
//
|
||||
// Summary:
|
||||
// Allows for using voice-activity-detection in a voice channel.
|
||||
UseVAD = 33554432,
|
||||
//
|
||||
// Summary:
|
||||
// Allows management and editing of roles.
|
||||
ManageRoles = 268435456,
|
||||
//
|
||||
// Summary:
|
||||
// Allows management and editing of webhooks.
|
||||
ManageWebhooks = 536870912
|
||||
}
|
||||
}
|
15
NadekoBot.Core/Common/Helpers.cs
Normal file
15
NadekoBot.Core/Common/Helpers.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public static class Helpers
|
||||
{
|
||||
public static void ReadErrorAndExit(int exitCode)
|
||||
{
|
||||
if (!Console.IsInputRedirected)
|
||||
Console.ReadKey();
|
||||
|
||||
Environment.Exit(exitCode);
|
||||
}
|
||||
}
|
||||
}
|
7
NadekoBot.Core/Common/INadekoCommandOptions.cs
Normal file
7
NadekoBot.Core/Common/INadekoCommandOptions.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public interface INadekoCommandOptions
|
||||
{
|
||||
void NormalizeOptions();
|
||||
}
|
||||
}
|
10
NadekoBot.Core/Common/IPlaceholderProvider.cs
Normal file
10
NadekoBot.Core/Common/IPlaceholderProvider.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public interface IPlaceholderProvider
|
||||
{
|
||||
public IEnumerable<(string Name, Func<string> Func)> GetPlaceholders();
|
||||
}
|
||||
}
|
49
NadekoBot.Core/Common/ImageUrls.cs
Normal file
49
NadekoBot.Core/Common/ImageUrls.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public class ImageUrls
|
||||
{
|
||||
public int Version { get; set; } = 2;
|
||||
|
||||
public CoinData Coins { get; set; }
|
||||
public Uri[] Currency { get; set; }
|
||||
public Uri[] Dice { get; set; }
|
||||
public RategirlData Rategirl { get; set; }
|
||||
public XpData Xp { get; set; }
|
||||
|
||||
//new
|
||||
public RipData Rip { get; set; }
|
||||
public SlotData Slots { get; set; }
|
||||
|
||||
public class RipData
|
||||
{
|
||||
public Uri Bg { get; set; }
|
||||
public Uri Overlay { get; set; }
|
||||
}
|
||||
|
||||
public class SlotData
|
||||
{
|
||||
public Uri[] Emojis { get; set; }
|
||||
public Uri[] Numbers { get; set; }
|
||||
public Uri Bg { get; set; }
|
||||
}
|
||||
|
||||
public class CoinData
|
||||
{
|
||||
public Uri[] Heads { get; set; }
|
||||
public Uri[] Tails { get; set; }
|
||||
}
|
||||
|
||||
public class RategirlData
|
||||
{
|
||||
public Uri Matrix { get; set; }
|
||||
public Uri Dot { get; set; }
|
||||
}
|
||||
|
||||
public class XpData
|
||||
{
|
||||
public Uri Bg { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
34
NadekoBot.Core/Common/JsonConverters/Rbga32Converter.cs
Normal file
34
NadekoBot.Core/Common/JsonConverters/Rbga32Converter.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
|
||||
namespace NadekoBot.Core.Common.JsonConverters
|
||||
{
|
||||
public class Rgba32Converter : JsonConverter<Rgba32>
|
||||
{
|
||||
public override Rgba32 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
return Rgba32.ParseHex(reader.GetString());
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, Rgba32 value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStringValue(value.ToHex());
|
||||
}
|
||||
}
|
||||
|
||||
public class CultureInfoConverter : JsonConverter<CultureInfo>
|
||||
{
|
||||
public override CultureInfo Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
return new CultureInfo(reader.GetString());
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, CultureInfo value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStringValue(value.Name);
|
||||
}
|
||||
}
|
||||
}
|
98
NadekoBot.Core/Common/Kwum.cs
Normal file
98
NadekoBot.Core/Common/Kwum.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
// needs proper invalid input check (character array input out of range)
|
||||
// needs negative number support
|
||||
public readonly struct kwum : IEquatable<kwum>
|
||||
{
|
||||
private readonly int _value;
|
||||
private const string ValidCharacters = "23456789abcdefghijkmnpqrstuvwxyz";
|
||||
|
||||
public kwum(int num)
|
||||
=> _value = num;
|
||||
|
||||
public kwum(in char c)
|
||||
{
|
||||
if (!IsValidChar(c))
|
||||
throw new ArgumentException("Character needs to be a valid kwum character.", nameof(c));
|
||||
|
||||
_value = InternalCharToValue(c);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int InternalCharToValue(in char c)
|
||||
=> ValidCharacters.IndexOf(c);
|
||||
|
||||
public kwum(in ReadOnlySpan<char> input)
|
||||
{;
|
||||
_value = 0;
|
||||
for (var index = 0; index < input.Length; index++)
|
||||
{
|
||||
var c = input[index];
|
||||
if (!IsValidChar(c))
|
||||
throw new ArgumentException("All characters need to be a valid kwum characters.", nameof(input));
|
||||
|
||||
_value += ValidCharacters.IndexOf(c) * (int)Math.Pow(ValidCharacters.Length, input.Length - index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryParse(in ReadOnlySpan<char> input, out kwum value)
|
||||
{
|
||||
value = default;
|
||||
foreach(var c in input)
|
||||
if (!IsValidChar(c))
|
||||
return false;
|
||||
|
||||
value = new kwum(input);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static kwum operator +(kwum left, kwum right)
|
||||
=> new kwum(left._value + right._value);
|
||||
|
||||
public static bool operator ==(kwum left, kwum right)
|
||||
=> left._value == right._value;
|
||||
|
||||
public static bool operator !=(kwum left, kwum right)
|
||||
=> !(left == right);
|
||||
|
||||
public static implicit operator long(kwum kwum)
|
||||
=> kwum._value;
|
||||
|
||||
public static implicit operator int(kwum kwum)
|
||||
=> kwum._value;
|
||||
public static implicit operator kwum(int num)
|
||||
=> new kwum(num);
|
||||
|
||||
public static bool IsValidChar(char c)
|
||||
=> ValidCharacters.Contains(c);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var count = ValidCharacters.Length;
|
||||
var localValue = _value;
|
||||
var arrSize = (int)Math.Log(localValue, count) + 1;
|
||||
Span<char> chars = new char[arrSize];
|
||||
while (localValue > 0)
|
||||
{
|
||||
localValue = Math.DivRem(localValue, count, out var rem);
|
||||
chars[--arrSize] = ValidCharacters[(int)rem];
|
||||
}
|
||||
|
||||
return new string(chars);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is kwum kw && kw == this;
|
||||
|
||||
public bool Equals(kwum other)
|
||||
=> other == this;
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _value.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
14
NadekoBot.Core/Common/LbOpts.cs
Normal file
14
NadekoBot.Core/Common/LbOpts.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using CommandLine;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public class LbOpts : INadekoCommandOptions
|
||||
{
|
||||
[Option('c', "clean", Default = false, HelpText = "Only show users who are on the server.")]
|
||||
public bool Clean { get; set; }
|
||||
public void NormalizeOptions()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
57
NadekoBot.Core/Common/LoginErrorHandler.cs
Normal file
57
NadekoBot.Core/Common/LoginErrorHandler.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Discord.Net;
|
||||
using Serilog;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public class LoginErrorHandler
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Handle(Exception ex)
|
||||
{
|
||||
Log.Fatal(ex, "A fatal error has occurred while attempting to connect to Discord");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Handle(HttpException ex)
|
||||
{
|
||||
switch (ex.HttpCode)
|
||||
{
|
||||
case HttpStatusCode.Unauthorized:
|
||||
Log.Error("Your bot token is wrong.\n" +
|
||||
"You can find the bot token under the Bot tab in the developer page.\n" +
|
||||
"Fix your token in the credentials file and restart the bot");
|
||||
break;
|
||||
|
||||
case HttpStatusCode.BadRequest:
|
||||
Log.Error("Something has been incorrectly formatted in your credentials file.\n" +
|
||||
"Use the JSON Guide as reference to fix it and restart the bot.");
|
||||
Log.Error("If you are on Linux, make sure Redis is installed and running");
|
||||
break;
|
||||
|
||||
case HttpStatusCode.RequestTimeout:
|
||||
Log.Error("The request timed out. Make sure you have no external program blocking the bot " +
|
||||
"from connecting to the internet");
|
||||
break;
|
||||
|
||||
case HttpStatusCode.ServiceUnavailable:
|
||||
case HttpStatusCode.InternalServerError:
|
||||
Log.Error("Discord is having internal issues. Please, try again later");
|
||||
break;
|
||||
|
||||
case HttpStatusCode.TooManyRequests:
|
||||
Log.Error("Your bot has been ratelimited by Discord. Please, try again later.\n" +
|
||||
"Global ratelimits usually last for an hour");
|
||||
break;
|
||||
|
||||
default:
|
||||
Log.Warning("An error occurred while attempting to connect to Discord");
|
||||
break;
|
||||
}
|
||||
|
||||
Log.Fatal(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
23
NadekoBot.Core/Common/ModuleBehaviors/IEarlyBlocker.cs
Normal file
23
NadekoBot.Core/Common/ModuleBehaviors/IEarlyBlocker.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.WebSocket;
|
||||
|
||||
namespace NadekoBot.Common.ModuleBehaviors
|
||||
{
|
||||
/// <summary>
|
||||
/// Implemented by modules which block execution before anything is executed
|
||||
/// </summary>
|
||||
public interface IEarlyBehavior
|
||||
{
|
||||
int Priority { get; }
|
||||
ModuleBehaviorType BehaviorType { get; }
|
||||
|
||||
Task<bool> RunBehavior(DiscordSocketClient client, IGuild guild, IUserMessage msg);
|
||||
}
|
||||
|
||||
public enum ModuleBehaviorType
|
||||
{
|
||||
Blocker,
|
||||
Executor,
|
||||
}
|
||||
}
|
10
NadekoBot.Core/Common/ModuleBehaviors/IINputTransformer.cs
Normal file
10
NadekoBot.Core/Common/ModuleBehaviors/IINputTransformer.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
|
||||
namespace NadekoBot.Common.ModuleBehaviors
|
||||
{
|
||||
public interface IInputTransformer
|
||||
{
|
||||
Task<string> TransformInput(IGuild guild, IMessageChannel channel, IUser user, string input);
|
||||
}
|
||||
}
|
14
NadekoBot.Core/Common/ModuleBehaviors/ILateBlocker.cs
Normal file
14
NadekoBot.Core/Common/ModuleBehaviors/ILateBlocker.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
|
||||
namespace NadekoBot.Common.ModuleBehaviors
|
||||
{
|
||||
public interface ILateBlocker
|
||||
{
|
||||
public int Priority { get; }
|
||||
|
||||
Task<bool> TryBlockLate(DiscordSocketClient client, ICommandContext context,
|
||||
string moduleName, CommandInfo command);
|
||||
}
|
||||
}
|
14
NadekoBot.Core/Common/ModuleBehaviors/ILateExecutor.cs
Normal file
14
NadekoBot.Core/Common/ModuleBehaviors/ILateExecutor.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.WebSocket;
|
||||
|
||||
namespace NadekoBot.Common.ModuleBehaviors
|
||||
{
|
||||
/// <summary>
|
||||
/// Last thing to be executed, won't stop further executions
|
||||
/// </summary>
|
||||
public interface ILateExecutor
|
||||
{
|
||||
Task LateExecute(DiscordSocketClient client, IGuild guild, IUserMessage msg);
|
||||
}
|
||||
}
|
34
NadekoBot.Core/Common/ModuleBehaviors/IModuleBehavior.cs
Normal file
34
NadekoBot.Core/Common/ModuleBehaviors/IModuleBehavior.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using Discord;
|
||||
using Discord.WebSocket;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Common.ModuleBehaviors
|
||||
{
|
||||
public struct ModuleBehaviorResult
|
||||
{
|
||||
public bool Blocked { get; set; }
|
||||
public string NewInput { get; set; }
|
||||
|
||||
public static ModuleBehaviorResult None() => new ModuleBehaviorResult
|
||||
{
|
||||
Blocked = false,
|
||||
NewInput = null,
|
||||
};
|
||||
|
||||
public static ModuleBehaviorResult FromBlocked(bool blocked) => new ModuleBehaviorResult
|
||||
{
|
||||
Blocked = blocked,
|
||||
NewInput = null,
|
||||
};
|
||||
}
|
||||
|
||||
public interface IModuleBehavior
|
||||
{
|
||||
/// <summary>
|
||||
/// Negative priority means it will try to apply as early as possible
|
||||
/// Positive priority menas it will try to apply as late as possible
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
Task<ModuleBehaviorResult> ApplyBehavior(DiscordSocketClient client, IGuild guild, IUserMessage msg);
|
||||
}
|
||||
}
|
16
NadekoBot.Core/Common/ModuleBehaviors/IReadyExecutor.cs
Normal file
16
NadekoBot.Core/Common/ModuleBehaviors/IReadyExecutor.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Common.ModuleBehaviors
|
||||
{
|
||||
/// <summary>
|
||||
/// All services which need to execute something after
|
||||
/// the bot is ready should implement this interface
|
||||
/// </summary>
|
||||
public interface IReadyExecutor
|
||||
{
|
||||
/// <summary>
|
||||
/// Executed when bot is ready
|
||||
/// </summary>
|
||||
public Task OnReadyAsync();
|
||||
}
|
||||
}
|
155
NadekoBot.Core/Common/NadekoModule.cs
Normal file
155
NadekoBot.Core/Common/NadekoModule.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
using NadekoBot.Core.Services;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules
|
||||
{
|
||||
public abstract class NadekoModule : ModuleBase
|
||||
{
|
||||
protected CultureInfo _cultureInfo { get; set; }
|
||||
public IBotStrings Strings { get; set; }
|
||||
public CommandHandler CmdHandler { get; set; }
|
||||
public ILocalization Localization { get; set; }
|
||||
|
||||
public string Prefix => CmdHandler.GetPrefix(ctx.Guild);
|
||||
|
||||
protected ICommandContext ctx => Context;
|
||||
|
||||
protected NadekoModule()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void BeforeExecute(CommandInfo cmd)
|
||||
{
|
||||
_cultureInfo = Localization.GetCultureInfo(ctx.Guild?.Id);
|
||||
}
|
||||
|
||||
protected string GetText(string key) =>
|
||||
Strings.GetText(key, _cultureInfo);
|
||||
|
||||
protected string GetText(string key, params object[] args) =>
|
||||
Strings.GetText(key, _cultureInfo, args);
|
||||
|
||||
public Task<IUserMessage> ErrorLocalizedAsync(string textKey, params object[] args)
|
||||
{
|
||||
var text = GetText(textKey, args);
|
||||
return ctx.Channel.SendErrorAsync(text);
|
||||
}
|
||||
|
||||
public Task<IUserMessage> ReplyErrorLocalizedAsync(string textKey, params object[] args)
|
||||
{
|
||||
var text = GetText(textKey, args);
|
||||
return ctx.Channel.SendErrorAsync(Format.Bold(ctx.User.ToString()) + " " + text);
|
||||
}
|
||||
public Task<IUserMessage> ReplyPendingLocalizedAsync(string textKey, params object[] args)
|
||||
{
|
||||
var text = GetText(textKey, args);
|
||||
return ctx.Channel.SendPendingAsync(Format.Bold(ctx.User.ToString()) + " " + text);
|
||||
}
|
||||
|
||||
public Task<IUserMessage> ConfirmLocalizedAsync(string textKey, params object[] args)
|
||||
{
|
||||
var text = GetText(textKey, args);
|
||||
return ctx.Channel.SendConfirmAsync(text);
|
||||
}
|
||||
|
||||
public Task<IUserMessage> ReplyConfirmLocalizedAsync(string textKey, params object[] args)
|
||||
{
|
||||
var text = GetText(textKey, args);
|
||||
return ctx.Channel.SendConfirmAsync(Format.Bold(ctx.User.ToString()) + " " + text);
|
||||
}
|
||||
|
||||
public async Task<bool> PromptUserConfirmAsync(EmbedBuilder embed)
|
||||
{
|
||||
embed
|
||||
.WithPendingColor()
|
||||
.WithFooter("yes/no");
|
||||
|
||||
var msg = await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var input = await GetUserInputAsync(ctx.User.Id, ctx.Channel.Id).ConfigureAwait(false);
|
||||
input = input?.ToUpperInvariant();
|
||||
|
||||
if (input != "YES" && input != "Y")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
var _ = Task.Run(() => msg.DeleteAsync());
|
||||
}
|
||||
}
|
||||
|
||||
// TypeConverter typeConverter = TypeDescriptor.GetConverter(propType); ?
|
||||
public async Task<string> GetUserInputAsync(ulong userId, ulong channelId)
|
||||
{
|
||||
var userInputTask = new TaskCompletionSource<string>();
|
||||
var dsc = (DiscordSocketClient)ctx.Client;
|
||||
try
|
||||
{
|
||||
dsc.MessageReceived += MessageReceived;
|
||||
|
||||
if ((await Task.WhenAny(userInputTask.Task, Task.Delay(10000)).ConfigureAwait(false)) != userInputTask.Task)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return await userInputTask.Task.ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
dsc.MessageReceived -= MessageReceived;
|
||||
}
|
||||
|
||||
Task MessageReceived(SocketMessage arg)
|
||||
{
|
||||
var _ = Task.Run(() =>
|
||||
{
|
||||
if (!(arg is SocketUserMessage userMsg) ||
|
||||
!(userMsg.Channel is ITextChannel chan) ||
|
||||
userMsg.Author.Id != userId ||
|
||||
userMsg.Channel.Id != channelId)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (userInputTask.TrySetResult(arg.Content))
|
||||
{
|
||||
userMsg.DeleteAfter(1);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class NadekoModule<TService> : NadekoModule
|
||||
{
|
||||
public TService _service { get; set; }
|
||||
|
||||
protected NadekoModule() : base()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class NadekoSubmodule : NadekoModule
|
||||
{
|
||||
protected NadekoSubmodule() : base() { }
|
||||
}
|
||||
|
||||
public abstract class NadekoSubmodule<TService> : NadekoModule<TService>
|
||||
{
|
||||
protected NadekoSubmodule() : base()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
7
NadekoBot.Core/Common/NadekoModuleExtensions.cs
Normal file
7
NadekoBot.Core/Common/NadekoModuleExtensions.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace NadekoBot.Modules
|
||||
{
|
||||
public static class NadekoModuleExtensions
|
||||
{
|
||||
|
||||
}
|
||||
}
|
74
NadekoBot.Core/Common/NadekoRandom.cs
Normal file
74
NadekoBot.Core/Common/NadekoRandom.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace NadekoBot.Common
|
||||
{
|
||||
public class NadekoRandom : Random
|
||||
{
|
||||
readonly RandomNumberGenerator _rng;
|
||||
|
||||
public NadekoRandom() : base()
|
||||
{
|
||||
_rng = RandomNumberGenerator.Create();
|
||||
}
|
||||
|
||||
public override int Next()
|
||||
{
|
||||
var bytes = new byte[sizeof(int)];
|
||||
_rng.GetBytes(bytes);
|
||||
return Math.Abs(BitConverter.ToInt32(bytes, 0));
|
||||
}
|
||||
|
||||
public override int Next(int maxValue)
|
||||
{
|
||||
if (maxValue <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(maxValue));
|
||||
var bytes = new byte[sizeof(int)];
|
||||
_rng.GetBytes(bytes);
|
||||
return Math.Abs(BitConverter.ToInt32(bytes, 0)) % maxValue;
|
||||
}
|
||||
|
||||
public override int Next(int minValue, int maxValue)
|
||||
{
|
||||
if (minValue > maxValue)
|
||||
throw new ArgumentOutOfRangeException(nameof(maxValue));
|
||||
if (minValue == maxValue)
|
||||
return minValue;
|
||||
var bytes = new byte[sizeof(int)];
|
||||
_rng.GetBytes(bytes);
|
||||
var sign = Math.Sign(BitConverter.ToInt32(bytes, 0));
|
||||
return (sign * BitConverter.ToInt32(bytes, 0)) % (maxValue - minValue) + minValue;
|
||||
}
|
||||
|
||||
public long NextLong(long minValue, long maxValue)
|
||||
{
|
||||
if (minValue > maxValue)
|
||||
throw new ArgumentOutOfRangeException(nameof(maxValue));
|
||||
if (minValue == maxValue)
|
||||
return minValue;
|
||||
var bytes = new byte[sizeof(long)];
|
||||
_rng.GetBytes(bytes);
|
||||
var sign = Math.Sign(BitConverter.ToInt64(bytes, 0));
|
||||
return (sign * BitConverter.ToInt64(bytes, 0)) % (maxValue - minValue) + minValue;
|
||||
}
|
||||
|
||||
public override void NextBytes(byte[] buffer)
|
||||
{
|
||||
_rng.GetBytes(buffer);
|
||||
}
|
||||
|
||||
protected override double Sample()
|
||||
{
|
||||
var bytes = new byte[sizeof(double)];
|
||||
_rng.GetBytes(bytes);
|
||||
return Math.Abs(BitConverter.ToDouble(bytes, 0) / double.MaxValue + 1);
|
||||
}
|
||||
|
||||
public override double NextDouble()
|
||||
{
|
||||
var bytes = new byte[sizeof(double)];
|
||||
_rng.GetBytes(bytes);
|
||||
return BitConverter.ToDouble(bytes, 0);
|
||||
}
|
||||
}
|
||||
}
|
19
NadekoBot.Core/Common/NoPublicBotPrecondition.cs
Normal file
19
NadekoBot.Core/Common/NoPublicBotPrecondition.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace NadekoBot.Common
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
|
||||
public sealed class NoPublicBotAttribute : PreconditionAttribute
|
||||
{
|
||||
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
|
||||
{
|
||||
#if GLOBAL_NADEKO
|
||||
return Task.FromResult(PreconditionResult.FromError("Not available on the public bot"));
|
||||
#else
|
||||
return Task.FromResult(PreconditionResult.FromSuccess());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
24
NadekoBot.Core/Common/OptionsParser.cs
Normal file
24
NadekoBot.Core/Common/OptionsParser.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using CommandLine;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public static class OptionsParser
|
||||
{
|
||||
public static T ParseFrom<T>(string[] args) where T : INadekoCommandOptions, new()
|
||||
=> ParseFrom(new T(), args).Item1;
|
||||
|
||||
public static (T, bool) ParseFrom<T>(T options, string[] args) where T : INadekoCommandOptions
|
||||
{
|
||||
using (var p = new Parser(x =>
|
||||
{
|
||||
x.HelpWriter = null;
|
||||
}))
|
||||
{
|
||||
var res = p.ParseArguments<T>(args);
|
||||
options = res.MapResult(x => x, x => options);
|
||||
options.NormalizeOptions();
|
||||
return (options, res.Tag == ParserResultType.Parsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
NadekoBot.Core/Common/OsuMapData.cs
Normal file
9
NadekoBot.Core/Common/OsuMapData.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public class OsuMapData
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string Artist { get; set; }
|
||||
public string Version { get; set; }
|
||||
}
|
||||
}
|
41
NadekoBot.Core/Common/OsuUserBets.cs
Normal file
41
NadekoBot.Core/Common/OsuUserBets.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public class OsuUserBests
|
||||
{
|
||||
[JsonProperty("beatmap_id")] public string BeatmapId { get; set; }
|
||||
|
||||
[JsonProperty("score_id")] public string ScoreId { get; set; }
|
||||
|
||||
[JsonProperty("score")] public string Score { get; set; }
|
||||
|
||||
[JsonProperty("maxcombo")] public string Maxcombo { get; set; }
|
||||
|
||||
[JsonProperty("count50")] public double Count50 { get; set; }
|
||||
|
||||
[JsonProperty("count100")] public double Count100 { get; set; }
|
||||
|
||||
[JsonProperty("count300")] public double Count300 { get; set; }
|
||||
|
||||
[JsonProperty("countmiss")] public int Countmiss { get; set; }
|
||||
|
||||
[JsonProperty("countkatu")] public double Countkatu { get; set; }
|
||||
|
||||
[JsonProperty("countgeki")] public double Countgeki { get; set; }
|
||||
|
||||
[JsonProperty("perfect")] public string Perfect { get; set; }
|
||||
|
||||
[JsonProperty("enabled_mods")] public int EnabledMods { get; set; }
|
||||
|
||||
[JsonProperty("user_id")] public string UserId { get; set; }
|
||||
|
||||
[JsonProperty("date")] public string Date { get; set; }
|
||||
|
||||
[JsonProperty("rank")] public string Rank { get; set; }
|
||||
|
||||
[JsonProperty("pp")] public double Pp { get; set; }
|
||||
|
||||
[JsonProperty("replay_available")] public string ReplayAvailable { get; set; }
|
||||
}
|
||||
}
|
25
NadekoBot.Core/Common/PlatformHelper.cs
Normal file
25
NadekoBot.Core/Common/PlatformHelper.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
|
||||
namespace NadekoBot.Common
|
||||
{
|
||||
public static class PlatformHelper
|
||||
{
|
||||
private const int ProcessorCountRefreshIntervalMs = 30000;
|
||||
|
||||
private static volatile int _processorCount;
|
||||
private static volatile int _lastProcessorCountRefreshTicks;
|
||||
|
||||
public static int ProcessorCount {
|
||||
get {
|
||||
var now = Environment.TickCount;
|
||||
if (_processorCount == 0 || (now - _lastProcessorCountRefreshTicks) >= ProcessorCountRefreshIntervalMs)
|
||||
{
|
||||
_processorCount = Environment.ProcessorCount;
|
||||
_lastProcessorCountRefreshTicks = now;
|
||||
}
|
||||
|
||||
return _processorCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
NadekoBot.Core/Common/Pokemon/PokemonNameId.cs
Normal file
8
NadekoBot.Core/Common/Pokemon/PokemonNameId.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace NadekoBot.Core.Common.Pokemon
|
||||
{
|
||||
public class PokemonNameId
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
40
NadekoBot.Core/Common/Pokemon/SearchPokemon.cs
Normal file
40
NadekoBot.Core/Common/Pokemon/SearchPokemon.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NadekoBot.Core.Common.Pokemon
|
||||
{
|
||||
public class SearchPokemon
|
||||
{
|
||||
public class GenderRatioClass
|
||||
{
|
||||
public float M { get; set; }
|
||||
public float F { get; set; }
|
||||
}
|
||||
|
||||
public class BaseStatsClass
|
||||
{
|
||||
public int HP { get; set; }
|
||||
public int ATK { get; set; }
|
||||
public int DEF { get; set; }
|
||||
public int SPA { get; set; }
|
||||
public int SPD { get; set; }
|
||||
public int SPE { get; set; }
|
||||
|
||||
public override string ToString() => $@"💚**HP:** {HP,-4} ⚔**ATK:** {ATK,-4} 🛡**DEF:** {DEF,-4}
|
||||
✨**SPA:** {SPA,-4} 🎇**SPD:** {SPD,-4} 💨**SPE:** {SPE,-4}";
|
||||
}
|
||||
|
||||
[JsonProperty("num")]
|
||||
public int Id { get; set; }
|
||||
public string Species { get; set; }
|
||||
public string[] Types { get; set; }
|
||||
public GenderRatioClass GenderRatio { get; set; }
|
||||
public BaseStatsClass BaseStats { get; set; }
|
||||
public Dictionary<string, string> Abilities { get; set; }
|
||||
public float HeightM { get; set; }
|
||||
public float WeightKg { get; set; }
|
||||
public string Color { get; set; }
|
||||
public string[] Evos { get; set; }
|
||||
public string[] EggGroups { get; set; }
|
||||
}
|
||||
}
|
10
NadekoBot.Core/Common/Pokemon/SearchPokemonAbility.cs
Normal file
10
NadekoBot.Core/Common/Pokemon/SearchPokemonAbility.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace NadekoBot.Core.Common.Pokemon
|
||||
{
|
||||
public class SearchPokemonAbility
|
||||
{
|
||||
public string Desc { get; set; }
|
||||
public string ShortDesc { get; set; }
|
||||
public string Name { get; set; }
|
||||
public float Rating { get; set; }
|
||||
}
|
||||
}
|
95
NadekoBot.Core/Common/PubSub/EventPubSub.cs
Normal file
95
NadekoBot.Core/Common/PubSub/EventPubSub.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public class EventPubSub : IPubSub
|
||||
{
|
||||
private readonly Dictionary<string, Dictionary<Delegate, List<Func<object, ValueTask>>>> _actions
|
||||
= new Dictionary<string, Dictionary<Delegate, List<Func<object, ValueTask>>>>();
|
||||
private readonly object locker = new object();
|
||||
|
||||
public Task Sub<TData>(in TypedKey<TData> key, Func<TData, ValueTask> action)
|
||||
{
|
||||
Func<object, ValueTask> localAction = obj => action((TData) obj);
|
||||
lock(locker)
|
||||
{
|
||||
Dictionary<Delegate, List<Func<object, ValueTask>>> keyActions;
|
||||
if (!_actions.TryGetValue(key.Key, out keyActions))
|
||||
{
|
||||
keyActions = new Dictionary<Delegate, List<Func<object, ValueTask>>>();
|
||||
_actions[key.Key] = keyActions;
|
||||
}
|
||||
|
||||
List<Func<object, ValueTask>> sameActions;
|
||||
if (!keyActions.TryGetValue(action, out sameActions))
|
||||
{
|
||||
sameActions = new List<Func<object, ValueTask>>();
|
||||
keyActions[action] = sameActions;
|
||||
}
|
||||
|
||||
sameActions.Add(localAction);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public Task Pub<TData>(in TypedKey<TData> key, TData data)
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
if(_actions.TryGetValue(key.Key, out var actions))
|
||||
{
|
||||
// if this class ever gets used, this needs to be properly implemented
|
||||
// 1. ignore all valuetasks which are completed
|
||||
// 2. return task.whenall all other tasks
|
||||
return Task.WhenAll(actions
|
||||
.SelectMany(kvp => kvp.Value)
|
||||
.Select(action => action(data).AsTask()));
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public Task Unsub<TData>(in TypedKey<TData> key, Func<TData, ValueTask> action)
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
// get subscriptions for this action
|
||||
if (_actions.TryGetValue(key.Key, out var actions))
|
||||
{
|
||||
var hashCode = action.GetHashCode();
|
||||
// get subscriptions which have the same action hash code
|
||||
// note: having this as a list allows for multiple subscriptions of
|
||||
// the same insance's/static method
|
||||
if (actions.TryGetValue(action, out var sameActions))
|
||||
{
|
||||
// remove last subscription
|
||||
sameActions.RemoveAt(sameActions.Count - 1);
|
||||
|
||||
// if the last subscription was the only subscription
|
||||
// we can safely remove this action's dictionary entry
|
||||
if (sameActions.Count == 0)
|
||||
{
|
||||
actions.Remove(action);
|
||||
|
||||
// if our dictionary has no more elements after
|
||||
// removing the entry
|
||||
// it's safe to remove it from the key's subscriptions
|
||||
if (actions.Count == 0)
|
||||
{
|
||||
_actions.Remove(key.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
11
NadekoBot.Core/Common/PubSub/IPubSub.cs
Normal file
11
NadekoBot.Core/Common/PubSub/IPubSub.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public interface IPubSub
|
||||
{
|
||||
public Task Pub<TData>(in TypedKey<TData> key, TData data);
|
||||
public Task Sub<TData>(in TypedKey<TData> key, Func<TData, ValueTask> action);
|
||||
}
|
||||
}
|
8
NadekoBot.Core/Common/PubSub/ISeria.cs
Normal file
8
NadekoBot.Core/Common/PubSub/ISeria.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public interface ISeria
|
||||
{
|
||||
byte[] Serialize<T>(T data);
|
||||
T Deserialize<T>(byte[] data);
|
||||
}
|
||||
}
|
28
NadekoBot.Core/Common/PubSub/JsonSeria.cs
Normal file
28
NadekoBot.Core/Common/PubSub/JsonSeria.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.Text.Json;
|
||||
using NadekoBot.Core.Common.JsonConverters;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public class JsonSeria : ISeria
|
||||
{
|
||||
private JsonSerializerOptions serializerOptions = new JsonSerializerOptions()
|
||||
{
|
||||
Converters =
|
||||
{
|
||||
new Rgba32Converter(),
|
||||
new CultureInfoConverter(),
|
||||
}
|
||||
};
|
||||
public byte[] Serialize<T>(T data)
|
||||
=> JsonSerializer.SerializeToUtf8Bytes(data, serializerOptions);
|
||||
|
||||
public T Deserialize<T>(byte[] data)
|
||||
{
|
||||
if (data is null)
|
||||
return default;
|
||||
|
||||
|
||||
return JsonSerializer.Deserialize<T>(data, serializerOptions);
|
||||
}
|
||||
}
|
||||
}
|
46
NadekoBot.Core/Common/PubSub/RedisPubSub.cs
Normal file
46
NadekoBot.Core/Common/PubSub/RedisPubSub.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using NadekoBot.Core.Services;
|
||||
using NadekoBot.Extensions;
|
||||
using Serilog;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public sealed class RedisPubSub : IPubSub
|
||||
{
|
||||
private readonly ConnectionMultiplexer _multi;
|
||||
private readonly ISeria _serializer;
|
||||
private readonly IBotCredentials _creds;
|
||||
|
||||
public RedisPubSub(ConnectionMultiplexer multi, ISeria serializer, IBotCredentials creds)
|
||||
{
|
||||
_multi = multi;
|
||||
_serializer = serializer;
|
||||
_creds = creds;
|
||||
}
|
||||
|
||||
public Task Pub<TData>(in TypedKey<TData> key, TData data)
|
||||
{
|
||||
var serialized = _serializer.Serialize(data);
|
||||
return _multi.GetSubscriber().PublishAsync($"{_creds.RedisKey()}:{key.Key}", serialized, CommandFlags.FireAndForget);
|
||||
}
|
||||
|
||||
public Task Sub<TData>(in TypedKey<TData> key, Func<TData, ValueTask> action)
|
||||
{
|
||||
var eventName = key.Key;
|
||||
return _multi.GetSubscriber().SubscribeAsync($"{_creds.RedisKey()}:{eventName}", async (ch, data) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var dataObj = _serializer.Deserialize<TData>(data);
|
||||
await action(dataObj);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"Error handling the event {eventName}: {ex.Message}");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
29
NadekoBot.Core/Common/PubSub/TypedKey.cs
Normal file
29
NadekoBot.Core/Common/PubSub/TypedKey.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public readonly struct TypedKey<TData>
|
||||
{
|
||||
public readonly string Key;
|
||||
|
||||
public TypedKey(in string key)
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
|
||||
public static implicit operator TypedKey<TData>(in string input)
|
||||
=> new TypedKey<TData>(input);
|
||||
public static implicit operator string(in TypedKey<TData> input)
|
||||
=> input.Key;
|
||||
|
||||
public static bool operator ==(in TypedKey<TData> left, in TypedKey<TData> right)
|
||||
=> left.Key == right.Key;
|
||||
public static bool operator !=(in TypedKey<TData> left, in TypedKey<TData> right)
|
||||
=> !(left == right);
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is TypedKey<TData> o && o == this;
|
||||
|
||||
public override int GetHashCode() => Key?.GetHashCode() ?? 0;
|
||||
|
||||
public override string ToString() => Key;
|
||||
}
|
||||
}
|
38
NadekoBot.Core/Common/PubSub/YamlSeria.cs
Normal file
38
NadekoBot.Core/Common/PubSub/YamlSeria.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using NadekoBot.Common.Yml;
|
||||
using NadekoBot.Core.Common.Configs;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public class YamlSeria : IConfigSeria
|
||||
{
|
||||
private readonly ISerializer _serializer;
|
||||
private readonly IDeserializer _deserializer;
|
||||
|
||||
private static readonly Regex CodePointRegex
|
||||
= new Regex(@"(\\U(?<code>[a-zA-Z0-9]{8})|\\u(?<code>[a-zA-Z0-9]{4})|\\x(?<code>[a-zA-Z0-9]{2}))",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
public YamlSeria()
|
||||
{
|
||||
_serializer = Yaml.Serializer;
|
||||
_deserializer = Yaml.Deserializer;
|
||||
}
|
||||
|
||||
public string Serialize<T>(T obj)
|
||||
{
|
||||
var escapedOutput = _serializer.Serialize(obj);
|
||||
var output = CodePointRegex.Replace(escapedOutput, me =>
|
||||
{
|
||||
var str = me.Groups["code"].Value;
|
||||
var newString = YamlHelper.UnescapeUnicodeCodePoint(str);
|
||||
return newString;
|
||||
});
|
||||
return output;
|
||||
}
|
||||
|
||||
public T Deserialize<T>(string data)
|
||||
=> _deserializer.Deserialize<T>(data);
|
||||
}
|
||||
}
|
235
NadekoBot.Core/Common/Replacements/ReplacementBuilder.cs
Normal file
235
NadekoBot.Core/Common/Replacements/ReplacementBuilder.cs
Normal file
@@ -0,0 +1,235 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Administration.Services;
|
||||
using NadekoBot.Modules.Music.Services;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using NadekoBot.Core.Common;
|
||||
|
||||
namespace NadekoBot.Common.Replacements
|
||||
{
|
||||
public class ReplacementBuilder
|
||||
{
|
||||
private static readonly Regex rngRegex = new Regex("%rng(?:(?<from>(?:-)?\\d+)-(?<to>(?:-)?\\d+))?%", RegexOptions.Compiled);
|
||||
private ConcurrentDictionary<string, Func<string>> _reps = new ConcurrentDictionary<string, Func<string>>();
|
||||
private ConcurrentDictionary<Regex, Func<Match, string>> _regex = new ConcurrentDictionary<Regex, Func<Match, string>>();
|
||||
|
||||
public ReplacementBuilder()
|
||||
{
|
||||
WithRngRegex();
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithDefault(IUser usr, IMessageChannel ch, SocketGuild g, DiscordSocketClient client)
|
||||
{
|
||||
return this.WithUser(usr)
|
||||
.WithChannel(ch)
|
||||
.WithServer(client, g)
|
||||
.WithClient(client);
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithDefault(ICommandContext ctx) =>
|
||||
WithDefault(ctx.User, ctx.Channel, ctx.Guild as SocketGuild, (DiscordSocketClient)ctx.Client);
|
||||
|
||||
public ReplacementBuilder WithMention(DiscordSocketClient client)
|
||||
{
|
||||
/*OBSOLETE*/
|
||||
_reps.TryAdd("%mention%", () => $"<@{client.CurrentUser.Id}>");
|
||||
/*NEW*/
|
||||
_reps.TryAdd("%bot.mention%", () => client.CurrentUser.Mention);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithClient(DiscordSocketClient client)
|
||||
{
|
||||
WithMention(client);
|
||||
|
||||
/*OBSOLETE*/
|
||||
_reps.TryAdd("%shardid%", () => client.ShardId.ToString());
|
||||
_reps.TryAdd("%time%", () => DateTime.Now.ToString("HH:mm " + TimeZoneInfo.Local.StandardName.GetInitials()));
|
||||
|
||||
/*NEW*/
|
||||
_reps.TryAdd("%bot.status%", () => client.Status.ToString());
|
||||
_reps.TryAdd("%bot.latency%", () => client.Latency.ToString());
|
||||
_reps.TryAdd("%bot.name%", () => client.CurrentUser.Username);
|
||||
_reps.TryAdd("%bot.fullname%", () => client.CurrentUser.ToString());
|
||||
_reps.TryAdd("%bot.time%", () => DateTime.Now.ToString("HH:mm " + TimeZoneInfo.Local.StandardName.GetInitials()));
|
||||
_reps.TryAdd("%bot.discrim%", () => client.CurrentUser.Discriminator);
|
||||
_reps.TryAdd("%bot.id%", () => client.CurrentUser.Id.ToString());
|
||||
_reps.TryAdd("%bot.avatar%", () => client.CurrentUser.RealAvatarUrl()?.ToString());
|
||||
|
||||
WithStats(client);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithServer(DiscordSocketClient client, SocketGuild g)
|
||||
{
|
||||
/*OBSOLETE*/
|
||||
_reps.TryAdd("%sid%", () => g == null ? "DM" : g.Id.ToString());
|
||||
_reps.TryAdd("%server%", () => g == null ? "DM" : g.Name);
|
||||
_reps.TryAdd("%members%", () => g != null && g is SocketGuild sg ? sg.MemberCount.ToString() : "?");
|
||||
_reps.TryAdd("%server_time%", () =>
|
||||
{
|
||||
TimeZoneInfo to = TimeZoneInfo.Local;
|
||||
if (g != null)
|
||||
{
|
||||
if (GuildTimezoneService.AllServices.TryGetValue(client.CurrentUser.Id, out var tz))
|
||||
to = tz.GetTimeZoneOrDefault(g.Id) ?? TimeZoneInfo.Local;
|
||||
}
|
||||
|
||||
return TimeZoneInfo.ConvertTime(DateTime.UtcNow,
|
||||
TimeZoneInfo.Utc,
|
||||
to).ToString("HH:mm ") + to.StandardName.GetInitials();
|
||||
});
|
||||
/*NEW*/
|
||||
_reps.TryAdd("%server.id%", () => g == null ? "DM" : g.Id.ToString());
|
||||
_reps.TryAdd("%server.name%", () => g == null ? "DM" : g.Name);
|
||||
_reps.TryAdd("%server.members%", () => g != null && g is SocketGuild sg ? sg.MemberCount.ToString() : "?");
|
||||
_reps.TryAdd("%server.time%", () =>
|
||||
{
|
||||
TimeZoneInfo to = TimeZoneInfo.Local;
|
||||
if (g != null)
|
||||
{
|
||||
if (GuildTimezoneService.AllServices.TryGetValue(client.CurrentUser.Id, out var tz))
|
||||
to = tz.GetTimeZoneOrDefault(g.Id) ?? TimeZoneInfo.Local;
|
||||
}
|
||||
|
||||
return TimeZoneInfo.ConvertTime(DateTime.UtcNow,
|
||||
TimeZoneInfo.Utc,
|
||||
to).ToString("HH:mm ") + to.StandardName.GetInitials();
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithChannel(IMessageChannel ch)
|
||||
{
|
||||
/*OBSOLETE*/
|
||||
_reps.TryAdd("%channel%", () => (ch as ITextChannel)?.Mention ?? "#" + ch.Name);
|
||||
_reps.TryAdd("%chname%", () => ch.Name);
|
||||
_reps.TryAdd("%cid%", () => ch?.Id.ToString());
|
||||
/*NEW*/
|
||||
_reps.TryAdd("%channel.mention%", () => (ch as ITextChannel)?.Mention ?? "#" + ch.Name);
|
||||
_reps.TryAdd("%channel.name%", () => ch.Name);
|
||||
_reps.TryAdd("%channel.id%", () => ch.Id.ToString());
|
||||
_reps.TryAdd("%channel.created%", () => ch.CreatedAt.ToString("HH:mm dd.MM.yyyy"));
|
||||
_reps.TryAdd("%channel.nsfw%", () => (ch as ITextChannel)?.IsNsfw.ToString() ?? "-");
|
||||
_reps.TryAdd("%channel.topic%", () => (ch as ITextChannel)?.Topic ?? "-");
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithUser(IUser user)
|
||||
{
|
||||
// /*OBSOLETE*/
|
||||
// _reps.TryAdd("%user%", () => user.Mention);
|
||||
// _reps.TryAdd("%userfull%", () => user.ToString());
|
||||
// _reps.TryAdd("%username%", () => user.Username);
|
||||
// _reps.TryAdd("%userdiscrim%", () => user.Discriminator);
|
||||
// _reps.TryAdd("%useravatar%", () => user.RealAvatarUrl()?.ToString());
|
||||
// _reps.TryAdd("%id%", () => user.Id.ToString());
|
||||
// _reps.TryAdd("%uid%", () => user.Id.ToString());
|
||||
// /*NEW*/
|
||||
// _reps.TryAdd("%user.mention%", () => user.Mention);
|
||||
// _reps.TryAdd("%user.fullname%", () => user.ToString());
|
||||
// _reps.TryAdd("%user.name%", () => user.Username);
|
||||
// _reps.TryAdd("%user.discrim%", () => user.Discriminator);
|
||||
// _reps.TryAdd("%user.avatar%", () => user.RealAvatarUrl()?.ToString());
|
||||
// _reps.TryAdd("%user.id%", () => user.Id.ToString());
|
||||
// _reps.TryAdd("%user.created_time%", () => user.CreatedAt.ToString("HH:mm"));
|
||||
// _reps.TryAdd("%user.created_date%", () => user.CreatedAt.ToString("dd.MM.yyyy"));
|
||||
// _reps.TryAdd("%user.joined_time%", () => (user as IGuildUser)?.JoinedAt?.ToString("HH:mm") ?? "-");
|
||||
// _reps.TryAdd("%user.joined_date%", () => (user as IGuildUser)?.JoinedAt?.ToString("dd.MM.yyyy") ?? "-");
|
||||
WithManyUsers(new[] {user});
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithManyUsers(IEnumerable<IUser> users)
|
||||
{
|
||||
/*OBSOLETE*/
|
||||
_reps.TryAdd("%user%", () => string.Join(" ", users.Select(user => user.Mention)));
|
||||
_reps.TryAdd("%userfull%", () => string.Join(" ", users.Select(user => user.ToString())));
|
||||
_reps.TryAdd("%username%", () => string.Join(" ", users.Select(user => user.Username)));
|
||||
_reps.TryAdd("%userdiscrim%", () => string.Join(" ", users.Select(user => user.Discriminator)));
|
||||
_reps.TryAdd("%useravatar%", () => string.Join(" ", users.Select(user => user.RealAvatarUrl()?.ToString())));
|
||||
_reps.TryAdd("%id%", () => string.Join(" ", users.Select(user => user.Id.ToString())));
|
||||
_reps.TryAdd("%uid%", () => string.Join(" ", users.Select(user => user.Id.ToString())));
|
||||
/*NEW*/
|
||||
_reps.TryAdd("%user.mention%", () => string.Join(" ", users.Select(user => user.Mention)));
|
||||
_reps.TryAdd("%user.fullname%", () => string.Join(" ", users.Select(user => user.ToString())));
|
||||
_reps.TryAdd("%user.name%", () => string.Join(" ", users.Select(user => user.Username)));
|
||||
_reps.TryAdd("%user.discrim%", () => string.Join(" ", users.Select(user => user.Discriminator)));
|
||||
_reps.TryAdd("%user.avatar%", () => string.Join(" ", users.Select(user => user.RealAvatarUrl()?.ToString())));
|
||||
_reps.TryAdd("%user.id%", () => string.Join(" ", users.Select(user => user.Id.ToString())));
|
||||
_reps.TryAdd("%user.created_time%", () => string.Join(" ", users.Select(user => user.CreatedAt.ToString("HH:mm"))));
|
||||
_reps.TryAdd("%user.created_date%", () => string.Join(" ", users.Select(user => user.CreatedAt.ToString("dd.MM.yyyy"))));
|
||||
_reps.TryAdd("%user.joined_time%", () => string.Join(" ", users.Select(user => (user as IGuildUser)?.JoinedAt?.ToString("HH:mm") ?? "-")));
|
||||
_reps.TryAdd("%user.joined_date%", () => string.Join(" ", users.Select(user => (user as IGuildUser)?.JoinedAt?.ToString("dd.MM.yyyy") ?? "-")));
|
||||
return this;
|
||||
}
|
||||
|
||||
private ReplacementBuilder WithStats(DiscordSocketClient c)
|
||||
{
|
||||
/*OBSOLETE*/
|
||||
_reps.TryAdd("%servers%", () => c.Guilds.Count.ToString());
|
||||
#if !GLOBAL_NADEKO
|
||||
_reps.TryAdd("%users%", () => c.Guilds.Sum(s => s.Users.Count).ToString());
|
||||
#endif
|
||||
|
||||
/*NEW*/
|
||||
_reps.TryAdd("%shard.servercount%", () => c.Guilds.Count.ToString());
|
||||
#if !GLOBAL_NADEKO
|
||||
_reps.TryAdd("%shard.usercount%", () => c.Guilds.Sum(s => s.Users.Count).ToString());
|
||||
#endif
|
||||
_reps.TryAdd("%shard.id%", () => c.ShardId.ToString());
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithRngRegex()
|
||||
{
|
||||
var rng = new NadekoRandom();
|
||||
_regex.TryAdd(rngRegex, (match) =>
|
||||
{
|
||||
if (!int.TryParse(match.Groups["from"].ToString(), out var from))
|
||||
from = 0;
|
||||
if (!int.TryParse(match.Groups["to"].ToString(), out var to))
|
||||
to = 0;
|
||||
|
||||
if (from == 0 && to == 0)
|
||||
return rng.Next(0, 11).ToString();
|
||||
|
||||
if (from >= to)
|
||||
return string.Empty;
|
||||
|
||||
return rng.Next(from, to + 1).ToString();
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithOverride(string key, Func<string> output)
|
||||
{
|
||||
_reps.AddOrUpdate(key, output, delegate { return output; });
|
||||
return this;
|
||||
}
|
||||
|
||||
public Replacer Build()
|
||||
{
|
||||
return new Replacer(_reps.Select(x => (x.Key, x.Value)).ToArray(), _regex.Select(x => (x.Key, x.Value)).ToArray());
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithProviders(IEnumerable<IPlaceholderProvider> phProviders)
|
||||
{
|
||||
foreach (var provider in phProviders)
|
||||
{
|
||||
foreach (var ovr in provider.GetPlaceholders())
|
||||
{
|
||||
_reps.TryAdd(ovr.Name, ovr.Func);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
66
NadekoBot.Core/Common/Replacements/Replacer.cs
Normal file
66
NadekoBot.Core/Common/Replacements/Replacer.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NadekoBot.Common.Replacements
|
||||
{
|
||||
public class Replacer
|
||||
{
|
||||
private readonly IEnumerable<(string Key, Func<string> Text)> _replacements;
|
||||
private readonly IEnumerable<(Regex Regex, Func<Match, string> Replacement)> _regex;
|
||||
|
||||
public Replacer(IEnumerable<(string, Func<string>)> replacements, IEnumerable<(Regex, Func<Match, string>)> regex)
|
||||
{
|
||||
_replacements = replacements;
|
||||
_regex = regex;
|
||||
}
|
||||
|
||||
public string Replace(string input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
return input;
|
||||
|
||||
foreach (var (Key, Text) in _replacements)
|
||||
{
|
||||
if (input.Contains(Key))
|
||||
input = input.Replace(Key, Text(), StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
foreach (var item in _regex)
|
||||
{
|
||||
input = item.Regex.Replace(input, (m) => item.Replacement(m));
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
public CREmbed Replace(CREmbed embedData)
|
||||
{
|
||||
embedData.PlainText = Replace(embedData.PlainText);
|
||||
embedData.Description = Replace(embedData.Description);
|
||||
embedData.Title = Replace(embedData.Title);
|
||||
embedData.Thumbnail = Replace(embedData.Thumbnail);
|
||||
embedData.Image = Replace(embedData.Image);
|
||||
if (embedData.Author != null)
|
||||
{
|
||||
embedData.Author.Name = Replace(embedData.Author.Name);
|
||||
embedData.Author.IconUrl = Replace(embedData.Author.IconUrl);
|
||||
}
|
||||
|
||||
if (embedData.Fields != null)
|
||||
foreach (var f in embedData.Fields)
|
||||
{
|
||||
f.Name = Replace(f.Name);
|
||||
f.Value = Replace(f.Value);
|
||||
}
|
||||
|
||||
if (embedData.Footer != null)
|
||||
{
|
||||
embedData.Footer.Text = Replace(embedData.Footer.Text);
|
||||
embedData.Footer.IconUrl = Replace(embedData.Footer.IconUrl);
|
||||
}
|
||||
|
||||
return embedData;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
|
||||
namespace NadekoBot.Common
|
||||
{
|
||||
public class RequireObjectPropertiesContractResolver : DefaultContractResolver
|
||||
{
|
||||
protected override JsonObjectContract CreateObjectContract(Type objectType)
|
||||
{
|
||||
var contract = base.CreateObjectContract(objectType);
|
||||
contract.ItemRequired = Required.DisallowNull;
|
||||
return contract;
|
||||
}
|
||||
}
|
||||
}
|
22
NadekoBot.Core/Common/ShardCom/ShardComMessage.cs
Normal file
22
NadekoBot.Core/Common/ShardCom/ShardComMessage.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using Discord;
|
||||
|
||||
namespace NadekoBot.Common.ShardCom
|
||||
{
|
||||
public class ShardComMessage
|
||||
{
|
||||
public int ShardId { get; set; }
|
||||
public ConnectionState ConnectionState { get; set; }
|
||||
public int Guilds { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
|
||||
public ShardComMessage Clone() =>
|
||||
new ShardComMessage
|
||||
{
|
||||
ShardId = ShardId,
|
||||
ConnectionState = ConnectionState,
|
||||
Guilds = Guilds,
|
||||
Time = Time,
|
||||
};
|
||||
}
|
||||
}
|
28
NadekoBot.Core/Common/ShardCom/ShardComServer.cs
Normal file
28
NadekoBot.Core/Common/ShardCom/ShardComServer.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using NadekoBot.Core.Services;
|
||||
|
||||
namespace NadekoBot.Common.ShardCom
|
||||
{
|
||||
public class ShardComServer
|
||||
{
|
||||
private readonly IDataCache _cache;
|
||||
|
||||
public ShardComServer(IDataCache cache)
|
||||
{
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
var sub = _cache.Redis.GetSubscriber();
|
||||
sub.SubscribeAsync("shardcoord_send", (ch, data) =>
|
||||
{
|
||||
var _ = OnDataReceived(JsonConvert.DeserializeObject<ShardComMessage>(data));
|
||||
}, StackExchange.Redis.CommandFlags.FireAndForget);
|
||||
}
|
||||
|
||||
public event Func<ShardComMessage, Task> OnDataReceived = delegate { return Task.CompletedTask; };
|
||||
}
|
||||
}
|
63
NadekoBot.Core/Common/ShmartNumber.cs
Normal file
63
NadekoBot.Core/Common/ShmartNumber.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
|
||||
namespace NadekoBot.Core.Common
|
||||
{
|
||||
public struct ShmartNumber : IEquatable<ShmartNumber>
|
||||
{
|
||||
public long Value { get; }
|
||||
public string Input { get; }
|
||||
|
||||
public ShmartNumber(long val, string input = null)
|
||||
{
|
||||
Value = val;
|
||||
Input = input;
|
||||
}
|
||||
|
||||
public static implicit operator ShmartNumber(long num)
|
||||
{
|
||||
return new ShmartNumber(num);
|
||||
}
|
||||
|
||||
public static implicit operator long(ShmartNumber num)
|
||||
{
|
||||
return num.Value;
|
||||
}
|
||||
|
||||
public static implicit operator ShmartNumber(int num)
|
||||
{
|
||||
return new ShmartNumber(num);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value.ToString();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is ShmartNumber sn
|
||||
? Equals(sn)
|
||||
: false;
|
||||
}
|
||||
|
||||
public bool Equals(ShmartNumber other)
|
||||
{
|
||||
return other.Value == Value;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode() ^ Input.GetHashCode(StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
public static bool operator ==(ShmartNumber left, ShmartNumber right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(ShmartNumber left, ShmartNumber right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
}
|
||||
}
|
91
NadekoBot.Core/Common/SocketMessageEventWrapper.cs
Normal file
91
NadekoBot.Core/Common/SocketMessageEventWrapper.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using Discord;
|
||||
using Discord.WebSocket;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Common
|
||||
{
|
||||
public sealed class ReactionEventWrapper : IDisposable
|
||||
{
|
||||
public IUserMessage Message { get; }
|
||||
public event Action<SocketReaction> OnReactionAdded = delegate { };
|
||||
public event Action<SocketReaction> OnReactionRemoved = delegate { };
|
||||
public event Action OnReactionsCleared = delegate { };
|
||||
|
||||
public ReactionEventWrapper(DiscordSocketClient client, IUserMessage msg)
|
||||
{
|
||||
Message = msg ?? throw new ArgumentNullException(nameof(msg));
|
||||
_client = client;
|
||||
|
||||
_client.ReactionAdded += Discord_ReactionAdded;
|
||||
_client.ReactionRemoved += Discord_ReactionRemoved;
|
||||
_client.ReactionsCleared += Discord_ReactionsCleared;
|
||||
}
|
||||
|
||||
private Task Discord_ReactionsCleared(Cacheable<IUserMessage, ulong> msg, ISocketMessageChannel channel)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (msg.Id == Message.Id)
|
||||
OnReactionsCleared?.Invoke();
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task Discord_ReactionRemoved(Cacheable<IUserMessage, ulong> msg, ISocketMessageChannel channel, SocketReaction reaction)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (msg.Id == Message.Id)
|
||||
OnReactionRemoved?.Invoke(reaction);
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task Discord_ReactionAdded(Cacheable<IUserMessage, ulong> msg, ISocketMessageChannel channel, SocketReaction reaction)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (msg.Id == Message.Id)
|
||||
OnReactionAdded?.Invoke(reaction);
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void UnsubAll()
|
||||
{
|
||||
_client.ReactionAdded -= Discord_ReactionAdded;
|
||||
_client.ReactionRemoved -= Discord_ReactionRemoved;
|
||||
_client.ReactionsCleared -= Discord_ReactionsCleared;
|
||||
OnReactionAdded = null;
|
||||
OnReactionRemoved = null;
|
||||
OnReactionsCleared = null;
|
||||
}
|
||||
|
||||
private bool disposing = false;
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposing)
|
||||
return;
|
||||
disposing = true;
|
||||
UnsubAll();
|
||||
}
|
||||
}
|
||||
}
|
9
NadekoBot.Core/Common/TypeReaders/AddRemove.cs
Normal file
9
NadekoBot.Core/Common/TypeReaders/AddRemove.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace NadekoBot.Common.TypeReaders
|
||||
{
|
||||
public enum AddRemove
|
||||
{
|
||||
Add = int.MinValue,
|
||||
Rem = int.MinValue + 1,
|
||||
Rm = int.MinValue + 1,
|
||||
}
|
||||
}
|
87
NadekoBot.Core/Common/TypeReaders/BotCommandTypeReader.cs
Normal file
87
NadekoBot.Core/Common/TypeReaders/BotCommandTypeReader.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Core.Services;
|
||||
using NadekoBot.Modules.CustomReactions.Services;
|
||||
using NadekoBot.Core.Common.TypeReaders;
|
||||
using Discord.WebSocket;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace NadekoBot.Common.TypeReaders
|
||||
{
|
||||
public class CommandTypeReader : NadekoTypeReader<CommandInfo>
|
||||
{
|
||||
public CommandTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
|
||||
{
|
||||
}
|
||||
|
||||
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
|
||||
{
|
||||
var _cmds = services.GetService<CommandService>();
|
||||
var _cmdHandler = services.GetService<CommandHandler>();
|
||||
input = input.ToUpperInvariant();
|
||||
var prefix = _cmdHandler.GetPrefix(context.Guild);
|
||||
if (!input.StartsWith(prefix.ToUpperInvariant(), StringComparison.InvariantCulture))
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "No such command found."));
|
||||
|
||||
input = input.Substring(prefix.Length);
|
||||
|
||||
var cmd = _cmds.Commands.FirstOrDefault(c =>
|
||||
c.Aliases.Select(a => a.ToUpperInvariant()).Contains(input));
|
||||
if (cmd == null)
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "No such command found."));
|
||||
|
||||
return Task.FromResult(TypeReaderResult.FromSuccess(cmd));
|
||||
}
|
||||
}
|
||||
|
||||
public class CommandOrCrTypeReader : NadekoTypeReader<CommandOrCrInfo>
|
||||
{
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly CommandService _cmds;
|
||||
public CommandOrCrTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
|
||||
{
|
||||
_client = client;
|
||||
_cmds = cmds;
|
||||
}
|
||||
|
||||
public override async Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
|
||||
{
|
||||
input = input.ToUpperInvariant();
|
||||
|
||||
var _crs = services.GetService<CustomReactionsService>();
|
||||
|
||||
if (_crs.ReactionExists(context.Guild?.Id, input))
|
||||
{
|
||||
return TypeReaderResult.FromSuccess(new CommandOrCrInfo(input, CommandOrCrInfo.Type.Custom));
|
||||
}
|
||||
|
||||
var cmd = await new CommandTypeReader(_client, _cmds).ReadAsync(context, input, services).ConfigureAwait(false);
|
||||
if (cmd.IsSuccess)
|
||||
{
|
||||
return TypeReaderResult.FromSuccess(new CommandOrCrInfo(((CommandInfo)cmd.Values.First().Value).Name, CommandOrCrInfo.Type.Normal));
|
||||
}
|
||||
return TypeReaderResult.FromError(CommandError.ParseFailed, "No such command or cr found.");
|
||||
}
|
||||
}
|
||||
|
||||
public class CommandOrCrInfo
|
||||
{
|
||||
public enum Type
|
||||
{
|
||||
Normal,
|
||||
Custom,
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
public Type CmdType { get; set; }
|
||||
public bool IsCustom => CmdType == Type.Custom;
|
||||
|
||||
public CommandOrCrInfo(string input, Type type)
|
||||
{
|
||||
this.Name = input;
|
||||
this.CmdType = type;
|
||||
}
|
||||
}
|
||||
}
|
56
NadekoBot.Core/Common/TypeReaders/GuildDateTimeTypeReader.cs
Normal file
56
NadekoBot.Core/Common/TypeReaders/GuildDateTimeTypeReader.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Modules.Administration.Services;
|
||||
using NadekoBot.Core.Common.TypeReaders;
|
||||
using Discord.WebSocket;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace NadekoBot.Common.TypeReaders
|
||||
{
|
||||
public class GuildDateTimeTypeReader : NadekoTypeReader<GuildDateTime>
|
||||
{
|
||||
public GuildDateTimeTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
|
||||
{
|
||||
}
|
||||
|
||||
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
|
||||
{
|
||||
var gdt = Parse(services, context.Guild.Id, input);
|
||||
if(gdt == null)
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Input string is in an incorrect format."));
|
||||
|
||||
return Task.FromResult(TypeReaderResult.FromSuccess(gdt));
|
||||
}
|
||||
|
||||
public static GuildDateTime Parse(IServiceProvider services, ulong guildId, string input)
|
||||
{
|
||||
var _gts = services.GetService<GuildTimezoneService>();
|
||||
if (!DateTime.TryParse(input, out var dt))
|
||||
return null;
|
||||
|
||||
var tz = _gts.GetTimeZoneOrUtc(guildId);
|
||||
|
||||
return new GuildDateTime(tz, dt);
|
||||
}
|
||||
}
|
||||
|
||||
public class GuildDateTime
|
||||
{
|
||||
public TimeZoneInfo Timezone { get; }
|
||||
public DateTime CurrentGuildTime { get; }
|
||||
public DateTime InputTime { get; }
|
||||
public DateTime InputTimeUtc { get; }
|
||||
|
||||
private GuildDateTime() { }
|
||||
|
||||
public GuildDateTime(TimeZoneInfo guildTimezone, DateTime inputTime)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
Timezone = guildTimezone;
|
||||
CurrentGuildTime = TimeZoneInfo.ConvertTime(now, TimeZoneInfo.Utc, Timezone);
|
||||
InputTime = inputTime;
|
||||
InputTimeUtc = TimeZoneInfo.ConvertTime(inputTime, Timezone, TimeZoneInfo.Utc);
|
||||
}
|
||||
}
|
||||
}
|
33
NadekoBot.Core/Common/TypeReaders/GuildTypeReader.cs
Normal file
33
NadekoBot.Core/Common/TypeReaders/GuildTypeReader.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
using NadekoBot.Core.Common.TypeReaders;
|
||||
using Discord;
|
||||
|
||||
namespace NadekoBot.Common.TypeReaders
|
||||
{
|
||||
public class GuildTypeReader : NadekoTypeReader<IGuild>
|
||||
{
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
||||
public GuildTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
|
||||
{
|
||||
_client = client;
|
||||
}
|
||||
|
||||
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider _)
|
||||
{
|
||||
input = input.Trim().ToUpperInvariant();
|
||||
var guilds = _client.Guilds;
|
||||
var guild = guilds.FirstOrDefault(g => g.Id.ToString().Trim().ToUpperInvariant() == input) ?? //by id
|
||||
guilds.FirstOrDefault(g => g.Name.Trim().ToUpperInvariant() == input); //by name
|
||||
|
||||
if (guild != null)
|
||||
return Task.FromResult(TypeReaderResult.FromSuccess(guild));
|
||||
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "No guild by that name or Id found"));
|
||||
}
|
||||
}
|
||||
}
|
22
NadekoBot.Core/Common/TypeReaders/KwumTypeReader.cs
Normal file
22
NadekoBot.Core/Common/TypeReaders/KwumTypeReader.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
|
||||
namespace NadekoBot.Core.Common.TypeReaders
|
||||
{
|
||||
public class KwumTypeReader : NadekoTypeReader<kwum>
|
||||
{
|
||||
public KwumTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
|
||||
{
|
||||
}
|
||||
|
||||
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
|
||||
{
|
||||
if (kwum.TryParse(input, out var val))
|
||||
return Task.FromResult(TypeReaderResult.FromSuccess(val));
|
||||
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Input is not a valid kwum"));
|
||||
}
|
||||
}
|
||||
}
|
27
NadekoBot.Core/Common/TypeReaders/Models/PermissionAction.cs
Normal file
27
NadekoBot.Core/Common/TypeReaders/Models/PermissionAction.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace NadekoBot.Common.TypeReaders.Models
|
||||
{
|
||||
public class PermissionAction
|
||||
{
|
||||
public static PermissionAction Enable => new PermissionAction(true);
|
||||
public static PermissionAction Disable => new PermissionAction(false);
|
||||
|
||||
public bool Value { get; }
|
||||
|
||||
public PermissionAction(bool value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null || GetType() != obj.GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.Value == ((PermissionAction)obj).Value;
|
||||
}
|
||||
|
||||
public override int GetHashCode() => Value.GetHashCode();
|
||||
}
|
||||
}
|
65
NadekoBot.Core/Common/TypeReaders/Models/StoopidTime.cs
Normal file
65
NadekoBot.Core/Common/TypeReaders/Models/StoopidTime.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NadekoBot.Core.Common.TypeReaders.Models
|
||||
{
|
||||
public class StoopidTime
|
||||
{
|
||||
public string Input { get; set; }
|
||||
public TimeSpan Time { get; set; }
|
||||
|
||||
private static readonly Regex _regex = new Regex(
|
||||
@"^(?:(?<months>\d)mo)?(?:(?<weeks>\d{1,2})w)?(?:(?<days>\d{1,2})d)?(?:(?<hours>\d{1,4})h)?(?:(?<minutes>\d{1,5})m)?(?:(?<seconds>\d{1,6})s)?$",
|
||||
RegexOptions.Compiled | RegexOptions.Multiline);
|
||||
|
||||
private StoopidTime() { }
|
||||
|
||||
public static StoopidTime FromInput(string input)
|
||||
{
|
||||
var m = _regex.Match(input);
|
||||
|
||||
if (m.Length == 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid string input format.");
|
||||
}
|
||||
|
||||
string output = "";
|
||||
var namesAndValues = new Dictionary<string, int>();
|
||||
|
||||
foreach (var groupName in _regex.GetGroupNames())
|
||||
{
|
||||
if (groupName == "0") continue;
|
||||
if (!int.TryParse(m.Groups[groupName].Value, out var value))
|
||||
{
|
||||
namesAndValues[groupName] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value < 1)
|
||||
{
|
||||
throw new ArgumentException($"Invalid {groupName} value.");
|
||||
}
|
||||
|
||||
namesAndValues[groupName] = value;
|
||||
output += m.Groups[groupName].Value + " " + groupName + " ";
|
||||
}
|
||||
var ts = new TimeSpan(30 * namesAndValues["months"] +
|
||||
7 * namesAndValues["weeks"] +
|
||||
namesAndValues["days"],
|
||||
namesAndValues["hours"],
|
||||
namesAndValues["minutes"],
|
||||
namesAndValues["seconds"]);
|
||||
if (ts > TimeSpan.FromDays(90))
|
||||
{
|
||||
throw new ArgumentException("Time is too long.");
|
||||
}
|
||||
|
||||
return new StoopidTime()
|
||||
{
|
||||
Input = input,
|
||||
Time = ts,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
58
NadekoBot.Core/Common/TypeReaders/ModuleTypeReader.cs
Normal file
58
NadekoBot.Core/Common/TypeReaders/ModuleTypeReader.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Core.Common.TypeReaders;
|
||||
using Discord.WebSocket;
|
||||
|
||||
namespace NadekoBot.Common.TypeReaders
|
||||
{
|
||||
public class ModuleTypeReader : NadekoTypeReader<ModuleInfo>
|
||||
{
|
||||
private readonly CommandService _cmds;
|
||||
|
||||
public ModuleTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
|
||||
{
|
||||
_cmds = cmds;
|
||||
}
|
||||
|
||||
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider _)
|
||||
{
|
||||
input = input.ToUpperInvariant();
|
||||
var module = _cmds.Modules.GroupBy(m => m.GetTopLevelModule()).FirstOrDefault(m => m.Key.Name.ToUpperInvariant() == input)?.Key;
|
||||
if (module == null)
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "No such module found."));
|
||||
|
||||
return Task.FromResult(TypeReaderResult.FromSuccess(module));
|
||||
}
|
||||
}
|
||||
|
||||
public class ModuleOrCrTypeReader : NadekoTypeReader<ModuleOrCrInfo>
|
||||
{
|
||||
private readonly CommandService _cmds;
|
||||
|
||||
public ModuleOrCrTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
|
||||
{
|
||||
_cmds = cmds;
|
||||
}
|
||||
|
||||
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider _)
|
||||
{
|
||||
input = input.ToUpperInvariant();
|
||||
var module = _cmds.Modules.GroupBy(m => m.GetTopLevelModule()).FirstOrDefault(m => m.Key.Name.ToUpperInvariant() == input)?.Key;
|
||||
if (module == null && input != "ACTUALCUSTOMREACTIONS")
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "No such module found."));
|
||||
|
||||
return Task.FromResult(TypeReaderResult.FromSuccess(new ModuleOrCrInfo
|
||||
{
|
||||
Name = input,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public class ModuleOrCrInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
18
NadekoBot.Core/Common/TypeReaders/NadekoTypeReader.cs
Normal file
18
NadekoBot.Core/Common/TypeReaders/NadekoTypeReader.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
|
||||
namespace NadekoBot.Core.Common.TypeReaders
|
||||
{
|
||||
public abstract class NadekoTypeReader<T> : TypeReader
|
||||
{
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly CommandService _cmds;
|
||||
|
||||
private NadekoTypeReader() { }
|
||||
protected NadekoTypeReader(DiscordSocketClient client, CommandService cmds)
|
||||
{
|
||||
_client = client;
|
||||
_cmds = cmds;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
using NadekoBot.Common.TypeReaders.Models;
|
||||
using NadekoBot.Core.Common.TypeReaders;
|
||||
|
||||
namespace NadekoBot.Common.TypeReaders
|
||||
{
|
||||
/// <summary>
|
||||
/// Used instead of bool for more flexible keywords for true/false only in the permission module
|
||||
/// </summary>
|
||||
public class PermissionActionTypeReader : NadekoTypeReader<PermissionAction>
|
||||
{
|
||||
public PermissionActionTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
|
||||
{
|
||||
}
|
||||
|
||||
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider _)
|
||||
{
|
||||
input = input.ToUpperInvariant();
|
||||
switch (input)
|
||||
{
|
||||
case "1":
|
||||
case "T":
|
||||
case "TRUE":
|
||||
case "ENABLE":
|
||||
case "ENABLED":
|
||||
case "ALLOW":
|
||||
case "PERMIT":
|
||||
case "UNBAN":
|
||||
return Task.FromResult(TypeReaderResult.FromSuccess(PermissionAction.Enable));
|
||||
case "0":
|
||||
case "F":
|
||||
case "FALSE":
|
||||
case "DENY":
|
||||
case "DISABLE":
|
||||
case "DISABLED":
|
||||
case "DISALLOW":
|
||||
case "BAN":
|
||||
return Task.FromResult(TypeReaderResult.FromSuccess(PermissionAction.Disable));
|
||||
default:
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Did not receive a valid boolean value"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
NadekoBot.Core/Common/TypeReaders/Rgba32TypeReader.cs
Normal file
30
NadekoBot.Core/Common/TypeReaders/Rgba32TypeReader.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
using SixLabors.ImageSharp;
|
||||
|
||||
namespace NadekoBot.Core.Common.TypeReaders
|
||||
{
|
||||
public class Rgba32TypeReader : NadekoTypeReader<Color>
|
||||
{
|
||||
public Rgba32TypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
|
||||
{
|
||||
await Task.Yield();
|
||||
|
||||
input = input.Replace("#", "", StringComparison.InvariantCulture);
|
||||
try
|
||||
{
|
||||
return TypeReaderResult.FromSuccess(Color.ParseHex(input));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return TypeReaderResult.FromError(CommandError.ParseFailed, "Parameter is not a valid color hex.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
109
NadekoBot.Core/Common/TypeReaders/ShmartNumberTypeReader.cs
Normal file
109
NadekoBot.Core/Common/TypeReaders/ShmartNumberTypeReader.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NadekoBot.Core.Services;
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using NadekoBot.Core.Modules.Gambling.Services;
|
||||
|
||||
namespace NadekoBot.Core.Common.TypeReaders
|
||||
{
|
||||
public class ShmartNumberTypeReader : NadekoTypeReader<ShmartNumber>
|
||||
{
|
||||
public ShmartNumberTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
|
||||
{
|
||||
await Task.Yield();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
return TypeReaderResult.FromError(CommandError.ParseFailed, "Input is empty.");
|
||||
|
||||
var i = input.Trim().ToUpperInvariant();
|
||||
|
||||
i = i.Replace("K", "000");
|
||||
|
||||
//can't add m because it will conflict with max atm
|
||||
|
||||
if (TryHandlePercentage(services, context, i, out var num))
|
||||
return TypeReaderResult.FromSuccess(new ShmartNumber(num, i));
|
||||
try
|
||||
{
|
||||
var expr = new NCalc.Expression(i, NCalc.EvaluateOptions.IgnoreCase);
|
||||
expr.EvaluateParameter += (str, ev) => EvaluateParam(str, ev, context, services);
|
||||
var lon = (long)(decimal.Parse(expr.Evaluate().ToString()));
|
||||
return TypeReaderResult.FromSuccess(new ShmartNumber(lon, input));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return TypeReaderResult.FromError(CommandError.ParseFailed, $"Invalid input: {input}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void EvaluateParam(string name, NCalc.ParameterArgs args, ICommandContext ctx, IServiceProvider svc)
|
||||
{
|
||||
switch (name.ToUpperInvariant())
|
||||
{
|
||||
case "PI":
|
||||
args.Result = Math.PI;
|
||||
break;
|
||||
case "E":
|
||||
args.Result = Math.E;
|
||||
break;
|
||||
case "ALL":
|
||||
case "ALLIN":
|
||||
args.Result = Cur(svc, ctx);
|
||||
break;
|
||||
case "HALF":
|
||||
args.Result = Cur(svc, ctx) / 2;
|
||||
break;
|
||||
case "MAX":
|
||||
args.Result = Max(svc, ctx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Regex percentRegex = new Regex(@"^((?<num>100|\d{1,2})%)$", RegexOptions.Compiled);
|
||||
|
||||
private static long Cur(IServiceProvider services, ICommandContext ctx)
|
||||
{
|
||||
var _db = services.GetService<DbService>();
|
||||
long cur;
|
||||
using (var uow = _db.GetDbContext())
|
||||
{
|
||||
cur = uow.DiscordUsers.GetUserCurrency(ctx.User.Id);
|
||||
uow.SaveChanges();
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
private static long Max(IServiceProvider services, ICommandContext ctx)
|
||||
{
|
||||
var settings = services.GetService<GamblingConfigService>().Data;
|
||||
var max = settings.MaxBet;
|
||||
return max == 0
|
||||
? Cur(services, ctx)
|
||||
: max;
|
||||
}
|
||||
|
||||
private static bool TryHandlePercentage(IServiceProvider services, ICommandContext ctx, string input, out long num)
|
||||
{
|
||||
num = 0;
|
||||
var m = percentRegex.Match(input);
|
||||
if (m.Captures.Count != 0)
|
||||
{
|
||||
if (!long.TryParse(m.Groups["num"].ToString(), out var percent))
|
||||
return false;
|
||||
|
||||
num = (long)(Cur(services, ctx) * (percent / 100.0f));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
30
NadekoBot.Core/Common/TypeReaders/StoopidTimeTypeReader.cs
Normal file
30
NadekoBot.Core/Common/TypeReaders/StoopidTimeTypeReader.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Discord.Commands;
|
||||
using Discord.WebSocket;
|
||||
using NadekoBot.Core.Common.TypeReaders.Models;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Core.Common.TypeReaders
|
||||
{
|
||||
public class StoopidTimeTypeReader : NadekoTypeReader<StoopidTime>
|
||||
{
|
||||
public StoopidTimeTypeReader(DiscordSocketClient client, CommandService cmds) : base(client, cmds)
|
||||
{
|
||||
}
|
||||
|
||||
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.Unsuccessful, "Input is empty."));
|
||||
try
|
||||
{
|
||||
var time = StoopidTime.FromInput(input);
|
||||
return Task.FromResult(TypeReaderResult.FromSuccess(time));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.Exception, ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
14
NadekoBot.Core/Common/Yml/CommentAttribute.cs
Normal file
14
NadekoBot.Core/Common/Yml/CommentAttribute.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace NadekoBot.Common.Yml
|
||||
{
|
||||
public class CommentAttribute : Attribute
|
||||
{
|
||||
public string Comment { get; }
|
||||
|
||||
public CommentAttribute(string comment)
|
||||
{
|
||||
Comment = comment;
|
||||
}
|
||||
}
|
||||
}
|
73
NadekoBot.Core/Common/Yml/CommentGatheringTypeInspector.cs
Normal file
73
NadekoBot.Core/Common/Yml/CommentGatheringTypeInspector.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.TypeInspectors;
|
||||
|
||||
namespace NadekoBot.Common.Yml
|
||||
{
|
||||
public class CommentGatheringTypeInspector : TypeInspectorSkeleton
|
||||
{
|
||||
private readonly ITypeInspector innerTypeDescriptor;
|
||||
|
||||
public CommentGatheringTypeInspector(ITypeInspector innerTypeDescriptor)
|
||||
{
|
||||
this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor");
|
||||
}
|
||||
|
||||
public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object container)
|
||||
{
|
||||
return innerTypeDescriptor
|
||||
.GetProperties(type, container)
|
||||
.Select(d => new CommentsPropertyDescriptor(d));
|
||||
}
|
||||
|
||||
private sealed class CommentsPropertyDescriptor : IPropertyDescriptor
|
||||
{
|
||||
private readonly IPropertyDescriptor baseDescriptor;
|
||||
|
||||
public CommentsPropertyDescriptor(IPropertyDescriptor baseDescriptor)
|
||||
{
|
||||
this.baseDescriptor = baseDescriptor;
|
||||
Name = baseDescriptor.Name;
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public Type Type { get { return baseDescriptor.Type; } }
|
||||
|
||||
public Type TypeOverride {
|
||||
get { return baseDescriptor.TypeOverride; }
|
||||
set { baseDescriptor.TypeOverride = value; }
|
||||
}
|
||||
|
||||
public int Order { get; set; }
|
||||
|
||||
public ScalarStyle ScalarStyle {
|
||||
get { return baseDescriptor.ScalarStyle; }
|
||||
set { baseDescriptor.ScalarStyle = value; }
|
||||
}
|
||||
|
||||
public bool CanWrite { get { return baseDescriptor.CanWrite; } }
|
||||
|
||||
public void Write(object target, object value)
|
||||
{
|
||||
baseDescriptor.Write(target, value);
|
||||
}
|
||||
|
||||
public T GetCustomAttribute<T>() where T : Attribute
|
||||
{
|
||||
return baseDescriptor.GetCustomAttribute<T>();
|
||||
}
|
||||
|
||||
public IObjectDescriptor Read(object target)
|
||||
{
|
||||
var comment = baseDescriptor.GetCustomAttribute<CommentAttribute>();
|
||||
return comment != null
|
||||
? new CommentsObjectDescriptor(baseDescriptor.Read(target), comment.Comment)
|
||||
: baseDescriptor.Read(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
NadekoBot.Core/Common/Yml/CommentsObjectDescriptor.cs
Normal file
24
NadekoBot.Core/Common/Yml/CommentsObjectDescriptor.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace NadekoBot.Common.Yml
|
||||
{
|
||||
public sealed class CommentsObjectDescriptor : IObjectDescriptor
|
||||
{
|
||||
private readonly IObjectDescriptor innerDescriptor;
|
||||
|
||||
public CommentsObjectDescriptor(IObjectDescriptor innerDescriptor, string comment)
|
||||
{
|
||||
this.innerDescriptor = innerDescriptor;
|
||||
this.Comment = comment;
|
||||
}
|
||||
|
||||
public string Comment { get; private set; }
|
||||
|
||||
public object Value { get { return innerDescriptor.Value; } }
|
||||
public Type Type { get { return innerDescriptor.Type; } }
|
||||
public Type StaticType { get { return innerDescriptor.StaticType; } }
|
||||
public ScalarStyle ScalarStyle { get { return innerDescriptor.ScalarStyle; } }
|
||||
}
|
||||
}
|
26
NadekoBot.Core/Common/Yml/CommentsObjectGraphVisitor.cs
Normal file
26
NadekoBot.Core/Common/Yml/CommentsObjectGraphVisitor.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Core.Events;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.ObjectGraphVisitors;
|
||||
|
||||
namespace NadekoBot.Common.Yml
|
||||
{
|
||||
public class CommentsObjectGraphVisitor : ChainedObjectGraphVisitor
|
||||
{
|
||||
public CommentsObjectGraphVisitor(IObjectGraphVisitor<IEmitter> nextVisitor)
|
||||
: base(nextVisitor)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, IEmitter context)
|
||||
{
|
||||
var commentsDescriptor = value as CommentsObjectDescriptor;
|
||||
if (commentsDescriptor != null && !string.IsNullOrWhiteSpace(commentsDescriptor.Comment))
|
||||
{
|
||||
context.Emit(new Comment(commentsDescriptor.Comment.Replace("\n", "\n# "), false));
|
||||
}
|
||||
|
||||
return base.EnterMapping(key, value, context);
|
||||
}
|
||||
}
|
||||
}
|
32
NadekoBot.Core/Common/Yml/MultilineScalarFlowStyleEmitter.cs
Normal file
32
NadekoBot.Core/Common/Yml/MultilineScalarFlowStyleEmitter.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.EventEmitters;
|
||||
|
||||
namespace NadekoBot.Common.Yml
|
||||
{
|
||||
public class MultilineScalarFlowStyleEmitter : ChainedEventEmitter
|
||||
{
|
||||
public MultilineScalarFlowStyleEmitter(IEventEmitter nextEmitter)
|
||||
: base(nextEmitter) { }
|
||||
|
||||
public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
|
||||
{
|
||||
|
||||
if (typeof(string).IsAssignableFrom(eventInfo.Source.Type))
|
||||
{
|
||||
string value = eventInfo.Source.Value as string;
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
bool isMultiLine = value.IndexOfAny(new char[] { '\r', '\n', '\x85', '\x2028', '\x2029' }) >= 0;
|
||||
if (isMultiLine)
|
||||
eventInfo = new ScalarEventInfo(eventInfo.Source)
|
||||
{
|
||||
Style = ScalarStyle.Literal,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
nextEmitter.Emit(eventInfo, emitter);
|
||||
}
|
||||
}
|
||||
}
|
52
NadekoBot.Core/Common/Yml/Rgba32Converter.cs
Normal file
52
NadekoBot.Core/Common/Yml/Rgba32Converter.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Core.Events;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace NadekoBot.Common.Yml
|
||||
{
|
||||
public class Rgba32Converter : IYamlTypeConverter
|
||||
{
|
||||
public bool Accepts(Type type)
|
||||
{
|
||||
return type == typeof(Rgba32);
|
||||
}
|
||||
|
||||
public object ReadYaml(IParser parser, Type type)
|
||||
{
|
||||
var scalar = parser.Consume<Scalar>();
|
||||
var result = Rgba32.ParseHex(scalar.Value);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void WriteYaml(IEmitter emitter, object value, Type type)
|
||||
{
|
||||
var color = (Rgba32)value;
|
||||
var val = (uint) (color.B << 0 | color.G << 8 | color.R << 16);
|
||||
emitter.Emit(new Scalar(val.ToString("X6").ToLower()));
|
||||
}
|
||||
}
|
||||
|
||||
public class CultureInfoConverter : IYamlTypeConverter
|
||||
{
|
||||
public bool Accepts(Type type)
|
||||
{
|
||||
return type == typeof(CultureInfo);
|
||||
}
|
||||
|
||||
public object ReadYaml(IParser parser, Type type)
|
||||
{
|
||||
var scalar = parser.Consume<Scalar>();
|
||||
var result = new CultureInfo(scalar.Value);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void WriteYaml(IEmitter emitter, object value, Type type)
|
||||
{
|
||||
var ci = (CultureInfo)value;
|
||||
emitter.Emit(new Scalar(ci.Name));
|
||||
}
|
||||
}
|
||||
}
|
28
NadekoBot.Core/Common/Yml/UriConverter.cs
Normal file
28
NadekoBot.Core/Common/Yml/UriConverter.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Core.Events;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace NadekoBot.Common.Yml
|
||||
{
|
||||
public class UriConverter : IYamlTypeConverter
|
||||
{
|
||||
public bool Accepts(Type type)
|
||||
{
|
||||
return type == typeof(Uri);
|
||||
}
|
||||
|
||||
public object ReadYaml(IParser parser, Type type)
|
||||
{
|
||||
var scalar = parser.Consume<Scalar>();
|
||||
var result = new Uri(scalar.Value);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void WriteYaml(IEmitter emitter, object value, Type type)
|
||||
{
|
||||
var uri = (Uri)value;
|
||||
emitter.Emit(new Scalar(uri.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
25
NadekoBot.Core/Common/Yml/Yaml.cs
Normal file
25
NadekoBot.Core/Common/Yml/Yaml.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace NadekoBot.Common.Yml
|
||||
{
|
||||
public class Yaml
|
||||
{
|
||||
public static ISerializer Serializer => new SerializerBuilder()
|
||||
.WithTypeInspector(inner => new CommentGatheringTypeInspector(inner))
|
||||
.WithEmissionPhaseObjectGraphVisitor(args => new CommentsObjectGraphVisitor(args.InnerVisitor))
|
||||
.WithEventEmitter(args => new MultilineScalarFlowStyleEmitter(args))
|
||||
.WithNamingConvention(YamlDotNet.Serialization.NamingConventions.CamelCaseNamingConvention.Instance)
|
||||
.WithIndentedSequences()
|
||||
.WithTypeConverter(new Rgba32Converter())
|
||||
.WithTypeConverter(new CultureInfoConverter())
|
||||
.WithTypeConverter(new UriConverter())
|
||||
.Build();
|
||||
|
||||
public static IDeserializer Deserializer => new DeserializerBuilder()
|
||||
.WithNamingConvention(YamlDotNet.Serialization.NamingConventions.CamelCaseNamingConvention.Instance)
|
||||
.WithTypeConverter(new Rgba32Converter())
|
||||
.WithTypeConverter(new CultureInfoConverter())
|
||||
.WithTypeConverter(new UriConverter())
|
||||
.Build();
|
||||
}
|
||||
}
|
58
NadekoBot.Core/Common/Yml/YamlHelper.cs
Normal file
58
NadekoBot.Core/Common/Yml/YamlHelper.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
namespace NadekoBot.Common.Yml
|
||||
{
|
||||
public class YamlHelper
|
||||
{
|
||||
// https://github.com/aaubry/YamlDotNet/blob/0f4cc205e8b2dd8ef6589d96de32bf608a687c6f/YamlDotNet/Core/Scanner.cs#L1687
|
||||
/// <summary>
|
||||
/// This is modified code from yamldotnet's repo which handles parsing unicode code points
|
||||
/// it is needed as yamldotnet doesn't support unescaped unicode characters
|
||||
/// </summary>
|
||||
/// <param name="point">Unicode code point</param>
|
||||
/// <returns>Actual character</returns>
|
||||
public static string UnescapeUnicodeCodePoint(string point)
|
||||
{
|
||||
var character = 0;
|
||||
|
||||
// Scan the character value.
|
||||
|
||||
foreach(var c in point)
|
||||
{
|
||||
if (!IsHex(c))
|
||||
{
|
||||
return point;
|
||||
}
|
||||
character = (character << 4) + AsHex(c);
|
||||
}
|
||||
|
||||
// Check the value and write the character.
|
||||
|
||||
if (character >= 0xD800 && character <= 0xDFFF || character > 0x10FFFF)
|
||||
{
|
||||
return point;
|
||||
}
|
||||
|
||||
return char.ConvertFromUtf32(character);
|
||||
}
|
||||
|
||||
public static bool IsHex(char c)
|
||||
{
|
||||
return
|
||||
(c >= '0' && c <= '9') ||
|
||||
(c >= 'A' && c <= 'F') ||
|
||||
(c >= 'a' && c <= 'f');
|
||||
}
|
||||
|
||||
public static int AsHex(char c)
|
||||
{
|
||||
if (c <= '9')
|
||||
{
|
||||
return c - '0';
|
||||
}
|
||||
if (c <= 'F')
|
||||
{
|
||||
return c - 'A' + 10;
|
||||
}
|
||||
return c - 'a' + 10;
|
||||
}
|
||||
}
|
||||
}
|
759
NadekoBot.Core/Migrations/20161011200458_first.Designer.cs
generated
Normal file
759
NadekoBot.Core/Migrations/20161011200458_first.Designer.cs
generated
Normal file
@@ -0,0 +1,759 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NadekoBot.Core.Services.Database;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
[DbContext(typeof(NadekoContext))]
|
||||
[Migration("20161011200458_first")]
|
||||
partial class first
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431");
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<ulong>("ItemId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("BlacklistItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BotConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("BufferSize");
|
||||
|
||||
b.Property<float>("CurrencyGenerationChance");
|
||||
|
||||
b.Property<int>("CurrencyGenerationCooldown");
|
||||
|
||||
b.Property<string>("CurrencyName");
|
||||
|
||||
b.Property<string>("CurrencyPluralName");
|
||||
|
||||
b.Property<string>("CurrencySign");
|
||||
|
||||
b.Property<string>("DMHelpString");
|
||||
|
||||
b.Property<bool>("ForwardMessages");
|
||||
|
||||
b.Property<bool>("ForwardToAllOwners");
|
||||
|
||||
b.Property<string>("HelpString");
|
||||
|
||||
b.Property<int>("MigrationVersion");
|
||||
|
||||
b.Property<string>("RemindMessageFormat");
|
||||
|
||||
b.Property<bool>("RotatingStatuses");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BotConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("BaseDestroyed");
|
||||
|
||||
b.Property<string>("CallUser");
|
||||
|
||||
b.Property<int>("ClashWarId");
|
||||
|
||||
b.Property<int>("Stars");
|
||||
|
||||
b.Property<DateTime>("TimeAdded");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ClashWarId");
|
||||
|
||||
b.ToTable("ClashCallers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashWar", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<string>("EnemyClan");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Size");
|
||||
|
||||
b.Property<DateTime>("StartedAt");
|
||||
|
||||
b.Property<int>("WarState");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ClashOfClans");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("CommandName");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int>("Seconds");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("CommandCooldown");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ConvertUnit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("InternalTrigger");
|
||||
|
||||
b.Property<decimal>("Modifier");
|
||||
|
||||
b.Property<string>("UnitType");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ConversionUnits");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Currency", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CustomReaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong?>("GuildId");
|
||||
|
||||
b.Property<bool>("IsRegex");
|
||||
|
||||
b.Property<bool>("OwnerOnly");
|
||||
|
||||
b.Property<string>("Response");
|
||||
|
||||
b.Property<string>("Trigger");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CustomReactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Donator", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("Amount");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Donators");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("EightBallResponses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int?>("GuildConfigId1");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.HasIndex("GuildConfigId1");
|
||||
|
||||
b.ToTable("FilterChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<string>("Word");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FilteredWord");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.Property<string>("Username");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FollowedStream");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("GCChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AutoAssignRoleId");
|
||||
|
||||
b.Property<bool>("AutoDeleteByeMessages");
|
||||
|
||||
b.Property<bool>("AutoDeleteGreetMessages");
|
||||
|
||||
b.Property<int>("AutoDeleteGreetMessagesTimer");
|
||||
|
||||
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages");
|
||||
|
||||
b.Property<ulong>("ByeMessageChannelId");
|
||||
|
||||
b.Property<string>("ChannelByeMessageText");
|
||||
|
||||
b.Property<string>("ChannelGreetMessageText");
|
||||
|
||||
b.Property<float>("DefaultMusicVolume");
|
||||
|
||||
b.Property<bool>("DeleteMessageOnCommand");
|
||||
|
||||
b.Property<string>("DmGreetMessageText");
|
||||
|
||||
b.Property<bool>("ExclusiveSelfAssignedRoles");
|
||||
|
||||
b.Property<bool>("FilterInvites");
|
||||
|
||||
b.Property<bool>("FilterWords");
|
||||
|
||||
b.Property<ulong>("GreetMessageChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.Property<string>("PermissionRole");
|
||||
|
||||
b.Property<int?>("RootPermissionId");
|
||||
|
||||
b.Property<bool>("SendChannelByeMessage");
|
||||
|
||||
b.Property<bool>("SendChannelGreetMessage");
|
||||
|
||||
b.Property<bool>("SendDmGreetMessage");
|
||||
|
||||
b.Property<bool>("VerbosePermissions");
|
||||
|
||||
b.Property<bool>("VoicePlusTextEnabled");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.HasIndex("RootPermissionId");
|
||||
|
||||
b.ToTable("GuildConfigs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredLogChannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredVoicePresenceCHannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.LogSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("ChannelCreated");
|
||||
|
||||
b.Property<bool>("ChannelDestroyed");
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("ChannelUpdated");
|
||||
|
||||
b.Property<bool>("IsLogging");
|
||||
|
||||
b.Property<bool>("LogUserPresence");
|
||||
|
||||
b.Property<bool>("LogVoicePresence");
|
||||
|
||||
b.Property<bool>("MessageDeleted");
|
||||
|
||||
b.Property<bool>("MessageUpdated");
|
||||
|
||||
b.Property<bool>("UserBanned");
|
||||
|
||||
b.Property<bool>("UserJoined");
|
||||
|
||||
b.Property<bool>("UserLeft");
|
||||
|
||||
b.Property<ulong>("UserPresenceChannelId");
|
||||
|
||||
b.Property<bool>("UserUnbanned");
|
||||
|
||||
b.Property<bool>("UserUpdated");
|
||||
|
||||
b.Property<ulong>("VoicePresenceChannelId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LogSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("ModuleName");
|
||||
|
||||
b.Property<string>("Prefix");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("ModulePrefixes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.MusicPlaylist", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Author");
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("MusicPlaylists");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("NextId");
|
||||
|
||||
b.Property<int>("PrimaryTarget");
|
||||
|
||||
b.Property<ulong>("PrimaryTargetId");
|
||||
|
||||
b.Property<int>("SecondaryTarget");
|
||||
|
||||
b.Property<string>("SecondaryTargetName");
|
||||
|
||||
b.Property<bool>("State");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NextId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Permission");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Status");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("PlayingStatus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("MusicPlaylistId");
|
||||
|
||||
b.Property<string>("Provider");
|
||||
|
||||
b.Property<int>("ProviderType");
|
||||
|
||||
b.Property<string>("Query");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("Uri");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MusicPlaylistId");
|
||||
|
||||
b.ToTable("PlaylistSong");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Quote", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("AuthorName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<string>("Keyword")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Quotes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Icon");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("RaceAnimals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Reminder", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("IsPrivate");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.Property<ulong>("ServerId");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.Property<DateTime>("When");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Reminders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Repeater", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<TimeSpan>("Interval");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Repeaters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.SelfAssignedRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<ulong>("RoleId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId", "RoleId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SelfAssignableRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("Blacklist")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.ClashWar", "ClashWar")
|
||||
.WithMany("Bases")
|
||||
.HasForeignKey("ClashWarId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("CommandCooldowns")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("EightBallResponses")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterInvitesChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterWordsChannelIds")
|
||||
.HasForeignKey("GuildConfigId1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilteredWords")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FollowedStreams")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("GenerateCurrencyChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany()
|
||||
.HasForeignKey("LogSettingId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "RootPermission")
|
||||
.WithMany()
|
||||
.HasForeignKey("RootPermissionId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredChannels")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredVoicePresenceChannelIds")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("ModulePrefixes")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "Next")
|
||||
.WithOne("Previous")
|
||||
.HasForeignKey("NadekoBot.Core.Services.Database.Models.Permission", "NextId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RotatingStatusMessages")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.MusicPlaylist")
|
||||
.WithMany("Songs")
|
||||
.HasForeignKey("MusicPlaylistId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RaceAnimals")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
804
NadekoBot.Core/Migrations/20161011200458_first.cs
Normal file
804
NadekoBot.Core/Migrations/20161011200458_first.cs
Normal file
@@ -0,0 +1,804 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class first : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BotConfig",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
BufferSize = table.Column<ulong>(nullable: false),
|
||||
CurrencyGenerationChance = table.Column<float>(nullable: false),
|
||||
CurrencyGenerationCooldown = table.Column<int>(nullable: false),
|
||||
CurrencyName = table.Column<string>(nullable: true),
|
||||
CurrencyPluralName = table.Column<string>(nullable: true),
|
||||
CurrencySign = table.Column<string>(nullable: true),
|
||||
DMHelpString = table.Column<string>(nullable: true),
|
||||
ForwardMessages = table.Column<bool>(nullable: false),
|
||||
ForwardToAllOwners = table.Column<bool>(nullable: false),
|
||||
HelpString = table.Column<string>(nullable: true),
|
||||
MigrationVersion = table.Column<int>(nullable: false),
|
||||
RemindMessageFormat = table.Column<string>(nullable: true),
|
||||
RotatingStatuses = table.Column<bool>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BotConfig", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ClashOfClans",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
ChannelId = table.Column<ulong>(nullable: false),
|
||||
EnemyClan = table.Column<string>(nullable: true),
|
||||
GuildId = table.Column<ulong>(nullable: false),
|
||||
Size = table.Column<int>(nullable: false),
|
||||
StartedAt = table.Column<DateTime>(nullable: false),
|
||||
WarState = table.Column<int>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ClashOfClans", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ConversionUnits",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
InternalTrigger = table.Column<string>(nullable: true),
|
||||
Modifier = table.Column<decimal>(nullable: false),
|
||||
UnitType = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ConversionUnits", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Currency",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
Amount = table.Column<long>(nullable: false),
|
||||
UserId = table.Column<ulong>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Currency", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "CustomReactions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
GuildId = table.Column<ulong>(nullable: true),
|
||||
IsRegex = table.Column<bool>(nullable: false),
|
||||
OwnerOnly = table.Column<bool>(nullable: false),
|
||||
Response = table.Column<string>(nullable: true),
|
||||
Trigger = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_CustomReactions", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Donators",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
Amount = table.Column<int>(nullable: false),
|
||||
Name = table.Column<string>(nullable: true),
|
||||
UserId = table.Column<ulong>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Donators", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "LogSettings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
ChannelCreated = table.Column<bool>(nullable: false),
|
||||
ChannelDestroyed = table.Column<bool>(nullable: false),
|
||||
ChannelId = table.Column<ulong>(nullable: false),
|
||||
ChannelUpdated = table.Column<bool>(nullable: false),
|
||||
IsLogging = table.Column<bool>(nullable: false),
|
||||
LogUserPresence = table.Column<bool>(nullable: false),
|
||||
LogVoicePresence = table.Column<bool>(nullable: false),
|
||||
MessageDeleted = table.Column<bool>(nullable: false),
|
||||
MessageUpdated = table.Column<bool>(nullable: false),
|
||||
UserBanned = table.Column<bool>(nullable: false),
|
||||
UserJoined = table.Column<bool>(nullable: false),
|
||||
UserLeft = table.Column<bool>(nullable: false),
|
||||
UserPresenceChannelId = table.Column<ulong>(nullable: false),
|
||||
UserUnbanned = table.Column<bool>(nullable: false),
|
||||
UserUpdated = table.Column<bool>(nullable: false),
|
||||
VoicePresenceChannelId = table.Column<ulong>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_LogSettings", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "MusicPlaylists",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
Author = table.Column<string>(nullable: true),
|
||||
AuthorId = table.Column<ulong>(nullable: false),
|
||||
Name = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_MusicPlaylists", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Permission",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
NextId = table.Column<int>(nullable: true),
|
||||
PrimaryTarget = table.Column<int>(nullable: false),
|
||||
PrimaryTargetId = table.Column<ulong>(nullable: false),
|
||||
SecondaryTarget = table.Column<int>(nullable: false),
|
||||
SecondaryTargetName = table.Column<string>(nullable: true),
|
||||
State = table.Column<bool>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Permission", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Permission_Permission_NextId",
|
||||
column: x => x.NextId,
|
||||
principalTable: "Permission",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Quotes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
AuthorId = table.Column<ulong>(nullable: false),
|
||||
AuthorName = table.Column<string>(nullable: false),
|
||||
GuildId = table.Column<ulong>(nullable: false),
|
||||
Keyword = table.Column<string>(nullable: false),
|
||||
Text = table.Column<string>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Quotes", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Reminders",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
ChannelId = table.Column<ulong>(nullable: false),
|
||||
IsPrivate = table.Column<bool>(nullable: false),
|
||||
Message = table.Column<string>(nullable: true),
|
||||
ServerId = table.Column<ulong>(nullable: false),
|
||||
UserId = table.Column<ulong>(nullable: false),
|
||||
When = table.Column<DateTime>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Reminders", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Repeaters",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
ChannelId = table.Column<ulong>(nullable: false),
|
||||
GuildId = table.Column<ulong>(nullable: false),
|
||||
Interval = table.Column<TimeSpan>(nullable: false),
|
||||
Message = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Repeaters", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SelfAssignableRoles",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
GuildId = table.Column<ulong>(nullable: false),
|
||||
RoleId = table.Column<ulong>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SelfAssignableRoles", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "BlacklistItem",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
BotConfigId = table.Column<int>(nullable: true),
|
||||
ItemId = table.Column<ulong>(nullable: false),
|
||||
Type = table.Column<int>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_BlacklistItem", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_BlacklistItem_BotConfig_BotConfigId",
|
||||
column: x => x.BotConfigId,
|
||||
principalTable: "BotConfig",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "EightBallResponses",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
BotConfigId = table.Column<int>(nullable: true),
|
||||
Text = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_EightBallResponses", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_EightBallResponses_BotConfig_BotConfigId",
|
||||
column: x => x.BotConfigId,
|
||||
principalTable: "BotConfig",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ModulePrefixes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
BotConfigId = table.Column<int>(nullable: true),
|
||||
ModuleName = table.Column<string>(nullable: true),
|
||||
Prefix = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ModulePrefixes", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ModulePrefixes_BotConfig_BotConfigId",
|
||||
column: x => x.BotConfigId,
|
||||
principalTable: "BotConfig",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PlayingStatus",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
BotConfigId = table.Column<int>(nullable: true),
|
||||
Status = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PlayingStatus", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_PlayingStatus_BotConfig_BotConfigId",
|
||||
column: x => x.BotConfigId,
|
||||
principalTable: "BotConfig",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "RaceAnimals",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
BotConfigId = table.Column<int>(nullable: true),
|
||||
Icon = table.Column<string>(nullable: true),
|
||||
Name = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_RaceAnimals", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_RaceAnimals_BotConfig_BotConfigId",
|
||||
column: x => x.BotConfigId,
|
||||
principalTable: "BotConfig",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ClashCallers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
BaseDestroyed = table.Column<bool>(nullable: false),
|
||||
CallUser = table.Column<string>(nullable: true),
|
||||
ClashWarId = table.Column<int>(nullable: false),
|
||||
Stars = table.Column<int>(nullable: false),
|
||||
TimeAdded = table.Column<DateTime>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ClashCallers", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ClashCallers_ClashOfClans_ClashWarId",
|
||||
column: x => x.ClashWarId,
|
||||
principalTable: "ClashOfClans",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "IgnoredLogChannels",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
ChannelId = table.Column<ulong>(nullable: false),
|
||||
LogSettingId = table.Column<int>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_IgnoredLogChannels", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_IgnoredLogChannels_LogSettings_LogSettingId",
|
||||
column: x => x.LogSettingId,
|
||||
principalTable: "LogSettings",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "IgnoredVoicePresenceCHannels",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
ChannelId = table.Column<ulong>(nullable: false),
|
||||
LogSettingId = table.Column<int>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_IgnoredVoicePresenceCHannels", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_IgnoredVoicePresenceCHannels_LogSettings_LogSettingId",
|
||||
column: x => x.LogSettingId,
|
||||
principalTable: "LogSettings",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PlaylistSong",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
MusicPlaylistId = table.Column<int>(nullable: true),
|
||||
Provider = table.Column<string>(nullable: true),
|
||||
ProviderType = table.Column<int>(nullable: false),
|
||||
Query = table.Column<string>(nullable: true),
|
||||
Title = table.Column<string>(nullable: true),
|
||||
Uri = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PlaylistSong", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_PlaylistSong_MusicPlaylists_MusicPlaylistId",
|
||||
column: x => x.MusicPlaylistId,
|
||||
principalTable: "MusicPlaylists",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GuildConfigs",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
AutoAssignRoleId = table.Column<ulong>(nullable: false),
|
||||
AutoDeleteByeMessages = table.Column<bool>(nullable: false),
|
||||
AutoDeleteGreetMessages = table.Column<bool>(nullable: false),
|
||||
AutoDeleteGreetMessagesTimer = table.Column<int>(nullable: false),
|
||||
AutoDeleteSelfAssignedRoleMessages = table.Column<bool>(nullable: false),
|
||||
ByeMessageChannelId = table.Column<ulong>(nullable: false),
|
||||
ChannelByeMessageText = table.Column<string>(nullable: true),
|
||||
ChannelGreetMessageText = table.Column<string>(nullable: true),
|
||||
DefaultMusicVolume = table.Column<float>(nullable: false),
|
||||
DeleteMessageOnCommand = table.Column<bool>(nullable: false),
|
||||
DmGreetMessageText = table.Column<string>(nullable: true),
|
||||
ExclusiveSelfAssignedRoles = table.Column<bool>(nullable: false),
|
||||
FilterInvites = table.Column<bool>(nullable: false),
|
||||
FilterWords = table.Column<bool>(nullable: false),
|
||||
GreetMessageChannelId = table.Column<ulong>(nullable: false),
|
||||
GuildId = table.Column<ulong>(nullable: false),
|
||||
LogSettingId = table.Column<int>(nullable: true),
|
||||
PermissionRole = table.Column<string>(nullable: true),
|
||||
RootPermissionId = table.Column<int>(nullable: true),
|
||||
SendChannelByeMessage = table.Column<bool>(nullable: false),
|
||||
SendChannelGreetMessage = table.Column<bool>(nullable: false),
|
||||
SendDmGreetMessage = table.Column<bool>(nullable: false),
|
||||
VerbosePermissions = table.Column<bool>(nullable: false),
|
||||
VoicePlusTextEnabled = table.Column<bool>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GuildConfigs", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GuildConfigs_LogSettings_LogSettingId",
|
||||
column: x => x.LogSettingId,
|
||||
principalTable: "LogSettings",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_GuildConfigs_Permission_RootPermissionId",
|
||||
column: x => x.RootPermissionId,
|
||||
principalTable: "Permission",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "CommandCooldown",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
CommandName = table.Column<string>(nullable: true),
|
||||
GuildConfigId = table.Column<int>(nullable: true),
|
||||
Seconds = table.Column<int>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_CommandCooldown", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_CommandCooldown_GuildConfigs_GuildConfigId",
|
||||
column: x => x.GuildConfigId,
|
||||
principalTable: "GuildConfigs",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "FilterChannelId",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
ChannelId = table.Column<ulong>(nullable: false),
|
||||
GuildConfigId = table.Column<int>(nullable: true),
|
||||
GuildConfigId1 = table.Column<int>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_FilterChannelId", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_FilterChannelId_GuildConfigs_GuildConfigId",
|
||||
column: x => x.GuildConfigId,
|
||||
principalTable: "GuildConfigs",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_FilterChannelId_GuildConfigs_GuildConfigId1",
|
||||
column: x => x.GuildConfigId1,
|
||||
principalTable: "GuildConfigs",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "FilteredWord",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
GuildConfigId = table.Column<int>(nullable: true),
|
||||
Word = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_FilteredWord", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_FilteredWord_GuildConfigs_GuildConfigId",
|
||||
column: x => x.GuildConfigId,
|
||||
principalTable: "GuildConfigs",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "FollowedStream",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
ChannelId = table.Column<ulong>(nullable: false),
|
||||
GuildConfigId = table.Column<int>(nullable: true),
|
||||
GuildId = table.Column<ulong>(nullable: false),
|
||||
Type = table.Column<int>(nullable: false),
|
||||
Username = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_FollowedStream", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_FollowedStream_GuildConfigs_GuildConfigId",
|
||||
column: x => x.GuildConfigId,
|
||||
principalTable: "GuildConfigs",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GCChannelId",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
ChannelId = table.Column<ulong>(nullable: false),
|
||||
GuildConfigId = table.Column<int>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GCChannelId", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_GCChannelId_GuildConfigs_GuildConfigId",
|
||||
column: x => x.GuildConfigId,
|
||||
principalTable: "GuildConfigs",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_BlacklistItem_BotConfigId",
|
||||
table: "BlacklistItem",
|
||||
column: "BotConfigId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ClashCallers_ClashWarId",
|
||||
table: "ClashCallers",
|
||||
column: "ClashWarId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CommandCooldown_GuildConfigId",
|
||||
table: "CommandCooldown",
|
||||
column: "GuildConfigId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Currency_UserId",
|
||||
table: "Currency",
|
||||
column: "UserId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Donators_UserId",
|
||||
table: "Donators",
|
||||
column: "UserId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_EightBallResponses_BotConfigId",
|
||||
table: "EightBallResponses",
|
||||
column: "BotConfigId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_FilterChannelId_GuildConfigId",
|
||||
table: "FilterChannelId",
|
||||
column: "GuildConfigId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_FilterChannelId_GuildConfigId1",
|
||||
table: "FilterChannelId",
|
||||
column: "GuildConfigId1");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_FilteredWord_GuildConfigId",
|
||||
table: "FilteredWord",
|
||||
column: "GuildConfigId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_FollowedStream_GuildConfigId",
|
||||
table: "FollowedStream",
|
||||
column: "GuildConfigId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GCChannelId_GuildConfigId",
|
||||
table: "GCChannelId",
|
||||
column: "GuildConfigId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GuildConfigs_GuildId",
|
||||
table: "GuildConfigs",
|
||||
column: "GuildId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GuildConfigs_LogSettingId",
|
||||
table: "GuildConfigs",
|
||||
column: "LogSettingId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_GuildConfigs_RootPermissionId",
|
||||
table: "GuildConfigs",
|
||||
column: "RootPermissionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_IgnoredLogChannels_LogSettingId",
|
||||
table: "IgnoredLogChannels",
|
||||
column: "LogSettingId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_IgnoredVoicePresenceCHannels_LogSettingId",
|
||||
table: "IgnoredVoicePresenceCHannels",
|
||||
column: "LogSettingId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ModulePrefixes_BotConfigId",
|
||||
table: "ModulePrefixes",
|
||||
column: "BotConfigId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Permission_NextId",
|
||||
table: "Permission",
|
||||
column: "NextId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PlayingStatus_BotConfigId",
|
||||
table: "PlayingStatus",
|
||||
column: "BotConfigId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PlaylistSong_MusicPlaylistId",
|
||||
table: "PlaylistSong",
|
||||
column: "MusicPlaylistId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RaceAnimals_BotConfigId",
|
||||
table: "RaceAnimals",
|
||||
column: "BotConfigId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Repeaters_channelId",
|
||||
table: "Repeaters",
|
||||
column: "ChannelId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SelfAssignableRoles_GuildId_RoleId",
|
||||
table: "SelfAssignableRoles",
|
||||
columns: new[] { "GuildId", "RoleId" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "BlacklistItem");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ClashCallers");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "CommandCooldown");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ConversionUnits");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Currency");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "CustomReactions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Donators");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "EightBallResponses");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "FilterChannelId");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "FilteredWord");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "FollowedStream");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "GCChannelId");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "IgnoredLogChannels");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "IgnoredVoicePresenceCHannels");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ModulePrefixes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PlayingStatus");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PlaylistSong");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Quotes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "RaceAnimals");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Reminders");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Repeaters");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SelfAssignableRoles");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ClashOfClans");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "GuildConfigs");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "MusicPlaylists");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "BotConfig");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "LogSettings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Permission");
|
||||
}
|
||||
}
|
||||
}
|
775
NadekoBot.Core/Migrations/20161015005020_CurrencyTransaction.Designer.cs
generated
Normal file
775
NadekoBot.Core/Migrations/20161015005020_CurrencyTransaction.Designer.cs
generated
Normal file
@@ -0,0 +1,775 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NadekoBot.Core.Services.Database;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
[DbContext(typeof(NadekoContext))]
|
||||
[Migration("20161015005020_CurrencyTransaction")]
|
||||
partial class CurrencyTransaction
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431");
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<ulong>("ItemId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("BlacklistItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BotConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("BufferSize");
|
||||
|
||||
b.Property<float>("CurrencyGenerationChance");
|
||||
|
||||
b.Property<int>("CurrencyGenerationCooldown");
|
||||
|
||||
b.Property<string>("CurrencyName");
|
||||
|
||||
b.Property<string>("CurrencyPluralName");
|
||||
|
||||
b.Property<string>("CurrencySign");
|
||||
|
||||
b.Property<string>("DMHelpString");
|
||||
|
||||
b.Property<bool>("ForwardMessages");
|
||||
|
||||
b.Property<bool>("ForwardToAllOwners");
|
||||
|
||||
b.Property<string>("HelpString");
|
||||
|
||||
b.Property<int>("MigrationVersion");
|
||||
|
||||
b.Property<string>("RemindMessageFormat");
|
||||
|
||||
b.Property<bool>("RotatingStatuses");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BotConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("BaseDestroyed");
|
||||
|
||||
b.Property<string>("CallUser");
|
||||
|
||||
b.Property<int>("ClashWarId");
|
||||
|
||||
b.Property<int>("Stars");
|
||||
|
||||
b.Property<DateTime>("TimeAdded");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ClashWarId");
|
||||
|
||||
b.ToTable("ClashCallers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashWar", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<string>("EnemyClan");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Size");
|
||||
|
||||
b.Property<DateTime>("StartedAt");
|
||||
|
||||
b.Property<int>("WarState");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ClashOfClans");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("CommandName");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int>("Seconds");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("CommandCooldown");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ConvertUnit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("InternalTrigger");
|
||||
|
||||
b.Property<decimal>("Modifier");
|
||||
|
||||
b.Property<string>("UnitType");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ConversionUnits");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Currency", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CurrencyTransaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<string>("Reason");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CustomReaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong?>("GuildId");
|
||||
|
||||
b.Property<bool>("IsRegex");
|
||||
|
||||
b.Property<bool>("OwnerOnly");
|
||||
|
||||
b.Property<string>("Response");
|
||||
|
||||
b.Property<string>("Trigger");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CustomReactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Donator", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("Amount");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Donators");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("EightBallResponses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int?>("GuildConfigId1");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.HasIndex("GuildConfigId1");
|
||||
|
||||
b.ToTable("FilterChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<string>("Word");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FilteredWord");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.Property<string>("Username");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FollowedStream");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("GCChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AutoAssignRoleId");
|
||||
|
||||
b.Property<bool>("AutoDeleteByeMessages");
|
||||
|
||||
b.Property<bool>("AutoDeleteGreetMessages");
|
||||
|
||||
b.Property<int>("AutoDeleteGreetMessagesTimer");
|
||||
|
||||
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages");
|
||||
|
||||
b.Property<ulong>("ByeMessageChannelId");
|
||||
|
||||
b.Property<string>("ChannelByeMessageText");
|
||||
|
||||
b.Property<string>("ChannelGreetMessageText");
|
||||
|
||||
b.Property<float>("DefaultMusicVolume");
|
||||
|
||||
b.Property<bool>("DeleteMessageOnCommand");
|
||||
|
||||
b.Property<string>("DmGreetMessageText");
|
||||
|
||||
b.Property<bool>("ExclusiveSelfAssignedRoles");
|
||||
|
||||
b.Property<bool>("FilterInvites");
|
||||
|
||||
b.Property<bool>("FilterWords");
|
||||
|
||||
b.Property<ulong>("GreetMessageChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.Property<string>("PermissionRole");
|
||||
|
||||
b.Property<int?>("RootPermissionId");
|
||||
|
||||
b.Property<bool>("SendChannelByeMessage");
|
||||
|
||||
b.Property<bool>("SendChannelGreetMessage");
|
||||
|
||||
b.Property<bool>("SendDmGreetMessage");
|
||||
|
||||
b.Property<bool>("VerbosePermissions");
|
||||
|
||||
b.Property<bool>("VoicePlusTextEnabled");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.HasIndex("RootPermissionId");
|
||||
|
||||
b.ToTable("GuildConfigs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredLogChannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredVoicePresenceCHannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.LogSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("ChannelCreated");
|
||||
|
||||
b.Property<bool>("ChannelDestroyed");
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("ChannelUpdated");
|
||||
|
||||
b.Property<bool>("IsLogging");
|
||||
|
||||
b.Property<bool>("LogUserPresence");
|
||||
|
||||
b.Property<bool>("LogVoicePresence");
|
||||
|
||||
b.Property<bool>("MessageDeleted");
|
||||
|
||||
b.Property<bool>("MessageUpdated");
|
||||
|
||||
b.Property<bool>("UserBanned");
|
||||
|
||||
b.Property<bool>("UserJoined");
|
||||
|
||||
b.Property<bool>("UserLeft");
|
||||
|
||||
b.Property<ulong>("UserPresenceChannelId");
|
||||
|
||||
b.Property<bool>("UserUnbanned");
|
||||
|
||||
b.Property<bool>("UserUpdated");
|
||||
|
||||
b.Property<ulong>("VoicePresenceChannelId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LogSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("ModuleName");
|
||||
|
||||
b.Property<string>("Prefix");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("ModulePrefixes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.MusicPlaylist", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Author");
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("MusicPlaylists");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("NextId");
|
||||
|
||||
b.Property<int>("PrimaryTarget");
|
||||
|
||||
b.Property<ulong>("PrimaryTargetId");
|
||||
|
||||
b.Property<int>("SecondaryTarget");
|
||||
|
||||
b.Property<string>("SecondaryTargetName");
|
||||
|
||||
b.Property<bool>("State");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NextId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Permission");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Status");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("PlayingStatus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("MusicPlaylistId");
|
||||
|
||||
b.Property<string>("Provider");
|
||||
|
||||
b.Property<int>("ProviderType");
|
||||
|
||||
b.Property<string>("Query");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("Uri");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MusicPlaylistId");
|
||||
|
||||
b.ToTable("PlaylistSong");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Quote", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("AuthorName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<string>("Keyword")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Quotes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Icon");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("RaceAnimals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Reminder", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("IsPrivate");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.Property<ulong>("ServerId");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.Property<DateTime>("When");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Reminders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Repeater", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<TimeSpan>("Interval");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Repeaters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.SelfAssignedRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<ulong>("RoleId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId", "RoleId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SelfAssignableRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("Blacklist")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.ClashWar", "ClashWar")
|
||||
.WithMany("Bases")
|
||||
.HasForeignKey("ClashWarId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("CommandCooldowns")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("EightBallResponses")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterInvitesChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterWordsChannelIds")
|
||||
.HasForeignKey("GuildConfigId1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilteredWords")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FollowedStreams")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("GenerateCurrencyChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany()
|
||||
.HasForeignKey("LogSettingId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "RootPermission")
|
||||
.WithMany()
|
||||
.HasForeignKey("RootPermissionId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredChannels")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredVoicePresenceChannelIds")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("ModulePrefixes")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "Next")
|
||||
.WithOne("Previous")
|
||||
.HasForeignKey("NadekoBot.Core.Services.Database.Models.Permission", "NextId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RotatingStatusMessages")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.MusicPlaylist")
|
||||
.WithMany("Songs")
|
||||
.HasForeignKey("MusicPlaylistId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RaceAnimals")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class CurrencyTransaction : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "CurrencyTransactions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Autoincrement", true),
|
||||
Amount = table.Column<long>(nullable: false),
|
||||
Reason = table.Column<string>(nullable: true),
|
||||
UserId = table.Column<ulong>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_CurrencyTransactions", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "CurrencyTransactions");
|
||||
}
|
||||
}
|
||||
}
|
777
NadekoBot.Core/Migrations/20161015102407_coc.Designer.cs
generated
Normal file
777
NadekoBot.Core/Migrations/20161015102407_coc.Designer.cs
generated
Normal file
@@ -0,0 +1,777 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NadekoBot.Core.Services.Database;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
[DbContext(typeof(NadekoContext))]
|
||||
[Migration("20161015102407_coc")]
|
||||
partial class coc
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431");
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<ulong>("ItemId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("BlacklistItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BotConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("BufferSize");
|
||||
|
||||
b.Property<float>("CurrencyGenerationChance");
|
||||
|
||||
b.Property<int>("CurrencyGenerationCooldown");
|
||||
|
||||
b.Property<string>("CurrencyName");
|
||||
|
||||
b.Property<string>("CurrencyPluralName");
|
||||
|
||||
b.Property<string>("CurrencySign");
|
||||
|
||||
b.Property<string>("DMHelpString");
|
||||
|
||||
b.Property<bool>("ForwardMessages");
|
||||
|
||||
b.Property<bool>("ForwardToAllOwners");
|
||||
|
||||
b.Property<string>("HelpString");
|
||||
|
||||
b.Property<int>("MigrationVersion");
|
||||
|
||||
b.Property<string>("RemindMessageFormat");
|
||||
|
||||
b.Property<bool>("RotatingStatuses");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BotConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("BaseDestroyed");
|
||||
|
||||
b.Property<string>("CallUser");
|
||||
|
||||
b.Property<int>("ClashWarId");
|
||||
|
||||
b.Property<int?>("SequenceNumber");
|
||||
|
||||
b.Property<int>("Stars");
|
||||
|
||||
b.Property<DateTime>("TimeAdded");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ClashWarId");
|
||||
|
||||
b.ToTable("ClashCallers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashWar", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<string>("EnemyClan");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Size");
|
||||
|
||||
b.Property<DateTime>("StartedAt");
|
||||
|
||||
b.Property<int>("WarState");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ClashOfClans");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("CommandName");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int>("Seconds");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("CommandCooldown");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ConvertUnit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("InternalTrigger");
|
||||
|
||||
b.Property<decimal>("Modifier");
|
||||
|
||||
b.Property<string>("UnitType");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ConversionUnits");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Currency", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CurrencyTransaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<string>("Reason");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CustomReaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong?>("GuildId");
|
||||
|
||||
b.Property<bool>("IsRegex");
|
||||
|
||||
b.Property<bool>("OwnerOnly");
|
||||
|
||||
b.Property<string>("Response");
|
||||
|
||||
b.Property<string>("Trigger");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CustomReactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Donator", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("Amount");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Donators");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("EightBallResponses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int?>("GuildConfigId1");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.HasIndex("GuildConfigId1");
|
||||
|
||||
b.ToTable("FilterChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<string>("Word");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FilteredWord");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.Property<string>("Username");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FollowedStream");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("GCChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AutoAssignRoleId");
|
||||
|
||||
b.Property<bool>("AutoDeleteByeMessages");
|
||||
|
||||
b.Property<bool>("AutoDeleteGreetMessages");
|
||||
|
||||
b.Property<int>("AutoDeleteGreetMessagesTimer");
|
||||
|
||||
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages");
|
||||
|
||||
b.Property<ulong>("ByeMessageChannelId");
|
||||
|
||||
b.Property<string>("ChannelByeMessageText");
|
||||
|
||||
b.Property<string>("ChannelGreetMessageText");
|
||||
|
||||
b.Property<float>("DefaultMusicVolume");
|
||||
|
||||
b.Property<bool>("DeleteMessageOnCommand");
|
||||
|
||||
b.Property<string>("DmGreetMessageText");
|
||||
|
||||
b.Property<bool>("ExclusiveSelfAssignedRoles");
|
||||
|
||||
b.Property<bool>("FilterInvites");
|
||||
|
||||
b.Property<bool>("FilterWords");
|
||||
|
||||
b.Property<ulong>("GreetMessageChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.Property<string>("PermissionRole");
|
||||
|
||||
b.Property<int?>("RootPermissionId");
|
||||
|
||||
b.Property<bool>("SendChannelByeMessage");
|
||||
|
||||
b.Property<bool>("SendChannelGreetMessage");
|
||||
|
||||
b.Property<bool>("SendDmGreetMessage");
|
||||
|
||||
b.Property<bool>("VerbosePermissions");
|
||||
|
||||
b.Property<bool>("VoicePlusTextEnabled");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.HasIndex("RootPermissionId");
|
||||
|
||||
b.ToTable("GuildConfigs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredLogChannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredVoicePresenceCHannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.LogSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("ChannelCreated");
|
||||
|
||||
b.Property<bool>("ChannelDestroyed");
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("ChannelUpdated");
|
||||
|
||||
b.Property<bool>("IsLogging");
|
||||
|
||||
b.Property<bool>("LogUserPresence");
|
||||
|
||||
b.Property<bool>("LogVoicePresence");
|
||||
|
||||
b.Property<bool>("MessageDeleted");
|
||||
|
||||
b.Property<bool>("MessageUpdated");
|
||||
|
||||
b.Property<bool>("UserBanned");
|
||||
|
||||
b.Property<bool>("UserJoined");
|
||||
|
||||
b.Property<bool>("UserLeft");
|
||||
|
||||
b.Property<ulong>("UserPresenceChannelId");
|
||||
|
||||
b.Property<bool>("UserUnbanned");
|
||||
|
||||
b.Property<bool>("UserUpdated");
|
||||
|
||||
b.Property<ulong>("VoicePresenceChannelId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LogSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("ModuleName");
|
||||
|
||||
b.Property<string>("Prefix");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("ModulePrefixes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.MusicPlaylist", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Author");
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("MusicPlaylists");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("NextId");
|
||||
|
||||
b.Property<int>("PrimaryTarget");
|
||||
|
||||
b.Property<ulong>("PrimaryTargetId");
|
||||
|
||||
b.Property<int>("SecondaryTarget");
|
||||
|
||||
b.Property<string>("SecondaryTargetName");
|
||||
|
||||
b.Property<bool>("State");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NextId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Permission");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Status");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("PlayingStatus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("MusicPlaylistId");
|
||||
|
||||
b.Property<string>("Provider");
|
||||
|
||||
b.Property<int>("ProviderType");
|
||||
|
||||
b.Property<string>("Query");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("Uri");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MusicPlaylistId");
|
||||
|
||||
b.ToTable("PlaylistSong");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Quote", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("AuthorName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<string>("Keyword")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Quotes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Icon");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("RaceAnimals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Reminder", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("IsPrivate");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.Property<ulong>("ServerId");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.Property<DateTime>("When");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Reminders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Repeater", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<TimeSpan>("Interval");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Repeaters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.SelfAssignedRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<ulong>("RoleId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId", "RoleId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SelfAssignableRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("Blacklist")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.ClashWar", "ClashWar")
|
||||
.WithMany("Bases")
|
||||
.HasForeignKey("ClashWarId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("CommandCooldowns")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("EightBallResponses")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterInvitesChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterWordsChannelIds")
|
||||
.HasForeignKey("GuildConfigId1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilteredWords")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FollowedStreams")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("GenerateCurrencyChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany()
|
||||
.HasForeignKey("LogSettingId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "RootPermission")
|
||||
.WithMany()
|
||||
.HasForeignKey("RootPermissionId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredChannels")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredVoicePresenceChannelIds")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("ModulePrefixes")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "Next")
|
||||
.WithOne("Previous")
|
||||
.HasForeignKey("NadekoBot.Core.Services.Database.Models.Permission", "NextId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RotatingStatusMessages")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.MusicPlaylist")
|
||||
.WithMany("Songs")
|
||||
.HasForeignKey("MusicPlaylistId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RaceAnimals")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
22
NadekoBot.Core/Migrations/20161015102407_coc.cs
Normal file
22
NadekoBot.Core/Migrations/20161015102407_coc.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class coc : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "SequenceNumber",
|
||||
table: "ClashCallers",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "SequenceNumber",
|
||||
table: "ClashCallers");
|
||||
}
|
||||
}
|
||||
}
|
779
NadekoBot.Core/Migrations/20161019055137_MuteRoleName.Designer.cs
generated
Normal file
779
NadekoBot.Core/Migrations/20161019055137_MuteRoleName.Designer.cs
generated
Normal file
@@ -0,0 +1,779 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NadekoBot.Core.Services.Database;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
[DbContext(typeof(NadekoContext))]
|
||||
[Migration("20161019055137_MuteRoleName")]
|
||||
partial class MuteRoleName
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431");
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<ulong>("ItemId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("BlacklistItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BotConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("BufferSize");
|
||||
|
||||
b.Property<float>("CurrencyGenerationChance");
|
||||
|
||||
b.Property<int>("CurrencyGenerationCooldown");
|
||||
|
||||
b.Property<string>("CurrencyName");
|
||||
|
||||
b.Property<string>("CurrencyPluralName");
|
||||
|
||||
b.Property<string>("CurrencySign");
|
||||
|
||||
b.Property<string>("DMHelpString");
|
||||
|
||||
b.Property<bool>("ForwardMessages");
|
||||
|
||||
b.Property<bool>("ForwardToAllOwners");
|
||||
|
||||
b.Property<string>("HelpString");
|
||||
|
||||
b.Property<int>("MigrationVersion");
|
||||
|
||||
b.Property<string>("RemindMessageFormat");
|
||||
|
||||
b.Property<bool>("RotatingStatuses");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BotConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("BaseDestroyed");
|
||||
|
||||
b.Property<string>("CallUser");
|
||||
|
||||
b.Property<int>("ClashWarId");
|
||||
|
||||
b.Property<int?>("SequenceNumber");
|
||||
|
||||
b.Property<int>("Stars");
|
||||
|
||||
b.Property<DateTime>("TimeAdded");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ClashWarId");
|
||||
|
||||
b.ToTable("ClashCallers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashWar", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<string>("EnemyClan");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Size");
|
||||
|
||||
b.Property<DateTime>("StartedAt");
|
||||
|
||||
b.Property<int>("WarState");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ClashOfClans");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("CommandName");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int>("Seconds");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("CommandCooldown");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ConvertUnit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("InternalTrigger");
|
||||
|
||||
b.Property<decimal>("Modifier");
|
||||
|
||||
b.Property<string>("UnitType");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ConversionUnits");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Currency", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CurrencyTransaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<string>("Reason");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CustomReaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong?>("GuildId");
|
||||
|
||||
b.Property<bool>("IsRegex");
|
||||
|
||||
b.Property<bool>("OwnerOnly");
|
||||
|
||||
b.Property<string>("Response");
|
||||
|
||||
b.Property<string>("Trigger");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CustomReactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Donator", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("Amount");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Donators");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("EightBallResponses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int?>("GuildConfigId1");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.HasIndex("GuildConfigId1");
|
||||
|
||||
b.ToTable("FilterChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<string>("Word");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FilteredWord");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.Property<string>("Username");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FollowedStream");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("GCChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AutoAssignRoleId");
|
||||
|
||||
b.Property<bool>("AutoDeleteByeMessages");
|
||||
|
||||
b.Property<bool>("AutoDeleteGreetMessages");
|
||||
|
||||
b.Property<int>("AutoDeleteGreetMessagesTimer");
|
||||
|
||||
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages");
|
||||
|
||||
b.Property<ulong>("ByeMessageChannelId");
|
||||
|
||||
b.Property<string>("ChannelByeMessageText");
|
||||
|
||||
b.Property<string>("ChannelGreetMessageText");
|
||||
|
||||
b.Property<float>("DefaultMusicVolume");
|
||||
|
||||
b.Property<bool>("DeleteMessageOnCommand");
|
||||
|
||||
b.Property<string>("DmGreetMessageText");
|
||||
|
||||
b.Property<bool>("ExclusiveSelfAssignedRoles");
|
||||
|
||||
b.Property<bool>("FilterInvites");
|
||||
|
||||
b.Property<bool>("FilterWords");
|
||||
|
||||
b.Property<ulong>("GreetMessageChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.Property<string>("MuteRoleName");
|
||||
|
||||
b.Property<string>("PermissionRole");
|
||||
|
||||
b.Property<int?>("RootPermissionId");
|
||||
|
||||
b.Property<bool>("SendChannelByeMessage");
|
||||
|
||||
b.Property<bool>("SendChannelGreetMessage");
|
||||
|
||||
b.Property<bool>("SendDmGreetMessage");
|
||||
|
||||
b.Property<bool>("VerbosePermissions");
|
||||
|
||||
b.Property<bool>("VoicePlusTextEnabled");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.HasIndex("RootPermissionId");
|
||||
|
||||
b.ToTable("GuildConfigs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredLogChannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredVoicePresenceCHannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.LogSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("ChannelCreated");
|
||||
|
||||
b.Property<bool>("ChannelDestroyed");
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("ChannelUpdated");
|
||||
|
||||
b.Property<bool>("IsLogging");
|
||||
|
||||
b.Property<bool>("LogUserPresence");
|
||||
|
||||
b.Property<bool>("LogVoicePresence");
|
||||
|
||||
b.Property<bool>("MessageDeleted");
|
||||
|
||||
b.Property<bool>("MessageUpdated");
|
||||
|
||||
b.Property<bool>("UserBanned");
|
||||
|
||||
b.Property<bool>("UserJoined");
|
||||
|
||||
b.Property<bool>("UserLeft");
|
||||
|
||||
b.Property<ulong>("UserPresenceChannelId");
|
||||
|
||||
b.Property<bool>("UserUnbanned");
|
||||
|
||||
b.Property<bool>("UserUpdated");
|
||||
|
||||
b.Property<ulong>("VoicePresenceChannelId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LogSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("ModuleName");
|
||||
|
||||
b.Property<string>("Prefix");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("ModulePrefixes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.MusicPlaylist", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Author");
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("MusicPlaylists");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("NextId");
|
||||
|
||||
b.Property<int>("PrimaryTarget");
|
||||
|
||||
b.Property<ulong>("PrimaryTargetId");
|
||||
|
||||
b.Property<int>("SecondaryTarget");
|
||||
|
||||
b.Property<string>("SecondaryTargetName");
|
||||
|
||||
b.Property<bool>("State");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NextId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Permission");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Status");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("PlayingStatus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("MusicPlaylistId");
|
||||
|
||||
b.Property<string>("Provider");
|
||||
|
||||
b.Property<int>("ProviderType");
|
||||
|
||||
b.Property<string>("Query");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("Uri");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MusicPlaylistId");
|
||||
|
||||
b.ToTable("PlaylistSong");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Quote", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("AuthorName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<string>("Keyword")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Quotes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Icon");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("RaceAnimals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Reminder", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("IsPrivate");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.Property<ulong>("ServerId");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.Property<DateTime>("When");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Reminders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Repeater", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<TimeSpan>("Interval");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Repeaters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.SelfAssignedRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<ulong>("RoleId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId", "RoleId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SelfAssignableRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("Blacklist")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.ClashWar", "ClashWar")
|
||||
.WithMany("Bases")
|
||||
.HasForeignKey("ClashWarId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("CommandCooldowns")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("EightBallResponses")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterInvitesChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterWordsChannelIds")
|
||||
.HasForeignKey("GuildConfigId1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilteredWords")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FollowedStreams")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("GenerateCurrencyChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany()
|
||||
.HasForeignKey("LogSettingId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "RootPermission")
|
||||
.WithMany()
|
||||
.HasForeignKey("RootPermissionId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredChannels")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredVoicePresenceChannelIds")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("ModulePrefixes")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "Next")
|
||||
.WithOne("Previous")
|
||||
.HasForeignKey("NadekoBot.Core.Services.Database.Models.Permission", "NextId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RotatingStatusMessages")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.MusicPlaylist")
|
||||
.WithMany("Songs")
|
||||
.HasForeignKey("MusicPlaylistId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RaceAnimals")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
22
NadekoBot.Core/Migrations/20161019055137_MuteRoleName.cs
Normal file
22
NadekoBot.Core/Migrations/20161019055137_MuteRoleName.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class MuteRoleName : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "MuteRoleName",
|
||||
table: "GuildConfigs",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MuteRoleName",
|
||||
table: "GuildConfigs");
|
||||
}
|
||||
}
|
||||
}
|
780
NadekoBot.Core/Migrations/20161107213222_Cleverbot.Designer.cs
generated
Normal file
780
NadekoBot.Core/Migrations/20161107213222_Cleverbot.Designer.cs
generated
Normal file
@@ -0,0 +1,780 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NadekoBot.Core.Services.Database;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
[DbContext(typeof(NadekoContext))]
|
||||
[Migration("20161107213222_Cleverbot")]
|
||||
partial class Cleverbot
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431");
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<ulong>("ItemId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("BlacklistItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BotConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("BufferSize");
|
||||
|
||||
b.Property<float>("CurrencyGenerationChance");
|
||||
|
||||
b.Property<int>("CurrencyGenerationCooldown");
|
||||
|
||||
b.Property<string>("CurrencyName");
|
||||
|
||||
b.Property<string>("CurrencyPluralName");
|
||||
|
||||
b.Property<string>("CurrencySign");
|
||||
|
||||
b.Property<string>("DMHelpString");
|
||||
|
||||
b.Property<bool>("ForwardMessages");
|
||||
|
||||
b.Property<bool>("ForwardToAllOwners");
|
||||
|
||||
b.Property<string>("HelpString");
|
||||
|
||||
b.Property<int>("MigrationVersion");
|
||||
|
||||
b.Property<string>("RemindMessageFormat");
|
||||
|
||||
b.Property<bool>("RotatingStatuses");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BotConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("BaseDestroyed");
|
||||
|
||||
b.Property<string>("CallUser");
|
||||
|
||||
b.Property<int>("ClashWarId");
|
||||
|
||||
b.Property<int?>("SequenceNumber");
|
||||
|
||||
b.Property<int>("Stars");
|
||||
|
||||
b.Property<DateTime>("TimeAdded");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ClashWarId");
|
||||
|
||||
b.ToTable("ClashCallers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashWar", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<string>("EnemyClan");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Size");
|
||||
|
||||
b.Property<DateTime>("StartedAt");
|
||||
|
||||
b.Property<int>("WarState");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ClashOfClans");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("CommandName");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int>("Seconds");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("CommandCooldown");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ConvertUnit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("InternalTrigger");
|
||||
|
||||
b.Property<decimal>("Modifier");
|
||||
|
||||
b.Property<string>("UnitType");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ConversionUnits");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Currency", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CurrencyTransaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<string>("Reason");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CustomReaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong?>("GuildId");
|
||||
|
||||
b.Property<bool>("IsRegex");
|
||||
|
||||
b.Property<bool>("OwnerOnly");
|
||||
|
||||
b.Property<string>("Response");
|
||||
|
||||
b.Property<string>("Trigger");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CustomReactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Donator", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("Amount");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Donators");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("EightBallResponses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int?>("GuildConfigId1");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.HasIndex("GuildConfigId1");
|
||||
|
||||
b.ToTable("FilterChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<string>("Word");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FilteredWord");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.Property<string>("Username");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FollowedStream");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("GCChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AutoAssignRoleId");
|
||||
|
||||
b.Property<bool>("AutoDeleteByeMessages");
|
||||
|
||||
b.Property<bool>("AutoDeleteGreetMessages");
|
||||
|
||||
b.Property<int>("AutoDeleteGreetMessagesTimer");
|
||||
|
||||
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages");
|
||||
|
||||
b.Property<ulong>("ByeMessageChannelId");
|
||||
|
||||
b.Property<string>("ChannelByeMessageText");
|
||||
|
||||
b.Property<string>("ChannelGreetMessageText");
|
||||
|
||||
b.Property<bool>("CleverbotEnabled");
|
||||
|
||||
b.Property<float>("DefaultMusicVolume");
|
||||
|
||||
b.Property<bool>("DeleteMessageOnCommand");
|
||||
|
||||
b.Property<string>("DmGreetMessageText");
|
||||
|
||||
b.Property<bool>("ExclusiveSelfAssignedRoles");
|
||||
|
||||
b.Property<bool>("FilterInvites");
|
||||
|
||||
b.Property<bool>("FilterWords");
|
||||
|
||||
b.Property<ulong>("GreetMessageChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.Property<string>("MuteRoleName");
|
||||
|
||||
b.Property<string>("PermissionRole");
|
||||
|
||||
b.Property<int?>("RootPermissionId");
|
||||
|
||||
b.Property<bool>("SendChannelByeMessage");
|
||||
|
||||
b.Property<bool>("SendChannelGreetMessage");
|
||||
|
||||
b.Property<bool>("SendDmGreetMessage");
|
||||
|
||||
b.Property<bool>("VerbosePermissions");
|
||||
|
||||
b.Property<bool>("VoicePlusTextEnabled");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.HasIndex("RootPermissionId");
|
||||
|
||||
b.ToTable("GuildConfigs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredLogChannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredVoicePresenceCHannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.LogSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("ChannelCreated");
|
||||
|
||||
b.Property<bool>("ChannelDestroyed");
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("ChannelUpdated");
|
||||
|
||||
b.Property<bool>("IsLogging");
|
||||
|
||||
b.Property<bool>("LogUserPresence");
|
||||
|
||||
b.Property<bool>("LogVoicePresence");
|
||||
|
||||
b.Property<bool>("MessageDeleted");
|
||||
|
||||
b.Property<bool>("MessageUpdated");
|
||||
|
||||
b.Property<bool>("UserBanned");
|
||||
|
||||
b.Property<bool>("UserJoined");
|
||||
|
||||
b.Property<bool>("UserLeft");
|
||||
|
||||
b.Property<ulong>("UserPresenceChannelId");
|
||||
|
||||
b.Property<bool>("UserUnbanned");
|
||||
|
||||
b.Property<bool>("UserUpdated");
|
||||
|
||||
b.Property<ulong>("VoicePresenceChannelId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LogSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("ModuleName");
|
||||
|
||||
b.Property<string>("Prefix");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("ModulePrefixes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.MusicPlaylist", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Author");
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("MusicPlaylists");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("NextId");
|
||||
|
||||
b.Property<int>("PrimaryTarget");
|
||||
|
||||
b.Property<ulong>("PrimaryTargetId");
|
||||
|
||||
b.Property<int>("SecondaryTarget");
|
||||
|
||||
b.Property<string>("SecondaryTargetName");
|
||||
|
||||
b.Property<bool>("State");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NextId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Permission");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Status");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("PlayingStatus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("MusicPlaylistId");
|
||||
|
||||
b.Property<string>("Provider");
|
||||
|
||||
b.Property<int>("ProviderType");
|
||||
|
||||
b.Property<string>("Query");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("Uri");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MusicPlaylistId");
|
||||
|
||||
b.ToTable("PlaylistSong");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Quote", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("AuthorName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<string>("Keyword")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Quotes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Icon");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("RaceAnimals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Reminder", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("IsPrivate");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.Property<ulong>("ServerId");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.Property<DateTime>("When");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Reminders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Repeater", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<TimeSpan>("Interval");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Repeaters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.SelfAssignedRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<ulong>("RoleId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId", "RoleId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SelfAssignableRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("Blacklist")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.ClashWar", "ClashWar")
|
||||
.WithMany("Bases")
|
||||
.HasForeignKey("ClashWarId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("CommandCooldowns")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("EightBallResponses")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterInvitesChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterWordsChannelIds")
|
||||
.HasForeignKey("GuildConfigId1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilteredWords")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FollowedStreams")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("GenerateCurrencyChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany()
|
||||
.HasForeignKey("LogSettingId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "RootPermission")
|
||||
.WithMany()
|
||||
.HasForeignKey("RootPermissionId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredChannels")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredVoicePresenceChannelIds")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("ModulePrefixes")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "Next")
|
||||
.WithOne("Previous")
|
||||
.HasForeignKey("NadekoBot.Core.Services.Database.Models.Permission", "NextId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RotatingStatusMessages")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.MusicPlaylist")
|
||||
.WithMany("Songs")
|
||||
.HasForeignKey("MusicPlaylistId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RaceAnimals")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
23
NadekoBot.Core/Migrations/20161107213222_Cleverbot.cs
Normal file
23
NadekoBot.Core/Migrations/20161107213222_Cleverbot.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class Cleverbot : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "CleverbotEnabled",
|
||||
table: "GuildConfigs",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "CleverbotEnabled",
|
||||
table: "GuildConfigs");
|
||||
}
|
||||
}
|
||||
}
|
783
NadekoBot.Core/Migrations/20161122100602_Greet and bye improved.Designer.cs
generated
Normal file
783
NadekoBot.Core/Migrations/20161122100602_Greet and bye improved.Designer.cs
generated
Normal file
@@ -0,0 +1,783 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NadekoBot.Core.Services.Database;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
[DbContext(typeof(NadekoContext))]
|
||||
[Migration("20161122100602_Greet and bye improved")]
|
||||
partial class Greetandbyeimproved
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "1.1.0-rtm-22752");
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<ulong>("ItemId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("BlacklistItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BotConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("BufferSize");
|
||||
|
||||
b.Property<float>("CurrencyGenerationChance");
|
||||
|
||||
b.Property<int>("CurrencyGenerationCooldown");
|
||||
|
||||
b.Property<string>("CurrencyName");
|
||||
|
||||
b.Property<string>("CurrencyPluralName");
|
||||
|
||||
b.Property<string>("CurrencySign");
|
||||
|
||||
b.Property<string>("DMHelpString");
|
||||
|
||||
b.Property<bool>("ForwardMessages");
|
||||
|
||||
b.Property<bool>("ForwardToAllOwners");
|
||||
|
||||
b.Property<string>("HelpString");
|
||||
|
||||
b.Property<int>("MigrationVersion");
|
||||
|
||||
b.Property<string>("RemindMessageFormat");
|
||||
|
||||
b.Property<bool>("RotatingStatuses");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BotConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("BaseDestroyed");
|
||||
|
||||
b.Property<string>("CallUser");
|
||||
|
||||
b.Property<int>("ClashWarId");
|
||||
|
||||
b.Property<int?>("SequenceNumber");
|
||||
|
||||
b.Property<int>("Stars");
|
||||
|
||||
b.Property<DateTime>("TimeAdded");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ClashWarId");
|
||||
|
||||
b.ToTable("ClashCallers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashWar", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<string>("EnemyClan");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Size");
|
||||
|
||||
b.Property<DateTime>("StartedAt");
|
||||
|
||||
b.Property<int>("WarState");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ClashOfClans");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("CommandName");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int>("Seconds");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("CommandCooldown");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ConvertUnit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("InternalTrigger");
|
||||
|
||||
b.Property<decimal>("Modifier");
|
||||
|
||||
b.Property<string>("UnitType");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ConversionUnits");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Currency", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CurrencyTransaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<string>("Reason");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CustomReaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong?>("GuildId");
|
||||
|
||||
b.Property<bool>("IsRegex");
|
||||
|
||||
b.Property<bool>("OwnerOnly");
|
||||
|
||||
b.Property<string>("Response");
|
||||
|
||||
b.Property<string>("Trigger");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CustomReactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Donator", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("Amount");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Donators");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("EightBallResponses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int?>("GuildConfigId1");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.HasIndex("GuildConfigId1");
|
||||
|
||||
b.ToTable("FilterChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<string>("Word");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FilteredWord");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.Property<string>("Username");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FollowedStream");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("GCChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AutoAssignRoleId");
|
||||
|
||||
b.Property<bool>("AutoDeleteByeMessages");
|
||||
|
||||
b.Property<int>("AutoDeleteByeMessagesTimer");
|
||||
|
||||
b.Property<bool>("AutoDeleteGreetMessages");
|
||||
|
||||
b.Property<int>("AutoDeleteGreetMessagesTimer");
|
||||
|
||||
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages");
|
||||
|
||||
b.Property<ulong>("ByeMessageChannelId");
|
||||
|
||||
b.Property<string>("ChannelByeMessageText");
|
||||
|
||||
b.Property<string>("ChannelGreetMessageText");
|
||||
|
||||
b.Property<bool>("CleverbotEnabled");
|
||||
|
||||
b.Property<float>("DefaultMusicVolume");
|
||||
|
||||
b.Property<bool>("DeleteMessageOnCommand");
|
||||
|
||||
b.Property<string>("DmGreetMessageText");
|
||||
|
||||
b.Property<bool>("ExclusiveSelfAssignedRoles");
|
||||
|
||||
b.Property<bool>("FilterInvites");
|
||||
|
||||
b.Property<bool>("FilterWords");
|
||||
|
||||
b.Property<ulong>("GreetMessageChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.Property<string>("MuteRoleName");
|
||||
|
||||
b.Property<string>("PermissionRole");
|
||||
|
||||
b.Property<int?>("RootPermissionId");
|
||||
|
||||
b.Property<bool>("SendChannelByeMessage");
|
||||
|
||||
b.Property<bool>("SendChannelGreetMessage");
|
||||
|
||||
b.Property<bool>("SendDmGreetMessage");
|
||||
|
||||
b.Property<bool>("VerbosePermissions");
|
||||
|
||||
b.Property<bool>("VoicePlusTextEnabled");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.HasIndex("RootPermissionId");
|
||||
|
||||
b.ToTable("GuildConfigs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredLogChannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredVoicePresenceCHannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.LogSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("ChannelCreated");
|
||||
|
||||
b.Property<bool>("ChannelDestroyed");
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("ChannelUpdated");
|
||||
|
||||
b.Property<bool>("IsLogging");
|
||||
|
||||
b.Property<bool>("LogUserPresence");
|
||||
|
||||
b.Property<bool>("LogVoicePresence");
|
||||
|
||||
b.Property<bool>("MessageDeleted");
|
||||
|
||||
b.Property<bool>("MessageUpdated");
|
||||
|
||||
b.Property<bool>("UserBanned");
|
||||
|
||||
b.Property<bool>("UserJoined");
|
||||
|
||||
b.Property<bool>("UserLeft");
|
||||
|
||||
b.Property<ulong>("UserPresenceChannelId");
|
||||
|
||||
b.Property<bool>("UserUnbanned");
|
||||
|
||||
b.Property<bool>("UserUpdated");
|
||||
|
||||
b.Property<ulong>("VoicePresenceChannelId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LogSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("ModuleName");
|
||||
|
||||
b.Property<string>("Prefix");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("ModulePrefixes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.MusicPlaylist", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Author");
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("MusicPlaylists");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("NextId");
|
||||
|
||||
b.Property<int>("PrimaryTarget");
|
||||
|
||||
b.Property<ulong>("PrimaryTargetId");
|
||||
|
||||
b.Property<int>("SecondaryTarget");
|
||||
|
||||
b.Property<string>("SecondaryTargetName");
|
||||
|
||||
b.Property<bool>("State");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NextId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Permission");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Status");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("PlayingStatus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("MusicPlaylistId");
|
||||
|
||||
b.Property<string>("Provider");
|
||||
|
||||
b.Property<int>("ProviderType");
|
||||
|
||||
b.Property<string>("Query");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("Uri");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MusicPlaylistId");
|
||||
|
||||
b.ToTable("PlaylistSong");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Quote", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("AuthorName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<string>("Keyword")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Quotes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Icon");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("RaceAnimals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Reminder", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("IsPrivate");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.Property<ulong>("ServerId");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.Property<DateTime>("When");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Reminders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Repeater", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<TimeSpan>("Interval");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Repeaters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.SelfAssignedRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<ulong>("RoleId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId", "RoleId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SelfAssignableRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("Blacklist")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.ClashWar", "ClashWar")
|
||||
.WithMany("Bases")
|
||||
.HasForeignKey("ClashWarId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("CommandCooldowns")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("EightBallResponses")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterInvitesChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterWordsChannelIds")
|
||||
.HasForeignKey("GuildConfigId1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilteredWords")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FollowedStreams")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("GenerateCurrencyChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany()
|
||||
.HasForeignKey("LogSettingId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "RootPermission")
|
||||
.WithMany()
|
||||
.HasForeignKey("RootPermissionId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredChannels")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredVoicePresenceChannelIds")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("ModulePrefixes")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "Next")
|
||||
.WithOne("Previous")
|
||||
.HasForeignKey("NadekoBot.Core.Services.Database.Models.Permission", "NextId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RotatingStatusMessages")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.MusicPlaylist")
|
||||
.WithMany("Songs")
|
||||
.HasForeignKey("MusicPlaylistId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RaceAnimals")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class Greetandbyeimproved : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "AutoDeleteByeMessagesTimer",
|
||||
table: "GuildConfigs",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutoDeleteByeMessagesTimer",
|
||||
table: "GuildConfigs");
|
||||
}
|
||||
}
|
||||
}
|
800
NadekoBot.Core/Migrations/20161127233843_PokeGame.Designer.cs
generated
Normal file
800
NadekoBot.Core/Migrations/20161127233843_PokeGame.Designer.cs
generated
Normal file
@@ -0,0 +1,800 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NadekoBot.Core.Services.Database;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
[DbContext(typeof(NadekoContext))]
|
||||
[Migration("20161127233843_PokeGame")]
|
||||
partial class PokeGame
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "1.1.0-rtm-22752");
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<ulong>("ItemId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("BlacklistItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BotConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("BufferSize");
|
||||
|
||||
b.Property<float>("CurrencyGenerationChance");
|
||||
|
||||
b.Property<int>("CurrencyGenerationCooldown");
|
||||
|
||||
b.Property<string>("CurrencyName");
|
||||
|
||||
b.Property<string>("CurrencyPluralName");
|
||||
|
||||
b.Property<string>("CurrencySign");
|
||||
|
||||
b.Property<string>("DMHelpString");
|
||||
|
||||
b.Property<bool>("ForwardMessages");
|
||||
|
||||
b.Property<bool>("ForwardToAllOwners");
|
||||
|
||||
b.Property<string>("HelpString");
|
||||
|
||||
b.Property<int>("MigrationVersion");
|
||||
|
||||
b.Property<string>("RemindMessageFormat");
|
||||
|
||||
b.Property<bool>("RotatingStatuses");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BotConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("BaseDestroyed");
|
||||
|
||||
b.Property<string>("CallUser");
|
||||
|
||||
b.Property<int>("ClashWarId");
|
||||
|
||||
b.Property<int?>("SequenceNumber");
|
||||
|
||||
b.Property<int>("Stars");
|
||||
|
||||
b.Property<DateTime>("TimeAdded");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ClashWarId");
|
||||
|
||||
b.ToTable("ClashCallers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashWar", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<string>("EnemyClan");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Size");
|
||||
|
||||
b.Property<DateTime>("StartedAt");
|
||||
|
||||
b.Property<int>("WarState");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ClashOfClans");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("CommandName");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int>("Seconds");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("CommandCooldown");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ConvertUnit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("InternalTrigger");
|
||||
|
||||
b.Property<decimal>("Modifier");
|
||||
|
||||
b.Property<string>("UnitType");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ConversionUnits");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Currency", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CurrencyTransaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<string>("Reason");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CustomReaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong?>("GuildId");
|
||||
|
||||
b.Property<bool>("IsRegex");
|
||||
|
||||
b.Property<bool>("OwnerOnly");
|
||||
|
||||
b.Property<string>("Response");
|
||||
|
||||
b.Property<string>("Trigger");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CustomReactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Donator", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("Amount");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Donators");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("EightBallResponses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int?>("GuildConfigId1");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.HasIndex("GuildConfigId1");
|
||||
|
||||
b.ToTable("FilterChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<string>("Word");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FilteredWord");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.Property<string>("Username");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FollowedStream");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("GCChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AutoAssignRoleId");
|
||||
|
||||
b.Property<bool>("AutoDeleteByeMessages");
|
||||
|
||||
b.Property<int>("AutoDeleteByeMessagesTimer");
|
||||
|
||||
b.Property<bool>("AutoDeleteGreetMessages");
|
||||
|
||||
b.Property<int>("AutoDeleteGreetMessagesTimer");
|
||||
|
||||
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages");
|
||||
|
||||
b.Property<ulong>("ByeMessageChannelId");
|
||||
|
||||
b.Property<string>("ChannelByeMessageText");
|
||||
|
||||
b.Property<string>("ChannelGreetMessageText");
|
||||
|
||||
b.Property<bool>("CleverbotEnabled");
|
||||
|
||||
b.Property<float>("DefaultMusicVolume");
|
||||
|
||||
b.Property<bool>("DeleteMessageOnCommand");
|
||||
|
||||
b.Property<string>("DmGreetMessageText");
|
||||
|
||||
b.Property<bool>("ExclusiveSelfAssignedRoles");
|
||||
|
||||
b.Property<bool>("FilterInvites");
|
||||
|
||||
b.Property<bool>("FilterWords");
|
||||
|
||||
b.Property<ulong>("GreetMessageChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.Property<string>("MuteRoleName");
|
||||
|
||||
b.Property<string>("PermissionRole");
|
||||
|
||||
b.Property<int?>("RootPermissionId");
|
||||
|
||||
b.Property<bool>("SendChannelByeMessage");
|
||||
|
||||
b.Property<bool>("SendChannelGreetMessage");
|
||||
|
||||
b.Property<bool>("SendDmGreetMessage");
|
||||
|
||||
b.Property<bool>("VerbosePermissions");
|
||||
|
||||
b.Property<bool>("VoicePlusTextEnabled");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.HasIndex("RootPermissionId");
|
||||
|
||||
b.ToTable("GuildConfigs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredLogChannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredVoicePresenceCHannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.LogSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("ChannelCreated");
|
||||
|
||||
b.Property<bool>("ChannelDestroyed");
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("ChannelUpdated");
|
||||
|
||||
b.Property<bool>("IsLogging");
|
||||
|
||||
b.Property<bool>("LogUserPresence");
|
||||
|
||||
b.Property<bool>("LogVoicePresence");
|
||||
|
||||
b.Property<bool>("MessageDeleted");
|
||||
|
||||
b.Property<bool>("MessageUpdated");
|
||||
|
||||
b.Property<bool>("UserBanned");
|
||||
|
||||
b.Property<bool>("UserJoined");
|
||||
|
||||
b.Property<bool>("UserLeft");
|
||||
|
||||
b.Property<ulong>("UserPresenceChannelId");
|
||||
|
||||
b.Property<bool>("UserUnbanned");
|
||||
|
||||
b.Property<bool>("UserUpdated");
|
||||
|
||||
b.Property<ulong>("VoicePresenceChannelId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LogSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("ModuleName");
|
||||
|
||||
b.Property<string>("Prefix");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("ModulePrefixes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.MusicPlaylist", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Author");
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("MusicPlaylists");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("NextId");
|
||||
|
||||
b.Property<int>("PrimaryTarget");
|
||||
|
||||
b.Property<ulong>("PrimaryTargetId");
|
||||
|
||||
b.Property<int>("SecondaryTarget");
|
||||
|
||||
b.Property<string>("SecondaryTargetName");
|
||||
|
||||
b.Property<bool>("State");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NextId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Permission");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Status");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("PlayingStatus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("MusicPlaylistId");
|
||||
|
||||
b.Property<string>("Provider");
|
||||
|
||||
b.Property<int>("ProviderType");
|
||||
|
||||
b.Property<string>("Query");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("Uri");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MusicPlaylistId");
|
||||
|
||||
b.ToTable("PlaylistSong");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Quote", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("AuthorName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<string>("Keyword")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Quotes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Icon");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("RaceAnimals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Reminder", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("IsPrivate");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.Property<ulong>("ServerId");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.Property<DateTime>("When");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Reminders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Repeater", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<TimeSpan>("Interval");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Repeaters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.SelfAssignedRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<ulong>("RoleId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId", "RoleId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SelfAssignableRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.UserPokeTypes", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("UserId");
|
||||
|
||||
b.Property<string>("type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("PokeGame");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("Blacklist")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.ClashWar", "ClashWar")
|
||||
.WithMany("Bases")
|
||||
.HasForeignKey("ClashWarId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("CommandCooldowns")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("EightBallResponses")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterInvitesChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterWordsChannelIds")
|
||||
.HasForeignKey("GuildConfigId1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilteredWords")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FollowedStreams")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.GuildConfig")
|
||||
.WithMany("GenerateCurrencyChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany()
|
||||
.HasForeignKey("LogSettingId");
|
||||
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "RootPermission")
|
||||
.WithMany()
|
||||
.HasForeignKey("RootPermissionId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredChannels")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredVoicePresenceChannelIds")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("ModulePrefixes")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.Permission", "Next")
|
||||
.WithOne("Previous")
|
||||
.HasForeignKey("NadekoBot.Core.Services.Database.Models.Permission", "NextId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RotatingStatusMessages")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.MusicPlaylist")
|
||||
.WithMany("Songs")
|
||||
.HasForeignKey("MusicPlaylistId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Core.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Core.Services.Database.Models.BotConfig")
|
||||
.WithMany("RaceAnimals")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
36
NadekoBot.Core/Migrations/20161127233843_PokeGame.cs
Normal file
36
NadekoBot.Core/Migrations/20161127233843_PokeGame.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class PokeGame : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PokeGame",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
UserId = table.Column<ulong>(nullable: false),
|
||||
type = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PokeGame", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PokeGame_UserId",
|
||||
table: "PokeGame",
|
||||
column: "UserId",
|
||||
unique: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "PokeGame");
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user