diff --git a/Attribute/CommandAttribute.cs b/Attribute/CommandAttribute.cs
new file mode 100644
index 00000000..e8daea49
--- /dev/null
+++ b/Attribute/CommandAttribute.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using PriconneBotConsoleApp.DataType;
+using PriconneBotConsoleApp.Extension;
+
+namespace PriconneBotConsoleApp.Attribute
+{
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ public class CommandAttribute : System.Attribute
+ {
+ public CommandAttribute(
+ string[] names = null,
+ int minArgumentLength = 0,
+ int maxArgumentLength = int.MaxValue,
+ params ChannelFeatureType[] compatibleChannels)
+ {
+ Names = names ?? new[] { string.Empty };
+ MinArgumentLength = minArgumentLength;
+ MaxArgumentLength = maxArgumentLength;
+ CompatibleChannels = compatibleChannels.Length == 0 ? new[] { ChannelFeatureType.All } : compatibleChannels;
+ }
+
+ public CommandAttribute(
+ string name,
+ int minArgumentLength = 0,
+ int maxArgumentLength = int.MaxValue,
+ params ChannelFeatureType[] compatibleChannels)
+ : this(
+ name == null ? null : new[] { name },
+ minArgumentLength,
+ maxArgumentLength,
+ compatibleChannels)
+ {
+ }
+
+ public CommandAttribute(
+ AttackType attackType,
+ int minArgumentLength = 0,
+ int maxArgumentLength = int.MaxValue,
+ params ChannelFeatureType[] compatibleChannels)
+ : this(
+ attackType.GetMultiDescription().Names,
+ minArgumentLength,
+ maxArgumentLength,
+ compatibleChannels)
+ {
+ }
+
+ ///
+ /// 受け取ったコマンドを格納する
+ ///
+ public IReadOnlyList Names { get; }
+
+ ///
+ /// 引数の長さの最小値
+ ///
+ public int MinArgumentLength { get; }
+
+ ///
+ /// 引数の長さの最大値
+ ///
+ public int MaxArgumentLength { get; }
+
+ ///
+ /// コマンドが対応するチャンネル
+ ///
+ public IReadOnlyList CompatibleChannels { get; }
+
+ public bool IsCompatibleArgumentLength(int argLength)
+ => MinArgumentLength <= argLength && argLength <= MaxArgumentLength;
+ }
+}
diff --git a/Attribute/Description.cs b/Attribute/MultiDescriptionAttribute.cs
similarity index 55%
rename from Attribute/Description.cs
rename to Attribute/MultiDescriptionAttribute.cs
index c3772e56..737441f6 100644
--- a/Attribute/Description.cs
+++ b/Attribute/MultiDescriptionAttribute.cs
@@ -1,20 +1,27 @@
using System;
+using System.Collections.Generic;
+using System.Linq;
namespace PriconneBotConsoleApp.Attribute
{
public struct MultiDescriptionData
{
- public string LongDescription;
- public string ShortDescription;
- public string[] Aliases;
+ public string LongDescription { get; init; }
+ public string ShortDescription { get; init; }
+ public IReadOnlyList Aliases { get; init; }
+
+ private string[] m_Names;
+
+ public string[] Names
+ => m_Names ??= Aliases.Append(LongDescription).Append(ShortDescription).ToArray();
}
[AttributeUsage(AttributeTargets.Field)]
public class MultiDescriptionAttribute : System.Attribute
{
public MultiDescriptionAttribute(
- string longDescription,
- string shortDescription = null,
+ string longDescription,
+ string shortDescription = null,
params string[] aliases)
{
Data = new MultiDescriptionData
@@ -26,5 +33,5 @@ public MultiDescriptionAttribute(
}
public MultiDescriptionData Data { get; }
- }
+ }
}
diff --git a/DataModel/CommandEventArgs.cs b/DataModel/CommandEventArgs.cs
new file mode 100644
index 00000000..8d046ced
--- /dev/null
+++ b/DataModel/CommandEventArgs.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Discord.WebSocket;
+using PriconneBotConsoleApp.Database;
+using PriconneBotConsoleApp.DataType;
+using PriconneBotConsoleApp.Extension;
+
+namespace PriconneBotConsoleApp.DataModel
+{
+ public class CommandEventArgs : EventArgs
+ {
+ public CommandEventArgs(SocketUserMessage socketUserMessage)
+ {
+ SocketUserMessage = socketUserMessage;
+
+ if (SocketUserMessage.Content.Length == 0)
+ {
+ throw new ArgumentException("Content.Length が 0");
+ }
+
+ var splitContents = SocketUserMessage.Content.ZenToHan().Split(' ', StringSplitOptions.RemoveEmptyEntries);
+ Name = splitContents[0];
+ Arguments = splitContents.Length > 1 ? splitContents.Skip(1).ToList() : Array.Empty();
+ User = SocketUserMessage.Author as SocketGuildUser;
+ Channel = SocketUserMessage.Channel as SocketTextChannel;
+ PlayerData = DatabasePlayerDataController.LoadPlayerData(Channel.Guild.Id, SocketUserMessage.Author.Id);
+ Role = Channel.Guild.GetRole(PlayerData?.ClanData.ClanRoleID ?? 0);
+
+ if (Role == null)
+ {
+ return;
+ }
+
+ ClanData = DatabaseClanDataController.LoadClanData(Role);
+
+ ChannelFeatureType =
+ (ChannelFeatureType?)ClanData.ChannelData.FirstOrDefault(x => x.ChannelID == Channel.Id)?.FeatureID
+ ?? ChannelFeatureType.All;
+ }
+
+ public SocketUserMessage SocketUserMessage { get; }
+ public string Name { get; }
+ public IReadOnlyList Arguments { get; }
+ public SocketGuildUser User { get; }
+ public SocketTextChannel Channel { get; }
+ public SocketRole Role { get; }
+ public ClanData ClanData { get; }
+ public PlayerData PlayerData { get; }
+ public ChannelFeatureType ChannelFeatureType { get; }
+ }
+}
diff --git a/DataModel/Shiori/ClanData.cs b/DataModel/Shiori/ClanData.cs
index aad51050..e2465059 100644
--- a/DataModel/Shiori/ClanData.cs
+++ b/DataModel/Shiori/ClanData.cs
@@ -1,4 +1,5 @@
using PriconneBotConsoleApp.DataType;
+using PriconneBotConsoleApp.Extension;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
@@ -82,68 +83,33 @@ public void SetBossLap(int bossNum, int bossLap)
};
}
+ public int GetBossLap(BossNumberType bossNumberType)
+ => GetBossLap((int)bossNumberType);
+
+ public void SetBossLap(BossNumberType bossNumberType, int bossLap)
+ => SetBossLap((int)bossNumberType, bossLap);
+
///
- /// 最も周回数を返す
+ /// クラン内のチャンネルIDを返す。
///
+ ///
///
- public int GetMinBossLap()
- => Enumerable.Min(new int[] { Boss1Lap, Boss2Lap, Boss3Lap, Boss4Lap, Boss5Lap });
+ public ulong GetChannelID(ChannelFeatureType channelFeatureType)
+ => ChannelData?.GetChannelID(ClanID, channelFeatureType) ?? 0;
///
- /// 5つのボスデータから今のボスに変換。来月削除。
+ /// クラン内のメッセージIDを返す。
///
- ///
+ ///
///
- [Obsolete]
- public byte GetNowBoss()
- {
- if (Boss1Lap == Boss2Lap
- && Boss2Lap == Boss3Lap
- && Boss3Lap == Boss4Lap
- && Boss4Lap == Boss5Lap)
- {
- return (byte)BossNumberType.Boss5Number;
- }
- if (Boss1Lap == Boss2Lap + 1 )
- {
- return (byte)BossNumberType.Boss1Number;
- }
- else if (Boss2Lap == Boss3Lap + 1)
- {
- return (byte)BossNumberType.Boss2Number;
- }
- else if (Boss3Lap == Boss4Lap + 1)
- {
- return (byte)BossNumberType.Boss3Number;
- }
- else if (Boss4Lap == Boss5Lap + 1)
- {
- return (byte)BossNumberType.Boss4Number;
- }
-
- return 0;
- }
+ public ulong GetMessageID(MessageFeatureType messageFeatureType)
+ => MessageData?.GetMessageID(ClanID, messageFeatureType) ?? 0;
///
- /// 5つのボスデータから今のLapに変換。来月削除。
+ /// 最も小さい周回数を返す
///
- ///
///
- [Obsolete]
- public ushort GetNowLap()
- {
- if (Boss1Lap == Boss2Lap
- && Boss2Lap == Boss3Lap
- && Boss3Lap == Boss4Lap
- && Boss4Lap == Boss5Lap)
- {
- return Boss5Lap;
- }
- else
- {
- return Boss1Lap;
- }
- }
+ public int GetMinBossLap()
+ => Enumerable.Min(new int[] { Boss1Lap, Boss2Lap, Boss3Lap, Boss4Lap, Boss5Lap });
}
-
}
diff --git a/DataType/AttackType.cs b/DataType/AttackType.cs
index 791b3bca..3e465638 100644
--- a/DataType/AttackType.cs
+++ b/DataType/AttackType.cs
@@ -13,7 +13,7 @@ public enum AttackType
Magic,
[MultiDescription("ニャル", "ニ", "n", "N")]
- NewYearKyaru,
+ NewYearKaryl,
[MultiDescription("持ち越し", "持", "-", "持越し", "持越")]
CarryOver,
diff --git a/DataType/BossNumberType.cs b/DataType/BossNumberType.cs
index 6ca9c3a0..b792c2b6 100644
--- a/DataType/BossNumberType.cs
+++ b/DataType/BossNumberType.cs
@@ -2,6 +2,7 @@
{
public enum BossNumberType
{
+ Unknown = 0,
Boss1Number = 1,
Boss2Number = 2,
Boss3Number = 3,
diff --git a/DataType/ErrorType.cs b/DataType/ErrorType.cs
index 2027cb0c..2c80f6dc 100644
--- a/DataType/ErrorType.cs
+++ b/DataType/ErrorType.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.ComponentModel;
+using System.ComponentModel;
namespace PriconneBotConsoleApp.DataType
{
@@ -12,10 +9,13 @@ public enum ErrorType
//予約関連
[Description("予約に失敗しました。")]
FailedReservation,
- [Description("予約できません。予約可能時間は{0}~{1}です。")]
+
+ [Description("予約できません。予約可能時間は{0}:00~{1}:00です。")]
OutOfReservationTime,
+
[Description("コメントが長いので切り取られました。\n 問題がある場合は予約削除をして再度予約してください。")]
TooLongComment,
+
[Description("予約できません。予約は{0}周目まで可能です。")]
OutOfReservationBossLaps,
diff --git a/DataType/InfomationType.cs b/DataType/InformationType.cs
similarity index 60%
rename from DataType/InfomationType.cs
rename to DataType/InformationType.cs
index 7c7a52b2..6ffecbb7 100644
--- a/DataType/InfomationType.cs
+++ b/DataType/InformationType.cs
@@ -7,12 +7,16 @@
namespace PriconneBotConsoleApp.DataType
{
- public enum InfomationType
+ public enum InformationType
{
Unknown,
// 凸報告関連
[Description("<@{0}>の凸報告を代理削除しました。\nこのメッセージは{1}秒後削除されます。")]
- DeleteInsted,
+ DeleteInstead,
+
+ //持ち越し関連
+ [Description("持ち越しをすべて削除しました。\nこのメッセージは{0}秒後削除されます。")]
+ DeleteAllCarryOverData,
}
}
diff --git a/DataType/ProgressStatus.cs b/DataType/ProgressStatus.cs
index a1febc90..6f0a8e79 100644
--- a/DataType/ProgressStatus.cs
+++ b/DataType/ProgressStatus.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.ComponentModel;
namespace PriconneBotConsoleApp.DataType
{
@@ -25,6 +20,6 @@ public enum ProgressStatus : byte
SOS,
[Description("🏃")]
- CarryOver,
+ SubdueBoss,
}
}
diff --git a/DataType/ShioriFeature/ChannelFeatureType.cs b/DataType/ShioriFeature/ChannelFeatureType.cs
index 5009709b..c0c9e151 100644
--- a/DataType/ShioriFeature/ChannelFeatureType.cs
+++ b/DataType/ShioriFeature/ChannelFeatureType.cs
@@ -5,6 +5,9 @@ public enum ChannelFeatureType : uint
{
Unknown = 0,
+ /// すべてのチャンネルで利用できるコマンドにつけられる.
+ All = 9999,
+
DeclareID = 1001,
ReserveID = 1002,
ReserveResultID = 1003,
diff --git a/DataType/WarningType.cs b/DataType/WarningType.cs
new file mode 100644
index 00000000..8cc0c060
--- /dev/null
+++ b/DataType/WarningType.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PriconneBotConsoleApp.DataType
+{
+ public enum WarningType
+ {
+ [Description("コメントが長いので切り取られました。\n 問題がある場合は予約削除をして再度予約してください。") ]
+ TooLongComment,
+ }
+}
diff --git a/Database/Shiori/DatabaseProgressController.cs b/Database/Shiori/DatabaseProgressController.cs
index 5c13a8c7..89bb012d 100644
--- a/Database/Shiori/DatabaseProgressController.cs
+++ b/Database/Shiori/DatabaseProgressController.cs
@@ -23,10 +23,11 @@ public static IEnumerable GetProgressData(ClanData clanData, BossN
public static IEnumerable GetProgressData(PlayerData playerData, BossNumberType bossNumber)
{
+ var playerID = playerData?.PlayerID ?? 0;
using var databaseConnector = new DatabaseConnector();
return databaseConnector.ProgressData.AsQueryable()
- .Where(x => x.PlayerID == playerData.PlayerID && x.BossNumber == (byte)bossNumber && !x.DeleteFlag)
+ .Where(x => x.PlayerID == playerID && x.BossNumber == (byte)bossNumber && !x.DeleteFlag)
.ToArray();
}
diff --git a/Database/Shiori/DatabaseReservationController.cs b/Database/Shiori/DatabaseReservationController.cs
index f644d435..f6424f1d 100644
--- a/Database/Shiori/DatabaseReservationController.cs
+++ b/Database/Shiori/DatabaseReservationController.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using PriconneBotConsoleApp.DataModel;
@@ -35,24 +36,22 @@ public static List LoadReservationData(ClanData clanData)
public static List LoadReservationData(PlayerData playerData)
{
- if (playerData == null)
+ if (playerData == null|| playerData.PlayerID == 0)
{
return null;
}
using var databaseConnector = new DatabaseConnector();
- var playerID = LoadPlayerID(databaseConnector.PlayerData, playerData);
-
return databaseConnector.ReservationData.AsQueryable()
- .Where(b => b.PlayerID == playerID && !b.DeleteFlag)
+ .Where(b => b.PlayerID == playerData.PlayerID && !b.DeleteFlag)
.OrderBy(o => o.BattleLap).ThenBy(d => d.BossNumber)
.ToList();
}
public static IEnumerable LoadReservationData(ClanData clanData, int bossNumber)
{
- if (bossNumber < CommonDefine.MinBossNumber || bossNumber > CommonDefine.MaxBossNumber)
+ if (!CommonDefine.IsValidBossNumber(bossNumber))
{
return null;
}
@@ -67,7 +66,7 @@ public static IEnumerable LoadReservationData(ClanData clanData
public static List LoadBossLapReservationData(ClanData clanData, int bossNumber)
{
- if (bossNumber < CommonDefine.MinBossNumber || bossNumber > CommonDefine.MaxBossNumber)
+ if (!CommonDefine.IsValidBossNumber(bossNumber))
{
return null;
}
@@ -96,28 +95,25 @@ public static List LoadBossLapReservationData(ClanData clanData
///
public static void CreateReservationData(ReservationData reservationData)
{
- var playerData = reservationData.PlayerData;
- using var databaseConnector = new DatabaseConnector();
- var transaction = databaseConnector.Database.BeginTransaction();
- var playerID = LoadPlayerID(databaseConnector.PlayerData, playerData);
-
- if (playerID == 0)
+ if (reservationData.PlayerID == 0)
{
- transaction.Rollback();
return;
}
- databaseConnector.ReservationData.Add(
- new ReservationData()
- {
- PlayerID = playerID,
- BattleLap = reservationData.BattleLap,
- BossNumber = reservationData.BossNumber,
- CommentData = reservationData.CommentData
- });
+ using var databaseConnector = new DatabaseConnector();
+ var transaction = databaseConnector.Database.BeginTransaction();
- databaseConnector.SaveChanges();
- transaction.Commit();
+ databaseConnector.ReservationData.Add(reservationData);
+
+ try
+ {
+ databaseConnector.SaveChanges();
+ transaction.Commit();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
}
///
@@ -126,30 +122,20 @@ public static void CreateReservationData(ReservationData reservationData)
///
public static void UpdateReservationData(ReservationData reservationData)
{
- var playerData = reservationData.PlayerData;
using var databaseConnector = new DatabaseConnector();
var transaction = databaseConnector.Database.BeginTransaction();
- var playerID = LoadPlayerID(databaseConnector.PlayerData, playerData);
+ var updateData = databaseConnector.ReservationData.FirstOrDefault(x => x.ReserveID == reservationData.ReserveID);
- if (playerID == 0)
+ try
{
- transaction.Rollback();
- return;
+ updateData.CommentData = reservationData.CommentData;
+ databaseConnector.SaveChanges();
+ transaction.Commit();
}
-
- var updateData = databaseConnector.ReservationData
- .FirstOrDefault(d => d.PlayerID == playerID && d.BattleLap == reservationData.BattleLap
- && d.BossNumber == reservationData.BossNumber && !d.DeleteFlag);
-
- if (updateData == null)
+ catch
{
transaction.Rollback();
- return;
}
-
- updateData.CommentData = reservationData.CommentData;
- databaseConnector.SaveChanges();
- transaction.Commit();
}
public static void DeleteReservationData(ReservationData reservationData)
@@ -162,7 +148,6 @@ public static void DeleteReservationData(IEnumerable reservatio
foreach (var reservationData in reservationDataSet)
{
-
var updateData = databaseConnector.ReservationData.AsQueryable()
.FirstOrDefault(d => d.PlayerID == reservationData.PlayerID && d.BossNumber == reservationData.BossNumber
&& d.BattleLap == reservationData.BattleLap && !d.DeleteFlag);
@@ -176,15 +161,5 @@ public static void DeleteReservationData(IEnumerable reservatio
databaseConnector.SaveChanges();
transaction.Commit();
}
-
- private static ulong LoadPlayerID(IQueryable queryable, PlayerData playerData)
- {
- return queryable
- .Include(b => b.ClanData)
- .FirstOrDefault(b => b.ClanData.ServerID == playerData.ClanData.ServerID
- && b.ClanData.ClanRoleID == playerData.ClanData.ClanRoleID
- && b.UserID == playerData.UserID)
- ?.PlayerID ?? 0;
- }
}
}
diff --git a/Define/ClanBattleDefine.cs b/Define/ClanBattleDefine.cs
index 84e6af72..701edba8 100644
--- a/Define/ClanBattleDefine.cs
+++ b/Define/ClanBattleDefine.cs
@@ -2,6 +2,9 @@
{
public static class ClanBattleDefine
{
- public const short MaxLapNumber = 250;
+ public const ushort MaxLapNumber = 250;
+
+ public static bool IsValidLapNumber(int value)
+ => 0 <= value && value <= MaxLapNumber;
}
}
diff --git a/Define/CommonDefine.cs b/Define/CommonDefine.cs
index 5c9dac39..43cb2641 100644
--- a/Define/CommonDefine.cs
+++ b/Define/CommonDefine.cs
@@ -19,5 +19,14 @@ public static class CommonDefine
public const int MaxDamageValue = 999999;
public const int DisplayDamageUnit = 10000;
+
+ public static bool IsValidBossNumber(int value)
+ => MinBossNumber <= value && value <= MaxBossNumber;
+
+ public static bool IsValidBattleTime(int value)
+ => MinBattleTime <= value && value <= MaxBattleTime;
+
+ public static bool IsValidDamageValue(int value)
+ => 0 <= value && value <= MaxDamageValue;
}
}
diff --git a/Define/TimeDefine.cs b/Define/TimeDefine.cs
index 0fcb6dc1..8bb0a977 100644
--- a/Define/TimeDefine.cs
+++ b/Define/TimeDefine.cs
@@ -8,6 +8,7 @@ public static class TimeDefine
public readonly static TimeSpan DailyRefreshTime = new(5, 0, 30);
public readonly static TimeSpan ErrorMessageDisplayTime = new(0, 0, 5);
+ public readonly static TimeSpan WarningMessageDisplayTime = new(0, 0, 20);
public readonly static TimeSpan SuccessMessageDisplayTime = new(0, 0, 30);
}
}
diff --git a/Extension/DictionaryExtension.cs b/Extension/DictionaryExtension.cs
index 97a43ff0..59815ad6 100644
--- a/Extension/DictionaryExtension.cs
+++ b/Extension/DictionaryExtension.cs
@@ -1,22 +1,51 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
namespace PriconneBotConsoleApp.Extension
{
public static class DictionaryExtension
{
public static TValue GetValueOrInitialize(
- this IDictionary dictionary,
- TKey key,
- Func initializer)
+ [NotNull] this IDictionary dictionary,
+ [NotNull] TKey key,
+ [NotNull] Func initializer)
=> dictionary.TryGetValue(key, out var result)
? result
: dictionary[key] = initializer();
- public static void Deconstruct(
- this KeyValuePair pair,
- out Tkey key,
- out TValue value)
+ ///
+ /// を複数のキーで検索できるようにしたバージョン
+ ///
+ /// paramsに対応するため、out引数を先に書く必要がある点に注意
+ ///
+ /// 検索対象の辞書
+ /// 検索結果 (無い場合はdefaultになる)
+ /// キーの候補 (前方から順に検索される)
+ /// 辞書のキーの型
+ /// 辞書の値の型
+ ///
+ public static bool TryGetValueMany(
+ [NotNull] this IDictionary dictionary,
+ [NotNull] out TValue value,
+ [NotNull] params TKey[] keys)
+ {
+ foreach (var key in keys)
+ {
+ if (dictionary.TryGetValue(key, out value))
+ {
+ return true;
+ }
+ }
+
+ value = default;
+ return false;
+ }
+
+ public static void Deconstruct(
+ [NotNull] this KeyValuePair pair,
+ [NotNull] out TKey key,
+ [NotNull] out TValue value)
=> (key, value) = (pair.Key, pair.Value);
}
}
diff --git a/Extension/EnumExtension.cs b/Extension/EnumExtension.cs
index fb8abb49..4a74f00b 100644
--- a/Extension/EnumExtension.cs
+++ b/Extension/EnumExtension.cs
@@ -1,30 +1,43 @@
-using PriconneBotConsoleApp.Attribute;
-using System;
+using System;
using System.ComponentModel;
using System.Reflection;
+using PriconneBotConsoleApp.Attribute;
+using PriconneBotConsoleApp.DataType;
namespace PriconneBotConsoleApp.Extension
{
public static class EnumExtension
{
- public static string GetDescription(this Enum type)
+ public static string GetDescription(this T enumValue) where T : Enum
{
- var descriptionAttribute = type.GetType()
- .GetField(type.ToString()).GetCustomAttribute(false);
+ var enumString = enumValue.ToString();
- return descriptionAttribute?.Description ?? type.ToString();
+ return typeof(T).GetField(enumString)?.GetCustomAttribute(false)?.Description
+ ?? enumString;
}
- public static MultiDescriptionData GetMultiDescripion(this Enum enumValue)
- => enumValue.GetType()
- .GetField(enumValue.ToString())
- .GetCustomAttribute(false)
- ?.Data
- ?? new MultiDescriptionData
- {
- LongDescription = enumValue.ToString(),
- ShortDescription = string.Empty,
- Aliases = Array.Empty(),
- };
+ public static MultiDescriptionData GetMultiDescription(this T enumValue) where T : Enum
+ {
+ var enumString = enumValue.ToString();
+
+ return typeof(T).GetField(enumString)?.GetCustomAttribute(false)?.Data
+ ?? new MultiDescriptionData
+ {
+ LongDescription = enumString,
+ ShortDescription = string.Empty,
+ Aliases = Array.Empty()
+ };
+ }
+
+ public static BossNumberType GetBossNumberType(this ChannelFeatureType channelFeatureType)
+ => channelFeatureType switch
+ {
+ ChannelFeatureType.ProgressBoss1ID => BossNumberType.Boss1Number,
+ ChannelFeatureType.ProgressBoss2ID => BossNumberType.Boss2Number,
+ ChannelFeatureType.ProgressBoss3ID => BossNumberType.Boss3Number,
+ ChannelFeatureType.ProgressBoss4ID => BossNumberType.Boss4Number,
+ ChannelFeatureType.ProgressBoss5ID => BossNumberType.Boss5Number,
+ _ => throw new ArgumentException($"Cannot cast to BossNumberType. {channelFeatureType}")
+ };
}
}
diff --git a/Extension/EnumerableExtension.cs b/Extension/EnumerableExtension.cs
new file mode 100644
index 00000000..bfa4920f
--- /dev/null
+++ b/Extension/EnumerableExtension.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+
+namespace PriconneBotConsoleApp.Extension
+{
+ public static class EnumerableExtension
+ {
+ public static void ForEach([NotNull] this IEnumerable source, [NotNull] Action action)
+ {
+ foreach (var element in source)
+ {
+ action(element);
+ }
+ }
+
+ public static TSource MaxBy([NotNull] this IEnumerable source, [NotNull] Func func)
+ where TValue : IComparable
+ {
+ var firstFlag = true;
+ TValue maxValue = default;
+ TSource maxSource = default;
+
+ foreach (var element in source)
+ {
+ var value = func(element);
+
+ if (firstFlag || value.CompareTo(maxValue) > 0)
+ {
+ maxValue = value;
+ maxSource = element;
+ firstFlag = false;
+ }
+ }
+
+ return maxSource;
+ }
+ }
+}
diff --git a/Extension/IEnumerableExtension.cs b/Extension/IEnumerableExtension.cs
deleted file mode 100644
index d557000c..00000000
--- a/Extension/IEnumerableExtension.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace PriconneBotConsoleApp.Extension
-{
- public static class IEnumerableExtension
- {
- public static void ForEach(this IEnumerable source, Action action)
- {
- foreach (T element in source)
- {
- action(element);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Script/ClanBattle/BattleCarryOver.cs b/Script/ClanBattle/BattleCarryOver.cs
index a6e2e8b1..38797a00 100644
--- a/Script/ClanBattle/BattleCarryOver.cs
+++ b/Script/ClanBattle/BattleCarryOver.cs
@@ -14,9 +14,7 @@ namespace PriconneBotConsoleApp.Script
{
public class BattleCarryOver
{
- private readonly ClanData m_ClanData;
- private readonly SocketUserMessage m_UserMessage;
- private readonly SocketRole m_ClanRole;
+ private readonly CommandEventArgs m_CommandEventArgs;
private class PlayerInfo
{
@@ -47,165 +45,145 @@ public string GetCarryOverString()
}
}
- public BattleCarryOver(ClanData clanData, SocketUserMessage userMessage)
+ public BattleCarryOver(CommandEventArgs commandEventArgs)
{
- m_ClanData = clanData;
- m_UserMessage = userMessage;
- var guild = (userMessage.Channel as SocketTextChannel)?.Guild;
- m_ClanRole = guild?.GetRole(clanData.ClanRoleID);
- }
-
- public async Task RunByMessage()
- {
- var messageContent = m_UserMessage.Content;
-
- if (messageContent.StartsWith("!"))
- {
- if (messageContent.StartsWith("!init"))
- {
- InitAllData();
- }
- else if (messageContent.StartsWith("!rm"))
- {
- UpdateOtherPlayerData();
- }
- else if (messageContent.StartsWith("!list"))
- {
- await SendClanCarryOverList();
- }
-
- }
- else
- {
- UpdateCarryOverData();
- }
+ m_CommandEventArgs = commandEventArgs;
}
///
- /// 個人の持ち越し所持・消化報告
+ /// 持ち越しを登録するか更新する. 引数は2以上
///
- private void UpdateCarryOverData()
+ public void UpdateCarryOverData()
{
- const int minCommandLength = 1;
- // TODO : " "を定数化する。
- var splitMessage = m_UserMessage.Content.ZenToHan().Split(" ", StringSplitOptions.RemoveEmptyEntries);
- var result = false;
+ var playerData = DatabasePlayerDataController
+ .LoadPlayerData(m_CommandEventArgs.Role, m_CommandEventArgs.SocketUserMessage.Author.Id);
- if (splitMessage.Length < minCommandLength)
+ if (!byte.TryParse(m_CommandEventArgs.Arguments[0], out var bossNumber)
+ || !byte.TryParse(m_CommandEventArgs.Arguments[1], out var remainTime)
+ || !CommonDefine.IsValidBossNumber(bossNumber)
+ || !CommonDefine.IsValidBattleTime(remainTime)
+ || playerData == null)
{
return;
}
- // TODO : 持ち越し番号をEnum化
-
- if (EnumMapper.TryParse(splitMessage.First(), out var attackType)
- && attackType == AttackType.CarryOver)
+ CarryOverData carryOverData = new()
{
- var userCarryOverData = CommandToCarryOverData(splitMessage);
+ BossNumber = bossNumber,
+ RemainTime = remainTime,
+ // TODO : " "を定数化する。
+ CommentData = string.Join(" ", m_CommandEventArgs.Arguments.Skip(2)),
+ PlayerID = playerData.PlayerID,
+ };
- if (userCarryOverData == null)
- {
- return;
- }
+ var databaseCarryOverList = DatabaseCarryOverController.GetCarryOverData(playerData).ToArray();
+ var databaseCarryOverData = databaseCarryOverList.FirstOrDefault(x => x.BossNumber == carryOverData.BossNumber && x.RemainTime == carryOverData.RemainTime);
+ var result = false;
- var userID = m_UserMessage.Author.Id;
- var playerData = DatabasePlayerDataController.LoadPlayerData(m_ClanRole, userID);
+ if (databaseCarryOverData != null)
+ {
+ carryOverData.CarryOverID = databaseCarryOverData.CarryOverID;
+ result = DatabaseCarryOverController.UpdateCarryOverData(carryOverData);
+ }
+ else if (databaseCarryOverList.Length < CommonDefine.MaxCarryOverNumber)
+ {
+ result = DatabaseCarryOverController.CreateCarryOverData(carryOverData);
+ }
- if (playerData == null)
- {
- return;
- }
+ if (result)
+ {
+ _ = m_CommandEventArgs.SocketUserMessage.AddReactionAsync(ReactionType.Success.ToEmoji());
+ }
+ }
- var databaseCarryOverList = DatabaseCarryOverController.GetCarryOverData(playerData).ToArray();
- var databaseCarryOverData = databaseCarryOverList.FirstOrDefault(x => x.BossNumber == userCarryOverData.BossNumber && x.RemainTime == userCarryOverData.RemainTime);
+ ///
+ /// 持ち越しデータを削除する時に用いる。引数0か1。
+ ///
+ public void DeleteCarryOverData()
+ {
+ const int defaultDeleteNumber = 1;
+ var playerData = DatabasePlayerDataController.LoadPlayerData(m_CommandEventArgs.Role, m_CommandEventArgs.User.Id);
- if (databaseCarryOverData == null && databaseCarryOverList.Length < CommonDefine.MaxCarryOverNumber)
- {
- result = DatabaseCarryOverController.CreateCarryOverData(userCarryOverData);
- }
- else if (databaseCarryOverData != null)
- {
- userCarryOverData.CarryOverID = databaseCarryOverData.CarryOverID;
- result = DatabaseCarryOverController.UpdateCarryOverData(userCarryOverData);
- }
- }
- // TODO:ここの消化記述を別にまとめたい
- else if (splitMessage.First() == "消化")
+ try
{
- var playerData = DatabasePlayerDataController.LoadPlayerData(m_ClanRole, m_UserMessage.Author.Id);
-
- if (splitMessage.Length > 1 && byte.TryParse(splitMessage[1], out byte deleteNumber))
+ if (byte.TryParse(m_CommandEventArgs.Arguments.ElementAtOrDefault(0), out var deleteNumber))
{
- result = DeleteCarryOverData(playerData, deleteNumber);
+ DeletePlayerCarryOverData(playerData, deleteNumber);
}
else
{
- result = DeleteCarryOverData(playerData);
+ DeletePlayerCarryOverData(playerData, defaultDeleteNumber);
}
}
-
- if (result)
+ catch
{
- _ = m_UserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
+ return;
}
+
+ _ = m_CommandEventArgs.SocketUserMessage.AddReactionAsync(ReactionType.Success.ToEmoji());
}
- private void UpdateOtherPlayerData()
+ ///
+ /// 他人の持越しを削除する。引数は2つ必要とする。
+ ///
+ public void DeleteOtherPlayerData()
{
- const int minCommandLength = 1;
-
- // TODO : " "を定数化する。
- var splitMessage = m_UserMessage.Content.ZenToHan().Split(" ", StringSplitOptions.RemoveEmptyEntries);
+ var targetUser = MentionUtils.TryParseUser(m_CommandEventArgs.Arguments[0], out var userID)
+ || ulong.TryParse(m_CommandEventArgs.Arguments[0], out userID)
+ ? m_CommandEventArgs.Role.Guild.GetUser(userID)
+ : throw new ArgumentNullException("ユーザー情報がありません。");
- if (splitMessage.Length <= minCommandLength || m_UserMessage.MentionedUsers.FirstOrDefault()?.Id is not ulong userID)
+ // コマンドは `!rm @削除対象のユーザー 古い方から何番目か` としている。
+ if (!byte.TryParse(m_CommandEventArgs.Arguments[1], out var number)
+ || number <= 0
+ || CommonDefine.MaxReportNumber < number)
{
- return;
+ throw new ArgumentOutOfRangeException("持ち越しがありません。");
}
- // コマンドは `!rm @削除対象のユーザー 古い方から何番目か` としている。
- var deleteNumber = (splitMessage.Length > minCommandLength + 1 && byte.TryParse(splitMessage[minCommandLength + 1], out var number)) ? number : (byte)0;
+ var playerData = DatabasePlayerDataController.LoadPlayerData(m_CommandEventArgs.Role, targetUser.Id);
- var playerData = DatabasePlayerDataController.LoadPlayerData(m_ClanRole, userID);
-
- if (DeleteCarryOverData(playerData, deleteNumber))
+ try
+ {
+ DeletePlayerCarryOverData(playerData, number);
+ _ = m_CommandEventArgs.SocketUserMessage.AddReactionAsync(ReactionType.Success.ToEmoji());
+ }
+ catch (Exception e)
{
- _ = m_UserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
+ Console.WriteLine(e.Message);
}
}
- private async Task SendClanCarryOverList()
+ ///
+ /// 持ち越しリストを表示するコマンド。引数0か1。
+ ///
+ ///
+ public async Task SendClanCarryOverList()
{
var clanCarryOverEmbed = CreateEmbedData();
- await m_UserMessage.Channel.SendMessageAsync(embed: clanCarryOverEmbed);
+ await m_CommandEventArgs.Channel.SendMessageAsync(embed: clanCarryOverEmbed);
}
- private bool DeleteCarryOverData(PlayerData playerData, byte deleteNumber = 0)
+ private void DeletePlayerCarryOverData(PlayerData playerData, byte deleteNumber)
{
var carryOverList = DatabaseCarryOverController.GetCarryOverData(playerData)
- .OrderBy(x => x.DateTime).ToArray();
+ .OrderBy(x => x.DateTime)
+ .ToArray();
if (carryOverList.Length == 0)
{
- return false;
+ throw new ArgumentOutOfRangeException("持ち越しがありません。");
}
- var result = false;
-
- if (deleteNumber > 0 && deleteNumber <= carryOverList.Length)
- {
- result = DatabaseCarryOverController.DeleteCarryOverData(carryOverList[deleteNumber - 1]);
- }
- else
- {
- result = DatabaseCarryOverController.DeleteCarryOverData(carryOverList.First());
- }
-
- return result;
+ DatabaseCarryOverController.DeleteCarryOverData(carryOverList[(deleteNumber > 0 && deleteNumber <= carryOverList.Length) ? deleteNumber - 1 : 0]);
}
- private void InitAllData()
+ ///
+ /// 全ての持ち越しを削除する。引数は0。
+ ///
+ public void InitAllData()
{
- var carryOverList = DatabaseCarryOverController.GetCarryOverData(m_ClanData);
+ var carryOverList = DatabaseCarryOverController.GetCarryOverData(m_CommandEventArgs.ClanData);
if (!carryOverList.Any())
{
@@ -213,41 +191,21 @@ private void InitAllData()
}
DatabaseCarryOverController.DeleteCarryOverData(carryOverList);
- _ = m_UserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
- }
+ _ = m_CommandEventArgs.SocketUserMessage.AddReactionAsync(ReactionType.Success.ToEmoji());
- private CarryOverData CommandToCarryOverData(string[] messageData)
- {
- const int bossNumberColumn = 1;
- const int remainTimeColumn = 2;
- const int messageMinLength = 3;
-
- if (messageData.Length < messageMinLength ||
- !byte.TryParse(messageData[bossNumberColumn], out var bossNumber) || !byte.TryParse(messageData[remainTimeColumn], out var remainTime)
- || bossNumber < CommonDefine.MinBossNumber || bossNumber > CommonDefine.MaxBossNumber
- || remainTime < CommonDefine.MinBattleTime || remainTime > CommonDefine.MaxBattleTime)
- {
- return null;
- }
-
- var playerID = DatabasePlayerDataController.LoadPlayerData(m_ClanRole, m_UserMessage.Author.Id).PlayerID;
-
- return new CarryOverData()
- {
- BossNumber = bossNumber,
- RemainTime = remainTime,
- // TODO : " "を定数化する。
- CommentData = string.Join(" ", messageData.Skip(3)),
- PlayerID = playerID,
- };
+ _ = m_CommandEventArgs.Channel.SendTimedMessageAsync(
+ TimeDefine.SuccessMessageDisplayTime,
+ string.Format(EnumMapper.ToLabel(InformationType.DeleteAllCarryOverData), TimeDefine.SuccessMessageDisplayTime)
+ );
}
// 持ち越しを表示するUIを考える
private Embed CreateEmbedData()
{
- var carryOverArray = DatabaseCarryOverController.GetCarryOverData(m_ClanData)
+ var carryOverArray = DatabaseCarryOverController.GetCarryOverData(m_CommandEventArgs.ClanData)
.OrderBy(x => x.DateTime);
- var playerArray = DatabasePlayerDataController.LoadPlayerData(m_ClanData);
+
+ var playerArray = DatabasePlayerDataController.LoadPlayerData(m_CommandEventArgs.ClanData);
List carryOverStringList = new();
foreach (var playerData in playerArray)
diff --git a/Script/ClanBattle/BattleDeclaration.cs b/Script/ClanBattle/BattleDeclaration.cs
index 7d72d56e..582bc32f 100644
--- a/Script/ClanBattle/BattleDeclaration.cs
+++ b/Script/ClanBattle/BattleDeclaration.cs
@@ -80,9 +80,9 @@ public async Task RunDeclarationCommandByMessage()
if (m_UserMessage.Content.StartsWith("!call"))
{
await DeclarationCallCommand();
- var battleReservation = new BattleReservation(m_UserRole);
- battleReservation.DeleteUnusedData(m_BossNumber);
- await battleReservation.UpdateSystemMessage();
+ var battleReservationSummary = new BattleReservationSummary(m_UserRole);
+ battleReservationSummary.DeleteUnusedData(m_BossNumber);
+ await battleReservationSummary.UpdateMessage();
}
}
@@ -119,7 +119,7 @@ public async Task RunByInteraction()
case ButtonType.SubdueBoss:
await NextBossCommand();
- await new BattleReservation(m_UserRole).UpdateSystemMessage();
+ await new BattleReservationSummary(m_UserRole).UpdateMessage();
return;
case ButtonType.CancelBattle:
@@ -128,7 +128,7 @@ public async Task RunByInteraction()
}
await UpdateDeclarationBotMessage();
- await new BattleReservation(m_UserRole).UpdateSystemMessage();
+ await new BattleReservationSummary(m_UserRole).UpdateMessage();
}
///
@@ -307,9 +307,9 @@ private async Task NextBossCommand()
m_UserClanData.SetBossLap(m_BossNumber, nextBattleLap);
DatabaseClanDataController.UpdateClanData(m_UserClanData);
- var battleReservation = new BattleReservation(m_UserRole);
- battleReservation.DeleteUnusedData(m_BossNumber);
- await Task.WhenAll(SendDeclarationBotMessage(), battleReservation.UpdateSystemMessage());
+ var battleReservationSummary = new BattleReservationSummary(m_UserRole);
+ battleReservationSummary.DeleteUnusedData(m_BossNumber);
+ await Task.WhenAll(SendDeclarationBotMessage(), battleReservationSummary.UpdateMessage());
}
///
diff --git a/Script/ClanBattle/BattleProgress.cs b/Script/ClanBattle/BattleProgress.cs
index a7dd4d04..ff184f50 100644
--- a/Script/ClanBattle/BattleProgress.cs
+++ b/Script/ClanBattle/BattleProgress.cs
@@ -9,20 +9,13 @@
using PriconneBotConsoleApp.DataModel;
using PriconneBotConsoleApp.DataType;
using PriconneBotConsoleApp.Define;
-using PriconneBotConsoleApp.Extension;
namespace PriconneBotConsoleApp.Script
{
public class BattleProgress
{
- private readonly SocketUserMessage m_UserMessage;
- private readonly SocketRole m_UserRole;
- private readonly ClanData m_UserClanData;
- private readonly SocketGuild m_Guild;
- private readonly byte m_BossNumber;
- private readonly bool m_AllBattleFlag = true;
-
- private ProgressData m_UserProgressData;
+ private readonly CommandEventArgs m_CommandEventArgs;
+ private readonly BossNumberType m_BossNumberType;
private class PlayerInfo
{
@@ -44,7 +37,7 @@ public string GetNameWithData()
return string.Join(
halfSizeWhitespace,
- ((ProgressStatus) ProgressData.Status).ToLabel(),
+ ((ProgressStatus)ProgressData.Status).ToLabel(),
ProgressData.CarryOverFlag ? "持" : fullSizeWhitespace,
$"{ProgressData.Damage,6}@{ProgressData.RemainTime:D2}",
((AttackType)ProgressData.AttackType).ToShortLabel(),
@@ -55,177 +48,162 @@ public string GetNameWithData()
}
}
- public BattleProgress(ClanData clanData, SocketUserMessage userMessage, byte bossNumber)
+ public BattleProgress(CommandEventArgs commandEventArgs)
+ {
+ m_CommandEventArgs = commandEventArgs;
+ m_BossNumberType = ChannelTypeToBossNumber(m_CommandEventArgs.ChannelFeatureType);
+ }
+
+ ///
+ /// 進行を開始するコマンド。引数は「ボス番号」。
+ ///
+ ///
+ public async Task Start()
{
- if (clanData.RoleData == null || clanData.ChannelData == null || clanData.MessageData == null)
+ if (!ushort.TryParse(m_CommandEventArgs.Arguments[0], out var lap)
+ || !ClanBattleDefine.IsValidLapNumber(lap))
{
- clanData = DatabaseClanDataController.LoadClanData(m_UserRole);
+ return;
}
- m_BossNumber = bossNumber;
- m_UserClanData = clanData;
- m_UserMessage = userMessage;
- m_Guild = (userMessage.Channel as SocketTextChannel)?.Guild;
- m_UserRole = m_Guild?.GetRole(clanData.ClanRoleID);
+ await ChangeLap(lap);
}
- public async Task RunByMessage()
+ public async Task SendList()
+ => await SendClanProgressList();
+
+ public async Task NextBoss()
+ => await ChangeLap();
+
+ ///
+ /// 編成データをアップデートする。
+ ///
+ ///
+ ///
+ public async Task UpdateAttackData(AttackType attackType)
{
- if (m_UserMessage.Content.StartsWith("!"))
+ if (!TryGetProgressData(out var userProgressData))
{
- if (m_UserMessage.Content.StartsWith("!init"))
- {
- InitializeProgressData();
- return;
- }
- else if (m_UserMessage.Content.StartsWith("!list"))
- {
- await SendClanProgressList();
- return;
- }
- else if (m_UserMessage.Content.StartsWith("!next"))
- {
- await ChangeLap();
- return;
- }
- else if (m_UserMessage.Content.StartsWith("!call"))
- {
- await CallProgress();
- return;
- }
- else if (m_UserMessage.Content.StartsWith("!rm"))
+ userProgressData = new ProgressData
{
- await RevertOrRevertUserData(true);
- return;
- }
- else if (m_UserMessage.Content.StartsWith("!rv"))
- {
- await RevertOrRevertUserData();
- return;
- }
+ PlayerID = m_CommandEventArgs.PlayerData.PlayerID,
+ BossNumber = (byte)m_BossNumberType,
+ BattleLap = (ushort)m_CommandEventArgs.ClanData.GetBossLap(m_BossNumberType),
+ };
+ }
+
+ if (attackType == AttackType.CarryOver)
+ {
+ userProgressData.CarryOverFlag = true;
}
else
{
- await UpdateProgressData();
+ userProgressData.AttackType = (byte)attackType;
}
- return;
+ await UpdateProgressData(userProgressData, m_CommandEventArgs.PlayerData);
}
- private async Task UpdateProgressData()
+ ///
+ /// ダメージ・残り時間を抽出。
+ ///
+ ///
+ ///
+ public async Task UpdateDamageData()
{
- var messageData = m_UserMessage.Content.ZenToHan().Split(" ", StringSplitOptions.RemoveEmptyEntries);
- var progressUser = m_UserMessage.Author;
+ // TODO : progressDataFlagでやりくりしているのが非常に見にくいので修正したい
+ var progressDataFlag = false;
+ int damageNumber = 0;
+ byte remainTimeNumber = 0;
- if (m_UserMessage.MentionedUsers.Count() == 1)
+ // TODO : 冗長なRegexの高速化 #131
+ if (Regex.IsMatch(m_CommandEventArgs.Name, @"\d+万$"))
{
- progressUser = m_UserMessage.MentionedUsers.FirstOrDefault();
- }
-
- var progressPlayerData = DatabasePlayerDataController.LoadPlayerData(m_UserRole, progressUser.Id);
- m_UserProgressData = DatabaseProgressController.GetProgressData(progressPlayerData, (BossNumberType)m_BossNumber)
- .Where(x => x.Status != (byte)ProgressStatus.AttackDone || x.Status != (byte)ProgressStatus.CarryOver)
- .FirstOrDefault();
-
- var successFlag = false;
+ if (!int.TryParse(Regex.Match(m_CommandEventArgs.Name, @"\d+").ToString(), out damageNumber)
+ || CommonDefine.IsValidDamageValue(damageNumber))
+ {
+ return;
+ }
- if (UpdateAttackData(messageData[0]))
- {
- successFlag = true;
- }
- else if (UpdateDamageData(messageData))
- {
- successFlag = true;
- }
- else if (m_UserProgressData == null)
- {
- return false;
- }
- else if (m_UserProgressData.ProgressID != 0 )
- {
- successFlag = UpdateStatusData(messageData);
+ progressDataFlag = true;
}
- if (!successFlag)
+ // TODO : 冗長なRegexの高速化 #131
+ if (Regex.IsMatch(m_CommandEventArgs.Name, @"\d+@\d+"))
{
- return false;
- }
+ var damageText = Regex.Match(m_CommandEventArgs.Name, @"\d+@").ToString();
+ var remainTimeText = Regex.Match(m_CommandEventArgs.Name, @"@\d+").ToString();
- if (m_UserProgressData.Status == (byte)ProgressStatus.Unknown)
- {
- m_UserProgressData.Status = (byte)ProgressStatus.AttackReported;
- }
+ if (!int.TryParse(Regex.Match(damageText, @"\d+").ToString(), out damageNumber)
+ || !byte.TryParse(Regex.Match(remainTimeText, @"\d+").ToString(), out remainTimeNumber)
+ || CommonDefine.IsValidDamageValue(damageNumber)
+ || remainTimeNumber > CommonDefine.MaxBattleTime)
+ {
+ return;
+ }
- m_UserProgressData.BossNumber = m_BossNumber;
- m_UserProgressData.BattleLap = (ushort)m_UserClanData.GetBossLap(m_BossNumber);
+ progressDataFlag = true;
+ }
- if (m_UserProgressData.ProgressID == 0)
+ if (!progressDataFlag)
{
- m_UserProgressData.PlayerID = progressPlayerData.PlayerID;
-
- if (DatabaseProgressController.CreateProgressData(m_UserProgressData))
- {
- _ = m_UserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
- await SendClanProgressList();
- return true;
- }
+ return;
}
- else
+
+ if (!TryGetProgressData(out var userProgressData))
{
- if (DatabaseProgressController.ModifyProgressData(m_UserProgressData))
+ userProgressData = new ProgressData()
{
- _ = m_UserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
- await SendClanProgressList();
- return true;
- }
+ PlayerID = m_CommandEventArgs.PlayerData.PlayerID,
+ BossNumber = (byte)m_BossNumberType,
+ BattleLap = (ushort)m_CommandEventArgs.ClanData.GetBossLap(m_BossNumberType),
+ };
}
- return false;
- }
-
- private async Task CallProgress()
- {
- var messageData = m_UserMessage.Content.ZenToHan().Split(" ", StringSplitOptions.RemoveEmptyEntries);
-
- if (messageData.Length != 2 || !ushort.TryParse(messageData[1], out var lap))
+ if (damageNumber == 0)
{
- return;
+ userProgressData.Status = (byte)ProgressStatus.SOS;
}
- await ChangeLap(lap);
+ userProgressData.Damage = (uint)damageNumber;
+ userProgressData.RemainTime = remainTimeNumber;
+ userProgressData.CommentData = string.Join(" ", m_CommandEventArgs.Arguments);
+ await UpdateProgressData(userProgressData, m_CommandEventArgs.PlayerData);
}
- private async Task ChangeLap(ushort lap = 0)
+ ///
+ /// 進行報告のステータス変更。引数 1か2。
+ ///
+ ///
+ ///
+ public async Task UpdateStatusData(ProgressStatus progressStatus)
{
- InitializeProgressData();
- var bossLap = m_UserClanData.GetBossLap(m_BossNumber);
-
- if (lap == 0)
- {
- m_UserClanData.SetBossLap(m_BossNumber, bossLap + 1);
- }
- else
+ if (!TryGetProgressData(out var userProgressData))
{
- m_UserClanData.SetBossLap(m_BossNumber, lap);
+ return;
}
- DatabaseClanDataController.UpdateClanData(m_UserClanData);
- await SendClanProgressList();
-
- return true;
+ userProgressData.Status = (byte)progressStatus;
+ await UpdateProgressData(userProgressData, m_CommandEventArgs.PlayerData);
}
- private async Task RevertOrRevertUserData(bool deleteFlag = false)
+ ///
+ /// 進行データの削除や戻しを行います。
+ ///
+ ///
+ ///
+ public async Task RemoveOrRevertUserData(bool deleteFlag = false)
{
- var userData = m_UserMessage.MentionedUsers.FirstOrDefault();
+ var userData = m_CommandEventArgs.SocketUserMessage.MentionedUsers.FirstOrDefault();
if (userData == null)
{
return;
}
- var playerData = DatabasePlayerDataController.LoadPlayerData(m_UserRole, userData.Id);
- var playerProgressData = DatabaseProgressController.GetProgressData(playerData, (BossNumberType)m_BossNumber)
+ var playerData = DatabasePlayerDataController.LoadPlayerData(m_CommandEventArgs.Role, userData.Id);
+
+ var playerProgressData = DatabaseProgressController.GetProgressData(playerData, m_BossNumberType)
.OrderByDescending(x => x.UpdateDateTime).FirstOrDefault();
if (playerProgressData == null)
@@ -247,229 +225,126 @@ private async Task RevertOrRevertUserData(bool deleteFlag = false)
}
///
- /// 凸報告の初期化
+ /// Initコマンドが入力されたとき
///
///
- private void InitializeProgressData()
+ public async Task InitCommand()
{
- var deleteData = DatabaseProgressController.GetProgressData(m_UserClanData, (BossNumberType)m_BossNumber);
-
- if (deleteData == null)
- {
- return;
- }
-
- if (DatabaseProgressController.DeleteProgressData(deleteData))
- {
- return;
- }
-
- return;
+ InitializeProgressData();
+ await SendClanProgressList();
}
- private async Task SendClanProgressList(bool removeLastMessage = true)
+ private async Task UpdateProgressData(ProgressData progressData, PlayerData playerData)
{
- var clanProgressEmbed = CreateProgressData();
- var sendMessage = await m_UserMessage.Channel.SendMessageAsync(embed: clanProgressEmbed);
- var bossNumber = 0;
- if (sendMessage == null)
+ if (progressData.Status == (byte)ProgressStatus.Unknown)
{
- return;
+ progressData.Status = (byte)ProgressStatus.AttackReported;
}
- if (m_AllBattleFlag)
+ if (progressData.ProgressID == 0)
{
- bossNumber = m_BossNumber;
- }
-
- var progressChannel = m_Guild.GetChannel(m_UserClanData.ChannelData.GetChannelID(m_UserClanData.ClanID, BossNumberToChannelType(bossNumber))) as SocketTextChannel;
- var lastMessageID = m_UserClanData.MessageData.GetMessageID(m_UserClanData.ClanID, BossNumberToMessageType(bossNumber));
- DatabaseMessageDataController.UpdateMessageID(m_UserClanData, sendMessage.Id, BossNumberToMessageType(bossNumber));
- var lastMessage = progressChannel.GetCachedMessage(lastMessageID);
+ progressData.PlayerID = playerData.PlayerID;
- if (lastMessage == null)
- {
- IMessage lastIMessage;
-
- try
+ if (DatabaseProgressController.CreateProgressData(progressData))
{
- lastIMessage = await progressChannel.GetMessageAsync(lastMessageID);
- }
- catch (Exception e)
- {
- Console.WriteLine(e.Message);
- return;
+ _ = m_CommandEventArgs.SocketUserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
+ await SendClanProgressList();
}
-
- await lastIMessage.DeleteAsync();
- return;
}
-
- await lastMessage.DeleteAsync();
- return;
- }
-
- ///
- /// 編成データをアップデートする。
- ///
- ///
- ///
- private bool UpdateAttackData(string inputCommand)
- {
- try
+ else
{
- var attackType = EnumMapper.Parse(inputCommand);
-
- if (m_UserProgressData == null)
- {
- m_UserProgressData = new ProgressData();
- }
-
- if (attackType == AttackType.CarryOver)
- {
- m_UserProgressData.CarryOverFlag = true;
- }
- else
+ if (DatabaseProgressController.ModifyProgressData(progressData))
{
- m_UserProgressData.AttackType = (byte)attackType;
+ _ = m_CommandEventArgs.SocketUserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
+ await SendClanProgressList();
}
-
- return true;
- }
- catch
- {
- return false;
}
}
- ///
- /// ダメージ・残り時間を抽出。
- ///
- ///
- ///
- private bool UpdateDamageData(string[] inputCommand)
+ private async Task ChangeLap(ushort lap = 0)
{
- var damageData = inputCommand.Select(x => Regex.Match(x, @"\d+万")).Where(x => x != null).FirstOrDefault().ToString();
+ InitializeProgressData();
+ var bossLap = m_CommandEventArgs.ClanData.GetBossLap(m_BossNumberType);
- if (damageData != "")
+ if (lap == 0)
{
- if (!uint.TryParse(Regex.Match(damageData, @"\d+").ToString(), out uint damageNumber)
- || damageNumber > CommonDefine.MaxDamageValue)
- {
- return false;
- }
-
- if (m_UserProgressData == null)
- {
- m_UserProgressData = new ProgressData();
- }
-
- if (damageNumber == 0)
- {
- m_UserProgressData.Status = (byte)ProgressStatus.SOS;
- }
-
- m_UserProgressData.Damage = damageNumber;
- var dataIndex = Array.IndexOf(inputCommand, damageData);
- m_UserProgressData.CommentData = string.Join(" ", inputCommand.Where((value, index) => index != dataIndex));
-
- return true;
+ m_CommandEventArgs.ClanData.SetBossLap(m_BossNumberType, bossLap + 1);
}
-
- var timeAndDamageData = inputCommand.Select(x => Regex.Match(x, @"\d+@\d+")).Where(x => x != null).FirstOrDefault().ToString();
-
- if (timeAndDamageData != "")
+ else
{
- var damageText = Regex.Match(timeAndDamageData, @"\d+@").ToString();
- var remainTimeText = Regex.Match(timeAndDamageData, @"@\d+").ToString();
-
- if (!uint.TryParse(Regex.Match(damageText, @"\d+").ToString(), out uint damageNumber)
- || !byte.TryParse(Regex.Match(remainTimeText, @"\d+").ToString(), out byte remainTimeNumber)
- || damageNumber > CommonDefine.MaxDamageValue || remainTimeNumber > CommonDefine.MaxBattleTime)
- {
- return false;
- }
-
- if (m_UserProgressData == null)
- {
- m_UserProgressData = new ProgressData();
- }
-
- if (damageNumber == 0)
- {
- m_UserProgressData.Status = (byte)ProgressStatus.SOS;
- }
-
- m_UserProgressData.Damage = damageNumber;
- m_UserProgressData.RemainTime = remainTimeNumber;
- var dataIndex = Array.IndexOf(inputCommand, timeAndDamageData);
- m_UserProgressData.CommentData = string.Join(" ", inputCommand.Where((value, index) => index != dataIndex));
-
- return true;
+ m_CommandEventArgs.ClanData.SetBossLap(m_BossNumberType, lap);
}
- return false;
+ DatabaseClanDataController.UpdateClanData(m_CommandEventArgs.ClanData);
+ await SendClanProgressList();
}
///
- /// 進行報告のステータス変更。
+ /// 凸進行報告状況の初期化
///
- ///
///
- private bool UpdateStatusData(string[] inputCommand)
+ private void InitializeProgressData()
{
- if (m_UserProgressData == null)
+ if (DatabaseProgressController.GetProgressData(m_CommandEventArgs.ClanData, m_BossNumberType) is { } deleteData)
{
- return false;
+ DatabaseProgressController.DeleteProgressData(deleteData);
}
+ }
- int maxSplitNumber = 2;
- var SplitData = inputCommand[0].Split("@", maxSplitNumber, StringSplitOptions.RemoveEmptyEntries);
-
- var dataUpdateFlag = SplitData[0] switch
- {
- "atk" or "凸確定" => m_UserProgressData.Status = (byte)ProgressStatus.AttackDone,
- "kari" or "仮確定" => m_UserProgressData.Status = (byte)ProgressStatus.AttackReady,
- "sos" or "ziko" or "jiko" or "事故" => m_UserProgressData.Status = (byte)ProgressStatus.SOS,
- "〆確定" or "fin" => m_UserProgressData.Status = (byte)ProgressStatus.CarryOver,
- _ => 0,
- };
+ private async Task SendClanProgressList(bool removeLastMessage = true)
+ {
+ var clanProgressEmbed = CreateProgressList();
+ var sendMessage = await m_CommandEventArgs.Channel.SendMessageAsync(embed: clanProgressEmbed);
- if (dataUpdateFlag == 0)
+ if (sendMessage == null)
{
- return false;
+ return;
}
- if (SplitData.Length == 1 || !uint.TryParse(SplitData[1], out uint damegeData))
+ var channelIDTemp = m_CommandEventArgs.ClanData.GetChannelID(BossNumberToChannelType(m_BossNumberType));
+ var progressChannel = m_CommandEventArgs.Role.Guild.GetChannel(channelIDTemp) as SocketTextChannel;
+ var lastMessageID = m_CommandEventArgs.ClanData.GetMessageID(BossNumberToMessageType(m_BossNumberType));
+ DatabaseMessageDataController.UpdateMessageID(m_CommandEventArgs.ClanData, sendMessage.Id, BossNumberToMessageType(m_BossNumberType));
+ var cachedMessage = progressChannel.GetCachedMessage(lastMessageID);
+
+ if (cachedMessage == null)
{
- return true;
- }
+ try
+ {
+ var message = await progressChannel.GetMessageAsync(lastMessageID);
- if (m_UserProgressData.Status == (byte)ProgressStatus.CarryOver)
+ if (removeLastMessage)
+ {
+ await message.DeleteAsync();
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+ }
+ else if (removeLastMessage)
{
- m_UserProgressData.RemainTime = (byte)damegeData;
- return true;
+ await cachedMessage.DeleteAsync();
}
-
- m_UserProgressData.Damage = damegeData;
-
- return true;
}
- private Embed CreateProgressData()
+ private Embed CreateProgressList()
{
- var clanProgressData = DatabaseProgressController.GetProgressData(m_UserClanData, (BossNumberType)m_BossNumber)
- .OrderBy(x => x.Status).ThenByDescending(x => x.Damage).ThenBy(x => x.CreateDateTime)
+ var clanPlayerDataList = DatabasePlayerDataController.LoadPlayerData(m_CommandEventArgs.ClanData);
+
+ var progressPlayer = DatabaseProgressController.GetProgressData(m_CommandEventArgs.ClanData, m_BossNumberType)
+ .OrderBy(x => x.Status)
+ .ThenByDescending(x => x.Damage)
+ .ThenBy(x => x.CreateDateTime)
+ .Select(x => new PlayerInfo(clanPlayerDataList.FirstOrDefault(y => y.PlayerID == x.PlayerID), x))
.ToArray();
- var clanPlayerDataList = DatabasePlayerDataController.LoadPlayerData(m_UserClanData);
- var progressPlayer = clanProgressData.Select(x => new PlayerInfo(
- clanPlayerDataList.FirstOrDefault(y => y.PlayerID == x.PlayerID),
- x
- )).ToArray();
- var bossLap = m_UserClanData.GetBossLap(m_BossNumber);
+
+ var bossLap = m_CommandEventArgs.ClanData.GetBossLap(m_BossNumberType);
+
var bossData = RediveClanBattleData.BossDataList
- .FirstOrDefault(x => x.BossNumber == m_BossNumber && x.LapNumberFrom <= bossLap && (x.LapNumberTo == -1 || x.LapNumberTo >= bossLap));
+ .FirstOrDefault(x => x.BossNumber == (byte)m_BossNumberType && x.LapNumberFrom <= bossLap && (x.LapNumberTo == -1 || x.LapNumberTo >= bossLap));
var summaryStringBuilder = new StringBuilder();
// 持ち越しデータ出力
@@ -478,19 +353,19 @@ private Embed CreateProgressData()
var remainAttackString = new StringBuilder();
remainAttackString.Append("残凸 ");
- var reportCount = DatabaseReportDataController.GetRemainPlayerCount(m_UserClanData);
+ var reportCount = DatabaseReportDataController.GetRemainPlayerCount(m_CommandEventArgs.ClanData);
for (int i = CommonDefine.MaxReportNumber; i >= 0; i--)
{
remainAttackString.Append((i == 0 ? "完凸:" : i + "凸:") + reportCount[i] + "人 ");
}
+
summaryStringBuilder.AppendLine(remainAttackString.ToString());
// ボスのHPをここに入力(万表示)
var bossHP = bossData?.HP / CommonDefine.DisplayDamageUnit ?? 0;
var sumAttackDoneHP = progressPlayer.Where(x => x.ProgressData.Status == (byte)ProgressStatus.AttackDone).Select(x => (int)x.ProgressData.Damage).Sum();
var sumAttackReadyHP = progressPlayer.Where(x => x.ProgressData.Status == (byte)ProgressStatus.AttackReady).Select(x => (int)x.ProgressData.Damage).Sum();
-
summaryStringBuilder.AppendLine("現在HP " + (bossHP - sumAttackDoneHP) + "万 / " + bossHP + "万");
summaryStringBuilder.AppendLine("仮確HP " + (bossHP - sumAttackReadyHP - sumAttackDoneHP) + "万 / " + bossHP + "万");
@@ -501,6 +376,7 @@ private Embed CreateProgressData()
};
var reportMessage = string.Join("\n", progressPlayer.Select(x => x.GetNameWithData()).ToArray());
+
var embedFieldBuilder = new EmbedFieldBuilder()
{
Name = "参加者",
@@ -510,7 +386,7 @@ private Embed CreateProgressData()
var embedBuilder = new EmbedBuilder();
embedBuilder.AddField(headerFieldBuilder);
embedBuilder.AddField(embedFieldBuilder);
- embedBuilder.Title = $"{m_UserClanData.GetBossLap(m_BossNumber)}周目 {m_BossNumber}ボス {bossData?.Name}";
+ embedBuilder.Title = $"{m_CommandEventArgs.ClanData.GetBossLap(m_BossNumberType)}周目 {(uint)m_BossNumberType}ボス {bossData?.Name}";
embedBuilder.Footer = new EmbedFooterBuilder()
{
@@ -520,30 +396,58 @@ private Embed CreateProgressData()
return embedBuilder.Build();
}
- private MessageFeatureType BossNumberToMessageType(int bossNumber)
+ private ProgressData GetProgressData(PlayerData playerData = null)
{
- return bossNumber switch
+ if (playerData == null)
{
- (int)BossNumberType.Boss1Number => MessageFeatureType.ProgressBoss1ID,
- (int)BossNumberType.Boss2Number => MessageFeatureType.ProgressBoss2ID,
- (int)BossNumberType.Boss3Number => MessageFeatureType.ProgressBoss3ID,
- (int)BossNumberType.Boss4Number => MessageFeatureType.ProgressBoss4ID,
- (int)BossNumberType.Boss5Number => MessageFeatureType.ProgressBoss5ID,
+ playerData = m_CommandEventArgs.PlayerData;
+ }
+
+ return DatabaseProgressController.GetProgressData(playerData, m_BossNumberType)
+ .Where(x => x.Status != (byte)ProgressStatus.AttackDone || x.Status != (byte)ProgressStatus.SubdueBoss)
+ .FirstOrDefault();
+ }
+
+ private bool TryGetProgressData(out ProgressData progressData)
+ => (progressData = GetProgressData()) != null;
+
+ private MessageFeatureType BossNumberToMessageType(BossNumberType bossNumberType)
+ {
+ return bossNumberType switch
+ {
+ BossNumberType.Boss1Number => MessageFeatureType.ProgressBoss1ID,
+ BossNumberType.Boss2Number => MessageFeatureType.ProgressBoss2ID,
+ BossNumberType.Boss3Number => MessageFeatureType.ProgressBoss3ID,
+ BossNumberType.Boss4Number => MessageFeatureType.ProgressBoss4ID,
+ BossNumberType.Boss5Number => MessageFeatureType.ProgressBoss5ID,
_ => MessageFeatureType.ProgressID,
};
}
- private ChannelFeatureType BossNumberToChannelType(int bossNumber)
+ private ChannelFeatureType BossNumberToChannelType(BossNumberType bossNumberType)
{
- return bossNumber switch
+ return bossNumberType switch
{
- (int)BossNumberType.Boss1Number => ChannelFeatureType.ProgressBoss1ID,
- (int)BossNumberType.Boss2Number => ChannelFeatureType.ProgressBoss2ID,
- (int)BossNumberType.Boss3Number => ChannelFeatureType.ProgressBoss3ID,
- (int)BossNumberType.Boss4Number => ChannelFeatureType.ProgressBoss4ID,
- (int)BossNumberType.Boss5Number => ChannelFeatureType.ProgressBoss5ID,
+ BossNumberType.Boss1Number => ChannelFeatureType.ProgressBoss1ID,
+ BossNumberType.Boss2Number => ChannelFeatureType.ProgressBoss2ID,
+ BossNumberType.Boss3Number => ChannelFeatureType.ProgressBoss3ID,
+ BossNumberType.Boss4Number => ChannelFeatureType.ProgressBoss4ID,
+ BossNumberType.Boss5Number => ChannelFeatureType.ProgressBoss5ID,
_ => ChannelFeatureType.ProgressID,
};
}
+
+ private BossNumberType ChannelTypeToBossNumber(ChannelFeatureType channelFeatureType)
+ {
+ return channelFeatureType switch
+ {
+ ChannelFeatureType.ProgressBoss1ID => BossNumberType.Boss1Number,
+ ChannelFeatureType.ProgressBoss2ID => BossNumberType.Boss2Number,
+ ChannelFeatureType.ProgressBoss3ID => BossNumberType.Boss3Number,
+ ChannelFeatureType.ProgressBoss4ID => BossNumberType.Boss4Number,
+ ChannelFeatureType.ProgressBoss5ID => BossNumberType.Boss5Number,
+ _ => BossNumberType.Unknown,
+ };
+ }
}
}
diff --git a/Script/ClanBattle/BattleReport.cs b/Script/ClanBattle/BattleReport.cs
index 9f48755f..082d6862 100644
--- a/Script/ClanBattle/BattleReport.cs
+++ b/Script/ClanBattle/BattleReport.cs
@@ -4,7 +4,6 @@
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Discord;
-using Discord.WebSocket;
using PriconneBotConsoleApp.Database;
using PriconneBotConsoleApp.DataModel;
using PriconneBotConsoleApp.DataType;
@@ -15,10 +14,7 @@ namespace PriconneBotConsoleApp.Script
{
public class BattleReport
{
- private readonly ClanData m_ClanData;
- private readonly SocketUserMessage m_UserMessage;
- private readonly SocketRole m_ClanRole;
- private readonly SocketGuild m_Guild;
+ private readonly CommandEventArgs m_CommandEventArgs;
private class PlayerInfo
{
@@ -48,71 +44,55 @@ public string GetNameWithReport()
}
}
- public BattleReport(ClanData clanData, SocketUserMessage userMessage)
- {
- m_ClanData = clanData;
- m_UserMessage = userMessage;
- m_Guild = (userMessage.Channel as SocketTextChannel)?.Guild;
- m_ClanRole = m_Guild?.GetRole(clanData.ClanRoleID);
- }
+ public BattleReport(CommandEventArgs commandEventArgs)
+ => m_CommandEventArgs = commandEventArgs;
- public async Task RunByMessage()
+ ///
+ /// 個人の凸報告
+ ///
+ public void RegisterReportData()
{
- if (m_UserMessage.Content.StartsWith("!"))
+ var reportData = new ReportData();
+
+ // TODO : 冗長なRegexの高速化 #131
+ if (Regex.IsMatch(m_CommandEventArgs.Name, @"\d\D{1,3}"))
{
- if (m_UserMessage.Content.StartsWith("!add"))
- {
- RegisterOtherUserReportData();
- }
- else if (m_UserMessage.Content.StartsWith("!list"))
- {
- await SendClanAttackList();
- }
- else if (m_UserMessage.Content.StartsWith("!rm"))
- {
- DeleteReportData();
- }
- else if (m_UserMessage.Content.StartsWith("!init"))
+ var bossNumber = int.Parse(Regex.Match(m_CommandEventArgs.Name, @"\d").Value);
+
+ if (!EnumMapper.TryParse(Regex.Match(m_CommandEventArgs.Name, @"\D{1,3}").Value, out var attackType)
+ || attackType == AttackType.Unknown
+ || attackType == AttackType.CarryOver)
{
- DeleteAllClanReport();
+ return;
}
- }
- else
- {
- RegisterReportData();
- }
- }
- ///
- /// 個人の凸報告
- ///
- private void RegisterReportData()
- {
- var playerData = DatabasePlayerDataController.LoadPlayerData(m_ClanRole, m_UserMessage.Author.Id);
+ reportData.AttackType = (byte)attackType;
+ reportData.BossNumber = (byte)bossNumber;
+ }
- if (playerData == null)
+ if (!CommonDefine.IsValidBossNumber(reportData.BossNumber))
{
return;
}
- var reportData = StringToReportData(m_UserMessage.Content.ZenToHan(), playerData.PlayerID);
+ reportData.PlayerID = m_CommandEventArgs.PlayerData.PlayerID;
if (reportData == null)
{
return;
}
- var userReportedData = DatabaseReportDataController.GetReportData(playerData);
+ var userReportedData = DatabaseReportDataController.GetReportData(m_CommandEventArgs.PlayerData);
if (userReportedData.Count() >= CommonDefine.MaxReportNumber)
{
- _ = m_UserMessage.Channel.SendTimedMessageAsync(TimeDefine.ErrorMessageDisplayTime, ErrorType.UpperLimitReport.ToLabel());
+ _ = m_CommandEventArgs.SocketUserMessage.Channel.SendTimedMessageAsync(TimeDefine.ErrorMessageDisplayTime, ErrorType.UpperLimitReport.ToLabel());
return;
}
if (DatabaseReportDataController.CreateReportData(reportData))
{
- _ = m_UserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
+ _ = m_CommandEventArgs.SocketUserMessage.AddReactionAsync(ReactionType.Success.ToEmoji());
}
return;
@@ -121,18 +101,18 @@ private void RegisterReportData()
///
/// 個人の最新の凸報告を削除する。
///
- private void DeleteReportData()
+ public void DeleteReportData()
{
- var splitContent = m_UserMessage.Content.ZenToHan().Split(" ", StringSplitOptions.RemoveEmptyEntries);
var playerData = new PlayerData();
- if (splitContent.Length == 2
- && ulong.TryParse(Regex.Match(splitContent[1], @"\d+").Value, out ulong registerUserID))
+
+ if (m_CommandEventArgs.Arguments.Count == 1
+ && ulong.TryParse(Regex.Match(m_CommandEventArgs.Arguments[0], @"\d+").Value, out ulong registerUserID))
{
- playerData = DatabasePlayerDataController.LoadPlayerData(m_ClanRole, registerUserID);
+ playerData = DatabasePlayerDataController.LoadPlayerData(m_CommandEventArgs.Role, registerUserID);
}
else
{
- playerData = DatabasePlayerDataController.LoadPlayerData(m_ClanRole, m_UserMessage.Author.Id);
+ playerData = m_CommandEventArgs.PlayerData;
}
if (playerData == null)
@@ -140,18 +120,17 @@ private void DeleteReportData()
return;
}
- var recentReportData = DatabaseReportDataController.GetReportData(playerData)
- .OrderBy(x => x.DateTime).ToList();
- var removeData = recentReportData.Last();
+ var removeData = DatabaseReportDataController.GetReportData(playerData)
+ .MaxBy(x => x.DateTime);
if (DatabaseReportDataController.DeleteReportData(removeData))
{
- _ = m_UserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
+ _ = m_CommandEventArgs.SocketUserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
- if (playerData.UserID != m_UserMessage.Author.Id)
+ if (playerData.UserID != m_CommandEventArgs.User.Id)
{
- _ = m_UserMessage.Channel.SendTimedMessageAsync(TimeDefine.SuccessMessageDisplayTime,
- string.Format(InfomationType.DeleteInsted.ToLabel(), playerData.UserID, TimeDefine.SuccessMessageDisplayTime));
+ _ = m_CommandEventArgs.SocketUserMessage.Channel.SendTimedMessageAsync(TimeDefine.SuccessMessageDisplayTime,
+ string.Format(InformationType.DeleteInstead.ToLabel(), playerData.UserID, TimeDefine.SuccessMessageDisplayTime));
}
}
}
@@ -159,60 +138,57 @@ private void DeleteReportData()
///
/// 代理報告用
///
- private void RegisterOtherUserReportData()
+ public void RegisterOtherUserReportData()
{
- var splitContent = m_UserMessage.Content.ZenToHan().Split(" ", StringSplitOptions.RemoveEmptyEntries);
-
- if (splitContent.Length != CommonDefine.MaxReportNumber)
+ if ((!ulong.TryParse(m_CommandEventArgs.Arguments[0], out var registerUserID)
+ && !MentionUtils.TryParseUser(m_CommandEventArgs.Arguments[0], out registerUserID))
+ || !byte.TryParse(m_CommandEventArgs.Arguments[1], out var bossNumber)
+ || !CommonDefine.IsValidBossNumber(bossNumber)
+ || !EnumMapper.TryParse(m_CommandEventArgs.Arguments[2], out var attackType))
{
return;
}
- if (!ulong.TryParse(Regex.Match(splitContent[1], @"\d+").Value, out ulong registerUserID))
- {
- return;
- }
-
- var registerPlayerData = DatabasePlayerDataController.LoadPlayerData(m_ClanRole, registerUserID);
+ var registerPlayerData = DatabasePlayerDataController.LoadPlayerData(m_CommandEventArgs.Role, registerUserID);
if (registerPlayerData == null)
{
return;
}
- var reportData = StringToReportData(splitContent[2], registerPlayerData.PlayerID);
-
- if (reportData == null)
+ var reportData = new ReportData
{
- return;
- }
+ AttackType = (byte)attackType,
+ BossNumber = bossNumber,
+ PlayerID = registerUserID,
+ };
var userReportedData = DatabaseReportDataController.GetReportData(registerPlayerData);
if (userReportedData.Count() >= CommonDefine.MaxReportNumber)
{
- _ = m_UserMessage.Channel.SendTimedMessageAsync(TimeDefine.ErrorMessageDisplayTime, ErrorType.UpperLimitReport.ToLabel());
+ _ = m_CommandEventArgs.Channel.SendTimedMessageAsync(TimeDefine.ErrorMessageDisplayTime, ErrorType.UpperLimitReport.ToLabel());
return;
}
if (DatabaseReportDataController.CreateReportData(reportData))
{
- _ = m_UserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
+ _ = m_CommandEventArgs.SocketUserMessage.AddReactionAsync(EnumMapper.ToEmoji(ReactionType.Success));
}
return;
-
}
///
/// クランの凸報告を削除
///
- private void DeleteAllClanReport()
+ public void DeleteAllClanReport()
{
- var clanReportData = DatabaseReportDataController.GetReportData(m_ClanData);
+ var clanReportData = DatabaseReportDataController.GetReportData(m_CommandEventArgs.ClanData);
+
if (DatabaseReportDataController.DeleteReportData(clanReportData))
{
- _ = m_UserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
+ _ = m_CommandEventArgs.SocketUserMessage.AddReactionAsync(EnumMapper.ToEmoji(ReactionType.Success));
}
}
@@ -220,43 +196,10 @@ private void DeleteAllClanReport()
/// 凸報告データ送信用
///
///
- private async Task SendClanAttackList()
+ public async Task SendClanAttackList()
{
var clanAttackEmbed = CreateClanReportData();
- await m_UserMessage.Channel.SendMessageAsync(embed: clanAttackEmbed);
- }
-
- ///
- /// メッセージ情報から報告データに変換する。
- ///
- /// メッセージ内容
- ///
- private ReportData StringToReportData(string messageContent, ulong playerID)
- {
- var userReportData = new ReportData();
-
- if (Regex.IsMatch(messageContent, @"\d\D{1,3}"))
- {
- var bossNumber = int.Parse(Regex.Match(messageContent, @"\d").Value);
-
- if (!EnumMapper.TryParse(Regex.Match(messageContent, @"\D{1,3}").Value, out var attackType)
- || attackType == AttackType.Unknown || attackType == AttackType.CarryOver)
- {
- return null;
- }
-
- userReportData.AttackType = (byte)attackType;
- userReportData.BossNumber = (byte)bossNumber;
- }
-
- if (userReportData.BossNumber < CommonDefine.MinBossNumber || userReportData.BossNumber > CommonDefine.MaxBossNumber)
- {
- return null;
- }
-
- userReportData.PlayerID = playerID;
-
- return userReportData;
+ await m_CommandEventArgs.SocketUserMessage.Channel.SendMessageAsync(embed: clanAttackEmbed);
}
///
@@ -267,8 +210,8 @@ private Embed CreateClanReportData()
{
var embedBuilder = new EmbedBuilder();
- var clanPlayerDataList = DatabasePlayerDataController.LoadPlayerData(m_ClanData);
- var reportDataList = DatabaseReportDataController.GetReportData(m_ClanData);
+ var clanPlayerDataList = DatabasePlayerDataController.LoadPlayerData(m_CommandEventArgs.ClanData);
+ var reportDataList = DatabaseReportDataController.GetReportData(m_CommandEventArgs.ClanData);
var playerInfoList = clanPlayerDataList.Select(x => new PlayerInfo(
x.PlayerID,
diff --git a/Script/ClanBattle/BattleReservation.cs b/Script/ClanBattle/BattleReservation.cs
index 32bbaf87..38fc4a27 100644
--- a/Script/ClanBattle/BattleReservation.cs
+++ b/Script/ClanBattle/BattleReservation.cs
@@ -1,17 +1,11 @@
using System;
using System.Linq;
using System.Text;
-using System.Threading.Tasks;
-using System.Reflection;
-using System.ComponentModel;
-using Discord;
-using Discord.WebSocket;
+using PriconneBotConsoleApp.Database;
using PriconneBotConsoleApp.DataModel;
using PriconneBotConsoleApp.DataType;
-using PriconneBotConsoleApp.Database;
-using PriconneBotConsoleApp.Extension;
-using System.Collections.Generic;
using PriconneBotConsoleApp.Define;
+using PriconneBotConsoleApp.Extension;
namespace PriconneBotConsoleApp.Script
{
@@ -19,232 +13,87 @@ public class BattleReservation
{
private const int MaxCommentLength = 30;
- private readonly ClanData m_UserClanData;
- private readonly SocketRole m_UserRole;
- private readonly SocketUserMessage m_UserMessage;
- private readonly SocketInteraction m_UserInteraction;
+ private readonly CommandEventArgs m_CommandEventArgs;
- private BattleReservation(
- ClanData userClanData,
- ISocketMessageChannel channel,
- SocketUserMessage userMessage = null,
- SocketInteraction userInterction = null)
- {
- m_UserClanData = userClanData;
- m_UserRole = (channel as SocketGuildChannel)?.Guild.GetRole(m_UserClanData.ClanRoleID);
- m_UserMessage = userMessage;
- m_UserInteraction = userInterction;
- }
-
- public BattleReservation(ClanData userClanData, SocketUserMessage message)
- : this(userClanData, message.Channel, userMessage: message)
- {
- }
+ public BattleReservation(CommandEventArgs commandEventArgs)
+ => m_CommandEventArgs = commandEventArgs;
- public BattleReservation(ClanData userClanData, SocketInteraction interaction)
- : this(userClanData, interaction.Channel, userInterction: interaction)
- {
- }
-
- public BattleReservation(SocketRole userRole)
- {
- m_UserRole = userRole;
- m_UserClanData = DatabaseClanDataController.LoadClanData(userRole);
- }
+ ///
+ /// 個人の予約一覧を表示する。引数は無し。
+ ///
+ public void PlayerReserveList()
+ => m_CommandEventArgs.Channel.SendMessageAsync(CreateUserReservationDataMessage(m_CommandEventArgs.PlayerData));
- public async Task RunReservationCommand()
+ public void RegisterReserveData()
{
- var userMessage = m_UserMessage;
-
- if (userMessage == null)
+ if (!IsReservationAllowTime())
{
- return;
- }
-
- var messageContents = userMessage.Content;
-
- if (messageContents.StartsWith("予約"))
- {
- switch (messageContents)
- {
- case "予約":
- case "予約確認":
- case "予約状況":
- Console.WriteLine("予約確認");
- await userMessage.Channel.SendMessageAsync(CreateUserReservationDataMessage());
- return;
- }
-
- if (!IsReservationAllowTime())
- {
- await SendErrorMessage(ErrorType.OutOfReservationTime,
- $"{m_UserClanData.ReservationStartTime.Hours}:00", $"{m_UserClanData.ReservationEndTime.Hours}:00");
- return;
- }
-
- var reservationData = MessageToReservationData();
-
- if (reservationData is null)
- {
- await SendErrorMessage(ErrorType.FailedReservation);
- return;
- }
-
- var allowReservationLap = m_UserClanData.ReservationLap == 0
- ? ClanBattleDefine.MaxLapNumber : (m_UserClanData.ReservationLap + m_UserClanData.GetMinBossLap());
-
- if (reservationData.BattleLap > allowReservationLap)
- {
- await SendErrorMessage(ErrorType.OutOfReservationBossLaps, allowReservationLap.ToString());
- return;
- }
-
- RegisterReservationData(reservationData);
- await SuccessAddEmoji();
- await UpdateSystemMessage();
+ _ = m_CommandEventArgs.Channel.SendTimedMessageAsync(
+ TimeDefine.ErrorMessageDisplayTime,
+ string.Format(ErrorType.OutOfReservationTime.ToLabel(),
+ $"{m_CommandEventArgs.ClanData.ReservationStartTime.Hours}",
+ $"{m_CommandEventArgs.ClanData.ReservationEndTime.Hours}"
+ )
+ );
- if (m_UserClanData.GetBossLap(reservationData.BossNumber) == reservationData.BattleLap)
- {
- await new BattleDeclaration(m_UserRole, (BossNumberType)reservationData.BossNumber).UpdateDeclarationBotMessage();
- }
+ return;
}
- else if (messageContents.StartsWith("削除"))
- {
- var deleteReservationData = MessageToReservationData();
- if (deleteReservationData is null)
- {
- // await FailedToRegisterMessage();
- return;
- }
+ var reservationData = MessageToReservationData();
- if (DeleteUserReservationData(deleteReservationData))
- {
- await SuccessAddEmoji();
- await UpdateSystemMessage();
- }
- }
- else if (messageContents.StartsWith("!rm"))
+ if (reservationData is null)
{
- var userReservationData = MessageToUserReservationData();
-
- if (userReservationData == null || !DeleteUserReservationData(userReservationData))
- {
- return;
- }
+ _ = m_CommandEventArgs.Channel.SendTimedMessageAsync(
+ TimeDefine.ErrorMessageDisplayTime,
+ ErrorType.FailedReservation.ToLabel()
+ );
- await SuccessAddEmoji();
- await UpdateSystemMessage();
-
- if (m_UserClanData.GetBossLap(userReservationData.BossNumber) == userReservationData.BattleLap)
- {
- await new BattleDeclaration(m_UserRole, (BossNumberType)userReservationData.BossNumber).UpdateDeclarationBotMessage();
- }
+ return;
}
- }
+ var allowReservationLap = m_CommandEventArgs.ClanData.ReservationLap == 0
+ ? ClanBattleDefine.MaxLapNumber
+ : (m_CommandEventArgs.ClanData.ReservationLap + m_CommandEventArgs.ClanData.GetMinBossLap());
- public async Task RunReservationResultCommand()
- {
- if (m_UserMessage.Content.StartsWith("!start"))
+ if (reservationData.BattleLap > allowReservationLap)
{
- await SendSystemMessage();
- }
- }
+ _ = m_CommandEventArgs.Channel.SendTimedMessageAsync(
+ TimeDefine.ErrorMessageDisplayTime,
+ string.Format(ErrorType.OutOfReservationBossLaps.ToLabel(), allowReservationLap.ToString())
+ );
- public async Task RunResultInteraction()
- {
- if (m_UserInteraction == null)
- {
return;
}
- var messageComponent = (SocketMessageComponent)m_UserInteraction;
+ RegisterReservationData(reservationData);
+ _ = m_CommandEventArgs.SocketUserMessage.AddReactionAsync(ReactionType.Success.ToEmoji());
+ _ = new BattleReservationSummary(m_CommandEventArgs.Role, m_CommandEventArgs.ClanData).UpdateMessage();
- if (!Enum.TryParse(messageComponent.Data.CustomId, out var buttonType))
+ if (m_CommandEventArgs.ClanData.GetBossLap(reservationData.BossNumber) == reservationData.BattleLap)
{
- return;
- }
-
- switch (buttonType)
- {
- case ButtonType.Reload:
- await UpdateSystemMessage();
- break;
+ _ = new BattleDeclaration(m_CommandEventArgs.Role, (BossNumberType)reservationData.BossNumber).UpdateDeclarationBotMessage();
}
}
- ///
- /// 凸予約一覧チャンネルにメッセージを送信する。
- ///
- ///
- public async Task SendSystemMessage()
+ public void DeleteReserveData()
{
- var embedData = CreateAllReservationDataMessage();
- var componentData = CreateSystemMessageComponent();
- var reservationResultChannelID = m_UserClanData.ChannelData
- .GetChannelID(m_UserClanData.ClanID, ChannelFeatureType.ReserveResultID);
+ var deleteReservationData = MessageToReservationData();
- if (reservationResultChannelID == 0)
+ if (deleteReservationData == null)
{
return;
}
- var resultChannel = m_UserRole.Guild
- .GetTextChannel(reservationResultChannelID);
-
- var sendedMessageData = await resultChannel.SendMessageAsync(embed: embedData, component: componentData);
- DatabaseMessageDataController.UpdateMessageID(m_UserClanData, sendedMessageData.Id, MessageFeatureType.ReserveResultID);
- }
-
- public async Task UpdateSystemMessage()
- {
- var reservationMessageID = m_UserClanData.MessageData
- .GetMessageID(m_UserClanData.ClanID, MessageFeatureType.ReserveResultID);
- var reservationResultChannelID = m_UserClanData.ChannelData
- .GetChannelID(m_UserClanData.ClanID, ChannelFeatureType.ReserveResultID);
-
- if (reservationResultChannelID == 0 || reservationMessageID == 0)
+ if (DeleteUserReservationData(deleteReservationData))
{
- return;
- }
+ _ = m_CommandEventArgs.SocketUserMessage.AddReactionAsync(ReactionType.Success.ToEmoji());
+ _ = new BattleReservationSummary(m_CommandEventArgs.Role, m_CommandEventArgs.ClanData).UpdateMessage();
- var guildChannel = m_UserRole.Guild
- .GetChannel(reservationResultChannelID) as SocketTextChannel;
- var socketMessage = guildChannel.GetCachedMessage(reservationMessageID);
-
- if (socketMessage == null || !(socketMessage is SocketUserMessage))
- {
- var message = await guildChannel.GetMessageAsync(reservationMessageID);
-
- if (message != null)
+ if (m_CommandEventArgs.ClanData.GetBossLap(deleteReservationData.BossNumber) == deleteReservationData.BattleLap)
{
- await guildChannel.DeleteMessageAsync(message);
- await SendSystemMessage();
+ _ = new BattleDeclaration(m_CommandEventArgs.Role, (BossNumberType)deleteReservationData.BossNumber).UpdateDeclarationBotMessage();
}
-
- return;
}
-
- var serverMessage = socketMessage as SocketUserMessage;
- var embedData = CreateAllReservationDataMessage();
- await serverMessage.ModifyAsync(x => x.Embed = embedData);
- }
-
- public void DeleteUnusedData(byte bossNumber)
- {
- var clanReservationData = DatabaseReservationController.LoadReservationData(m_UserClanData, bossNumber);
- var bossLap = m_UserClanData.GetBossLap(bossNumber);
- var deleteData = clanReservationData.Where(x => x.BattleLap < bossLap);
- DatabaseReservationController.DeleteReservationData(deleteData);
- }
-
- private MessageComponent CreateSystemMessageComponent()
- {
- ComponentBuilder componentBuilder = new();
- componentBuilder.WithButton(
- ButtonType.Reload.ToLongLabel(), ButtonType.Reload.ToString(), ButtonStyle.Secondary, ButtonType.Reload.ToEmoji());
- return componentBuilder.Build();
}
///
@@ -255,30 +104,25 @@ private MessageComponent CreateSystemMessageComponent()
///
private ReservationData MessageToReservationData()
{
- var splitMessageContent = m_UserMessage.Content.ZenToHan().Split(' ', StringSplitOptions.RemoveEmptyEntries);
-
- if (splitMessageContent.Length < 3
- || !(byte.TryParse(splitMessageContent[1], out byte battleLap) && battleLap > 0)
- || !(byte.TryParse(splitMessageContent[2], out byte bossNumber) && bossNumber <= CommonDefine.MaxBossNumber && bossNumber >= CommonDefine.MinBossNumber)
- || battleLap < m_UserClanData.GetBossLap(bossNumber))
+ if (!byte.TryParse(m_CommandEventArgs.Arguments[1], out var bossNumber)
+ || !byte.TryParse(m_CommandEventArgs.Arguments[0], out var battleLap)
+ || !CommonDefine.IsValidBossNumber(bossNumber)
+ || !CommonDefine.IsValidBattleTime(battleLap))
{
return null;
}
- var commentData = string.Join(' ', splitMessageContent.Skip(3));
+
+ var commentData = string.Join(' ', m_CommandEventArgs.Arguments.Skip(2));
if (commentData.Length > MaxCommentLength)
{
commentData = commentData.Substring(0, MaxCommentLength);
- m_UserMessage.Channel.SendMessageAsync($"コメントが長いので切り取られました。\n 問題がある場合は予約削除をして再度予約してください。");
+ _ = m_CommandEventArgs.Channel.SendTimedMessageAsync(TimeDefine.WarningMessageDisplayTime, WarningType.TooLongComment.ToLabel());
}
return new ReservationData()
{
- PlayerData = new PlayerData
- {
- ClanData = m_UserClanData,
- UserID = m_UserMessage.Author.Id,
- },
+ PlayerID = m_CommandEventArgs.PlayerData.PlayerID,
BattleLap = battleLap,
BossNumber = bossNumber,
CommentData = commentData,
@@ -287,51 +131,25 @@ private ReservationData MessageToReservationData()
private void RegisterReservationData(ReservationData reservationData)
{
- var allSqlReservationData = DatabaseReservationController.LoadReservationData(reservationData.PlayerData);
+ var allSqlReservationData = DatabaseReservationController.LoadReservationData(m_CommandEventArgs.PlayerData);
- var doesExistReservationData = allSqlReservationData
- .Any(x => x.BossNumber == reservationData.BossNumber && x.BattleLap == reservationData.BattleLap);
+ var DatabaseReservationData = allSqlReservationData
+ .FirstOrDefault(x => x.BossNumber == reservationData.BossNumber && x.BattleLap == reservationData.BattleLap);
- if (!doesExistReservationData)
+ if (DatabaseReservationData == null)
{
DatabaseReservationController.CreateReservationData(reservationData);
}
else
{
+ reservationData.ReserveID = DatabaseReservationData.ReserveID;
DatabaseReservationController.UpdateReservationData(reservationData);
}
}
- ///
- /// 個人が予約しているデータの取得
- ///
- ///
- private ReservationData MessageToUserReservationData()
- {
- var splitMessageContent = m_UserMessage.Content.ZenToHan().Split(' ', StringSplitOptions.RemoveEmptyEntries);
-
- if (splitMessageContent.Length != 4
- || !ulong.TryParse(splitMessageContent[1], out ulong userID)
- || !(byte.TryParse(splitMessageContent[2], out byte battleLap) && battleLap > 0)
- || !(byte.TryParse(splitMessageContent[3], out byte bossNumber) && bossNumber <= CommonDefine.MaxBossNumber && bossNumber >= CommonDefine.MinBossNumber))
- {
- return null;
- }
-
- var playerData = DatabasePlayerDataController.LoadPlayerData(m_UserRole, userID);
-
- if (playerData == null)
- {
- return null;
- }
-
- return DatabaseReservationController.LoadReservationData(playerData)
- .FirstOrDefault(d => d.BattleLap == battleLap && d.BossNumber == bossNumber);
- }
-
private bool DeleteUserReservationData(ReservationData reservationData)
{
- var userReservationDataList = DatabaseReservationController.LoadReservationData(reservationData.PlayerData);
+ var userReservationDataList = DatabaseReservationController.LoadReservationData(m_CommandEventArgs.PlayerData);
var sqlReservationData = userReservationDataList
.Where(x => x.BossNumber == reservationData.BossNumber && x.BattleLap == reservationData.BattleLap)
@@ -347,11 +165,6 @@ private bool DeleteUserReservationData(ReservationData reservationData)
return true;
}
- private string CreateUserReservationDataMessage()
- => CreateUserReservationDataMessage(
- DatabasePlayerDataController.LoadPlayerData(m_UserRole, m_UserMessage.Author.Id)
- );
-
private string CreateUserReservationDataMessage(PlayerData playerData)
{
var reservationDataSet = DatabaseReservationController.LoadReservationData(playerData);
@@ -377,82 +190,19 @@ private string CreateUserReservationDataMessage(PlayerData playerData)
return messageData.ToString();
}
- ///
- /// 予約メッセージを作成する
- ///
- ///
- ///
- private Embed CreateAllReservationDataMessage()
- {
- var reservationDataSet = DatabaseReservationController.LoadReservationData(m_UserClanData);
- List> reservationDataList = new();
-
- for (var i = 0; i < CommonDefine.MaxBossNumber; i++)
- {
- reservationDataList.Add(new List());
- }
-
- reservationDataSet.ForEach(x => reservationDataList[x.BossNumber - 1].Add(x));
- EmbedBuilder embedBuilder = new();
-
- for (var i = 0; i < CommonDefine.MaxBossNumber; i++)
- {
- EmbedFieldBuilder fieldBuilder = new();
-
- if (!reservationDataList[i].Any())
- {
- // 何かの空白代入して空行を生成している。
- fieldBuilder.Value = "\n\u200b";
- }
- else
- {
- StringBuilder messageData = new();
- messageData.AppendLine("```python");
- reservationDataList[i].ForEach(x => messageData.AppendLine($"{x.BattleLap,2}周目 {x.PlayerData.GuildUserName} {x.CommentData}"));
- messageData.AppendLine("```");
- fieldBuilder.Value = messageData.ToString();
- }
-
- fieldBuilder.Name = $"{i + 1}ボス({reservationDataList[i].Count}件)";
- embedBuilder.AddField(fieldBuilder);
- }
-
- embedBuilder.Title = $"現在の予約状況:計{reservationDataSet.Count}件";
-
- return embedBuilder.Build();
- }
-
- private async Task SendErrorMessage(ErrorType type, params string[] parameters)
- {
- var descriptionString = type.GetDescription();
- var sendMessage = string.Empty;
- if (descriptionString == null)
- {
- sendMessage = type.ToString();
- }
- else
- {
- sendMessage = string.Format(descriptionString, parameters);
- }
- await m_UserMessage.Channel.SendMessageAsync(sendMessage);
- }
-
- private async Task SuccessAddEmoji()
- => await m_UserMessage.AddReactionAsync(new Emoji(ReactionType.Success.GetDescription()));
-
///
/// 予約できる時間かどうか判断する。
///
///
private bool IsReservationAllowTime()
{
- if (m_UserClanData == null)
+ if (m_CommandEventArgs.ClanData == null)
{
return false;
}
- var startTime = m_UserClanData.ReservationStartTime;
- var endTime = m_UserClanData.ReservationEndTime;
+ var startTime = m_CommandEventArgs.ClanData.ReservationStartTime;
+ var endTime = m_CommandEventArgs.ClanData.ReservationEndTime;
var nowTime = DateTime.Now.TimeOfDay;
if (startTime.Hours == 0 && endTime.Hours == 0)
diff --git a/Script/ClanBattle/BattleReservationSummary.cs b/Script/ClanBattle/BattleReservationSummary.cs
new file mode 100644
index 00000000..bba2321d
--- /dev/null
+++ b/Script/ClanBattle/BattleReservationSummary.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Discord;
+using Discord.WebSocket;
+using PriconneBotConsoleApp.Database;
+using PriconneBotConsoleApp.DataModel;
+using PriconneBotConsoleApp.DataType;
+using PriconneBotConsoleApp.Define;
+
+namespace PriconneBotConsoleApp.Script
+{
+ public class BattleReservationSummary
+ {
+ private readonly ClanData m_ClanData;
+ private readonly SocketRole m_Role;
+ private readonly SocketTextChannel m_SocketTextChannel;
+
+ public BattleReservationSummary(SocketRole role, ClanData clanData = null)
+ {
+ m_Role = role;
+
+ if (clanData == null)
+ {
+ m_ClanData = DatabaseClanDataController.LoadClanData(m_Role);
+ }
+ else
+ {
+ m_ClanData = clanData;
+ }
+
+ m_SocketTextChannel = m_Role.Guild.GetChannel(m_ClanData.GetChannelID(ChannelFeatureType.ReserveResultID)) as SocketTextChannel;
+ }
+
+ public async Task RunInteraction(SocketMessageComponent messageComponent)
+ {
+ if (!Enum.TryParse(messageComponent.Data.CustomId, out var buttonType))
+ {
+ return;
+ }
+
+ if (buttonType == ButtonType.Reload)
+ {
+ await UpdateMessage();
+ }
+ }
+
+ ///
+ /// 凸予約一覧チャンネルにメッセージを送信する。
+ ///
+ ///
+ public async Task SendMessage()
+ {
+ var embedData = CreateEmbed();
+ var componentData = CreateComponent();
+ var sendedMessageData = await m_SocketTextChannel.SendMessageAsync(embed: embedData, component: componentData);
+ DatabaseMessageDataController.UpdateMessageID(m_ClanData, sendedMessageData.Id, MessageFeatureType.ReserveResultID);
+ }
+
+ public async Task UpdateMessage()
+ {
+ if (m_SocketTextChannel == null)
+ {
+ return;
+ }
+
+ var reservationMessageID = m_ClanData.GetMessageID(MessageFeatureType.ReserveResultID);
+ var cachedMessage = m_SocketTextChannel.GetCachedMessage(reservationMessageID);
+ var embedData = CreateEmbed();
+ var componentData = CreateComponent();
+
+ if (cachedMessage is SocketUserMessage serverMessage)
+ {
+ await serverMessage.ModifyAsync(x => x.Embed = embedData);
+ }
+ else
+ {
+ var message = await m_SocketTextChannel.GetMessageAsync(reservationMessageID);
+ await SendMessage();
+
+ if (message != null)
+ {
+ await m_SocketTextChannel.DeleteMessageAsync(message);
+ }
+ }
+ }
+
+ public void DeleteUnusedData(byte bossNumber)
+ {
+ var clanReservationData = DatabaseReservationController.LoadReservationData(m_ClanData, bossNumber);
+ var bossLap = m_ClanData.GetBossLap(bossNumber);
+ var deleteData = clanReservationData.Where(x => x.BattleLap < bossLap);
+ DatabaseReservationController.DeleteReservationData(deleteData);
+ }
+
+ ///
+ /// 予約メッセージを作成する
+ ///
+ ///
+ ///
+ private Embed CreateEmbed()
+ {
+ var reservationDataSet = DatabaseReservationController.LoadReservationData(m_ClanData);
+ List> reservationDataList = new();
+
+ // TODO : Linqで行けそうな気がする
+ for (var i = 0; i < CommonDefine.MaxBossNumber; i++)
+ {
+ reservationDataList.Add(new List());
+ }
+
+ reservationDataSet.ForEach(x => reservationDataList[x.BossNumber - 1].Add(x));
+ EmbedBuilder embedBuilder = new();
+
+ for (var i = 0; i < CommonDefine.MaxBossNumber; i++)
+ {
+ EmbedFieldBuilder fieldBuilder = new();
+
+ if (!reservationDataList[i].Any())
+ {
+ // 空行を保つためのゼロ幅空白(\u200b)を挿入している。
+ fieldBuilder.Value = "\n\u200b";
+ }
+ else
+ {
+ StringBuilder messageData = new();
+ messageData.AppendLine("```python");
+ reservationDataList[i].ForEach(x => messageData.AppendLine($"{x.BattleLap,2}周目 {x.PlayerData.GuildUserName} {x.CommentData}"));
+ messageData.AppendLine("```");
+ fieldBuilder.Value = messageData.ToString();
+ }
+
+ fieldBuilder.Name = $"{i + 1}ボス({reservationDataList[i].Count}件)";
+ embedBuilder.AddField(fieldBuilder);
+ }
+
+ embedBuilder.Title = $"現在の予約状況:計{reservationDataSet.Count}件";
+
+ return embedBuilder.Build();
+ }
+
+ private MessageComponent CreateComponent()
+ {
+ ComponentBuilder componentBuilder = new();
+ componentBuilder.WithButton(
+ ButtonType.Reload.ToLongLabel(),
+ ButtonType.Reload.ToString(),
+ ButtonStyle.Secondary,
+ ButtonType.Reload.ToEmoji()
+ );
+
+ return componentBuilder.Build();
+ }
+ }
+}
diff --git a/Script/ClanBattle/BattleTaskKill.cs b/Script/ClanBattle/BattleTaskKill.cs
index 1eba12a9..361a6144 100644
--- a/Script/ClanBattle/BattleTaskKill.cs
+++ b/Script/ClanBattle/BattleTaskKill.cs
@@ -153,6 +153,6 @@ private async Task SyncTaskKillRole()
}
private async Task SuccessAddEmoji()
- => await m_UserMessage.AddReactionAsync(new Emoji(ReactionType.Success.ToLabel()));
+ => await m_UserMessage.AddReactionAsync(ReactionType.Success.ToEmoji());
}
}
diff --git a/Script/ClanBattle/UpdateDate.cs b/Script/ClanBattle/UpdateDate.cs
index da5b09ef..190f3dbb 100644
--- a/Script/ClanBattle/UpdateDate.cs
+++ b/Script/ClanBattle/UpdateDate.cs
@@ -55,7 +55,7 @@ public async Task DeleteYesterdayData()
}
taskList.Add(new BattleTaskKill(clanRole).SyncTaskKillData());
- taskList.Add(new BattleReservation(clanRole).UpdateSystemMessage());
+ taskList.Add(new BattleReservationSummary(clanRole).UpdateMessage());
for (int i = 0; i < CommonDefine.MaxBossNumber; i++)
{
diff --git a/Script/Commands.cs b/Script/Commands.cs
new file mode 100644
index 00000000..3f6ac1a4
--- /dev/null
+++ b/Script/Commands.cs
@@ -0,0 +1,348 @@
+using System.Threading.Tasks;
+using PriconneBotConsoleApp.Attribute;
+using PriconneBotConsoleApp.DataModel;
+using PriconneBotConsoleApp.DataType;
+
+namespace PriconneBotConsoleApp.Script
+{
+ public static class Commands
+ {
+ // 持ち越し関連
+ [Command(AttackType.CarryOver, 2, compatibleChannels: ChannelFeatureType.CarryOverID)]
+ public static Task UpdateCarryOverData(CommandEventArgs commandEventArgs)
+ {
+ new BattleCarryOver(commandEventArgs).UpdateCarryOverData();
+ return Task.CompletedTask;
+ }
+
+ [Command("消化", 0, 1, compatibleChannels: ChannelFeatureType.CarryOverID)]
+ public static Task DeleteCarryOverData(CommandEventArgs commandEventArgs)
+ {
+ new BattleCarryOver(commandEventArgs).DeleteCarryOverData();
+ return Task.CompletedTask;
+ }
+
+ [Command("!rm", 0, 2, compatibleChannels: ChannelFeatureType.CarryOverID)]
+ public static Task DeleteOtherPlayerCarryOverData(CommandEventArgs commandEventArgs)
+ {
+ if (commandEventArgs.Arguments.Count == 2)
+ {
+ new BattleCarryOver(commandEventArgs).DeleteOtherPlayerData();
+ }
+ else
+ {
+ new BattleCarryOver(commandEventArgs).DeleteCarryOverData();
+ }
+
+ return Task.CompletedTask;
+ }
+
+ [Command("!list", 0, 0, compatibleChannels: ChannelFeatureType.CarryOverID)]
+ public static async Task DisplayCarryOverList(CommandEventArgs commandEventArgs)
+ {
+ await new BattleCarryOver(commandEventArgs).SendClanCarryOverList();
+ }
+
+ [Command("!init", 0, 0, compatibleChannels: ChannelFeatureType.CarryOverID)]
+ public static Task InitAllCarryOverData(CommandEventArgs commandEventArgs)
+ {
+ new BattleCarryOver(commandEventArgs).InitAllData();
+ return Task.CompletedTask;
+ }
+
+ // 進行関連
+ [Command(
+ AttackType.Physics,
+ 0,
+ 0,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task AttackPhysics(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).UpdateAttackData(AttackType.Physics);
+
+ [Command(
+ AttackType.Magic,
+ 0,
+ 0,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task AttackMagic(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).UpdateAttackData(AttackType.Magic);
+
+ [Command(
+ AttackType.NewYearKaryl,
+ 0,
+ 0,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task AttackNewYearKaryl(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).UpdateAttackData(AttackType.NewYearKaryl);
+
+ [Command(
+ AttackType.CarryOver,
+ 0,
+ 0,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task AttackCarryOver(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).UpdateAttackData(AttackType.CarryOver);
+
+ [Command(
+ new[] { "kari", "仮確定" },
+ 0,
+ 0,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task UpdateProgressStatusReady(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).UpdateStatusData(ProgressStatus.AttackReady);
+
+ [Command(
+ new[] { "atk", "確定" },
+ 0,
+ 0,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task UpdateProgressStatusDone(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).UpdateStatusData(ProgressStatus.AttackDone);
+
+ [Command(
+ new[] { "sos", "jiko", "ziko", "事故" },
+ 0,
+ 0,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task UpdateProgressSOS(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).UpdateStatusData(ProgressStatus.SOS);
+
+ [Command(
+ new[] { "〆確定", "fin" },
+ 0,
+ 0,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task UpdateProgressFin(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).UpdateStatusData(ProgressStatus.SubdueBoss);
+
+ [Command(
+ "!init", 0, 0,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task InitProgressData(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).InitCommand();
+
+ [Command(
+ "!call", 1, 1,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task CallProgress(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).Start();
+
+ [Command(
+ "!list", 0, 0,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task DisplayList(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).SendList();
+
+ [Command(
+ "!rm", 1, 1,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task RemoveProgressData(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).RemoveOrRevertUserData(true);
+
+ [Command(
+ "!rv", 1, 1,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task RevertProgressData(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).RemoveOrRevertUserData();
+
+ [Command(
+ "!next", 0, 0,
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID
+ )]
+ public static async Task NextProgressBoss(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).NextBoss();
+
+ [Command(
+ compatibleChannels: new[]
+ {
+ ChannelFeatureType.ProgressBoss1ID,
+ ChannelFeatureType.ProgressBoss2ID,
+ ChannelFeatureType.ProgressBoss3ID,
+ ChannelFeatureType.ProgressBoss4ID,
+ ChannelFeatureType.ProgressBoss5ID,
+ }
+ )]
+ public static async Task UpdateProgressDamage(CommandEventArgs commandEventArgs)
+ => await new BattleProgress(commandEventArgs).UpdateDamageData();
+
+ [Command("!list", 0, 0, ChannelFeatureType.ReportID)]
+ public static async Task ListReport(CommandEventArgs commandEventArgs)
+ => await new BattleReport(commandEventArgs).SendClanAttackList();
+
+ [Command("!rm", 0, 1, ChannelFeatureType.ReportID)]
+ public static Task RemovePlayerReportData(CommandEventArgs commandEventArgs)
+ {
+ new BattleReport(commandEventArgs).DeleteReportData();
+ return Task.CompletedTask;
+ }
+
+ [Command("!add", 3, 3, ChannelFeatureType.ReportID)]
+ public static Task RegisterOtherPlayerReportData(CommandEventArgs commandEventArgs)
+ {
+ new BattleReport(commandEventArgs).RegisterOtherUserReportData();
+ return Task.CompletedTask;
+ }
+
+ [Command("!init", 0, 0, ChannelFeatureType.ReportID)]
+ public static Task InitReportData(CommandEventArgs commandEventArgs)
+ {
+ new BattleReport(commandEventArgs).DeleteAllClanReport();
+ return Task.CompletedTask;
+ }
+
+ [Command(minArgumentLength: 0, maxArgumentLength: 0, compatibleChannels: ChannelFeatureType.ReportID)]
+ public static Task RegisterReportData(CommandEventArgs commandEventArgs)
+ {
+ new BattleReport(commandEventArgs).RegisterReportData();
+ return Task.CompletedTask;
+ }
+
+ [Command("予約", 0, compatibleChannels: ChannelFeatureType.ReserveID)]
+ public static Task ReservationCommand(CommandEventArgs commandEventArgs)
+ {
+ BattleReservation battleReservation = new(commandEventArgs);
+
+ if (commandEventArgs.Arguments.Count == 0)
+ {
+ battleReservation.PlayerReserveList();
+ }
+ else
+ {
+ battleReservation.RegisterReserveData();
+ }
+
+ return Task.CompletedTask;
+ }
+
+ [Command(new[] { "予約一覧, 予約確認, 予約状況, !list" }, 0, 0, ChannelFeatureType.ReserveID)]
+ public static Task ListReservation(CommandEventArgs commandEventArgs)
+ {
+ new BattleReservation(commandEventArgs).PlayerReserveList();
+ return Task.CompletedTask;
+ }
+
+ [Command(new[] { "削除", "!rm" }, 2, 2, ChannelFeatureType.ReserveID)]
+ public static Task DeleteReserveData(CommandEventArgs commandEventArgs)
+ {
+ new BattleReservation(commandEventArgs).DeleteReserveData();
+ return Task.CompletedTask;
+ }
+
+ [Command("!start", 0, 0, ChannelFeatureType.ReserveResultID)]
+ public static async Task SendReserveSummary(CommandEventArgs commandEventArgs)
+ => await new BattleReservationSummary(commandEventArgs.Role, commandEventArgs.ClanData).SendMessage();
+
+ [Command(compatibleChannels: new[]
+ {
+ ChannelFeatureType.DeclareBoss1ID,
+ ChannelFeatureType.DeclareBoss2ID,
+ ChannelFeatureType.DeclareBoss3ID,
+ ChannelFeatureType.DeclareBoss4ID,
+ ChannelFeatureType.DeclareBoss5ID,
+ })]
+ public static async Task StartDeclare(CommandEventArgs commandEventArgs)
+ {
+ var BossNumber = commandEventArgs.ChannelFeatureType switch
+ {
+ ChannelFeatureType.DeclareBoss1ID => BossNumberType.Boss1Number,
+ ChannelFeatureType.DeclareBoss2ID => BossNumberType.Boss2Number,
+ ChannelFeatureType.DeclareBoss3ID => BossNumberType.Boss3Number,
+ ChannelFeatureType.DeclareBoss4ID => BossNumberType.Boss4Number,
+ ChannelFeatureType.DeclareBoss5ID => BossNumberType.Boss5Number,
+ _ => BossNumberType.Unknown,
+ };
+
+ if (BossNumber == BossNumberType.Unknown)
+ {
+ return;
+ }
+
+ await new BattleDeclaration(commandEventArgs.ClanData, commandEventArgs.SocketUserMessage, BossNumber).RunDeclarationCommandByMessage();
+ }
+
+ [Command(compatibleChannels: ChannelFeatureType.TaskKillID)]
+ public static async Task StartTaskkill(CommandEventArgs commandEventArgs)
+ => await new BattleTaskKill(commandEventArgs.ClanData, commandEventArgs.SocketUserMessage).RunByMessageCommands();
+
+ [Command("!dice", 0, 1)]
+ public static async Task Dice(CommandEventArgs commandEventArgs)
+ => await new Dice(commandEventArgs).Run();
+
+ [Command("!tl", 2, 2)]
+ public static async Task TimeLineConversion(CommandEventArgs commandEventArgs)
+ => await new TimeLineConversion(commandEventArgs).RunByMessage();
+
+ [Command("!today", 0, 0)]
+ public static async Task EventInformation(CommandEventArgs commandEventArgs)
+ => await new PriconneEventViewer(commandEventArgs).SendEventInfomationByMessage();
+ }
+}
diff --git a/Script/Program.cs b/Script/Program.cs
index 2a48a8ab..cb6afe84 100644
--- a/Script/Program.cs
+++ b/Script/Program.cs
@@ -27,6 +27,7 @@ public class Program
public async Task MainAsync()
{
BotConfigManager.SetJsonConfig(ConfigPath);
+ CommandMapper.InitCommandCache();
m_config = new DiscordSocketConfig
{
@@ -59,24 +60,29 @@ public async Task MainAsync()
///
/// メッセージの受信処理
///
- ///
+ ///
///
- private async Task CommandRecieved(SocketMessage messageParam)
+ private async Task CommandRecieved(SocketMessage socketMessage)
{
- if (messageParam is not SocketUserMessage message)
+ if (socketMessage is not SocketUserMessage socketUserMessage)
{
return;
}
- Console.WriteLine($"{message.Channel.Name} {message.Author.Username}:{message}");
+ Console.WriteLine($"{socketUserMessage.Channel.Name} {socketUserMessage.Author.Username}:{socketUserMessage}");
- if (message.Author.IsBot)
+ if (socketUserMessage.Author.IsBot)
{
return;
}
- var receiveMessages = new ReceiveMessageController(message);
- await receiveMessages.RunMessageReceive();
+ try
+ {
+ await CommandMapper.Invoke(new CommandEventArgs(socketUserMessage));
+ }
+ catch
+ {
+ }
}
///
diff --git a/Script/ReceiveInteractionController.cs b/Script/ReceiveInteractionController.cs
index f29da2a2..24f59a64 100644
--- a/Script/ReceiveInteractionController.cs
+++ b/Script/ReceiveInteractionController.cs
@@ -13,6 +13,7 @@ public class ReceiveInteractionController
private readonly SocketTextChannel m_TextChannel;
private readonly PlayerData m_PlayerData;
private readonly ClanData m_ClanData;
+ private readonly SocketRole m_Role;
public ReceiveInteractionController(SocketInteraction interaction)
{
@@ -25,8 +26,8 @@ public ReceiveInteractionController(SocketInteraction interaction)
return;
}
- var playerRole = m_TextChannel.Guild.GetRole(m_PlayerData.ClanData.ClanRoleID);
- m_ClanData = DatabaseClanDataController.LoadClanData(playerRole);
+ m_Role = m_TextChannel.Guild.GetRole(m_PlayerData.ClanData.ClanRoleID);
+ m_ClanData = DatabaseClanDataController.LoadClanData(m_Role);
}
public async Task Run()
@@ -40,9 +41,10 @@ public async Task Run()
.FirstOrDefault(x => x.ChannelID == m_TextChannel.Id)
?.FeatureID ?? 0;
- if (channelFeatureID == (int)ChannelFeatureType.ReserveResultID)
+ if (channelFeatureID == (int)ChannelFeatureType.ReserveResultID
+ && m_Interaction is SocketMessageComponent socketMessageComponent)
{
- await new BattleReservation(m_ClanData, m_Interaction).RunResultInteraction();
+ await new BattleReservationSummary(m_Role, m_ClanData).RunInteraction(socketMessageComponent);
}
BattleDeclaration battleDeclaration = channelFeatureID switch
diff --git a/Script/ReceiveMessageController.cs b/Script/ReceiveMessageController.cs
deleted file mode 100644
index 016bffaa..00000000
--- a/Script/ReceiveMessageController.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-using System.Threading.Tasks;
-using Discord.WebSocket;
-using PriconneBotConsoleApp.DataModel;
-using PriconneBotConsoleApp.Database;
-using System.Linq;
-using PriconneBotConsoleApp.DataType;
-using PriconneBotConsoleApp.Extension;
-
-namespace PriconneBotConsoleApp.Script
-{
- public class ReceiveMessageController
- {
- private readonly ClanData m_PlayerClanData;
- private readonly PlayerData m_PlayerData;
- private readonly SocketUserMessage m_ReceiveMessage;
-
- public ReceiveMessageController(SocketUserMessage message)
- {
- m_ReceiveMessage = message;
- var messageChannel = message.Channel as SocketGuildChannel;
- var guildID = messageChannel.Guild.Id;
- var userID = message.Author.Id;
- m_PlayerData = DatabasePlayerDataController.LoadPlayerData(guildID, userID);
-
- if (m_PlayerData == null)
- {
- return;
- }
-
- var userRole = messageChannel.Guild.GetRole(m_PlayerData.ClanData.ClanRoleID);
-
- if (userRole == null)
- {
- return;
- }
-
- m_PlayerClanData = DatabaseClanDataController.LoadClanData(userRole);
- }
-
- public async Task RunMessageReceive()
- {
- if (m_ReceiveMessage != null)
- {
- await RunMessageReceive(m_ReceiveMessage);
- }
- }
-
- public async Task RunMessageReceive(SocketUserMessage message)
- {
- await new TimeLineConversion(message).RunByMessage();
- await new PriconneEventViewer(message).SendEventInfomationByMessage();
- await new Dice(message).Run();
-
- if (m_PlayerData == null || m_PlayerClanData == null)
- {
- return;
- }
-
- var messageChannelID = message.Channel.Id;
- var featureID = m_PlayerClanData.ChannelData.FirstOrDefault(x => x.ChannelID == messageChannelID)?.FeatureID ?? 0;
-
- if (messageChannelID == m_PlayerClanData.ChannelData.GetChannelID(m_PlayerClanData.ClanID, ChannelFeatureType.ReserveID))
- {
- await new BattleReservation(m_PlayerClanData, message).RunReservationCommand();
- }
-
- if (messageChannelID == m_PlayerClanData.ChannelData.GetChannelID(m_PlayerClanData.ClanID, ChannelFeatureType.ReserveResultID))
- {
- await new BattleReservation(m_PlayerClanData, message).RunReservationResultCommand();
- }
-
- if (messageChannelID == m_PlayerClanData.ChannelData.GetChannelID(m_PlayerClanData.ClanID, ChannelFeatureType.TaskKillID))
- {
- await new BattleTaskKill(m_PlayerClanData, message).RunByMessageCommands();
- }
-
- if (messageChannelID == m_PlayerClanData.ChannelData.GetChannelID(m_PlayerClanData.ClanID, ChannelFeatureType.ReportID))
- {
- await new BattleReport(m_PlayerClanData, message).RunByMessage();
- }
-
- if (messageChannelID == m_PlayerClanData.ChannelData.GetChannelID(m_PlayerClanData.ClanID, ChannelFeatureType.CarryOverID))
- {
- await new BattleCarryOver(m_PlayerClanData, message).RunByMessage();
- }
-
- BattleDeclaration battleDeclaration = featureID switch
- {
- (int)ChannelFeatureType.DeclareBoss1ID => new(m_PlayerClanData, message, BossNumberType.Boss1Number),
- (int)ChannelFeatureType.DeclareBoss2ID => new(m_PlayerClanData, message, BossNumberType.Boss2Number),
- (int)ChannelFeatureType.DeclareBoss3ID => new(m_PlayerClanData, message, BossNumberType.Boss3Number),
- (int)ChannelFeatureType.DeclareBoss4ID => new(m_PlayerClanData, message, BossNumberType.Boss4Number),
- (int)ChannelFeatureType.DeclareBoss5ID => new(m_PlayerClanData, message, BossNumberType.Boss5Number),
- _ => null,
- };
-
- if (battleDeclaration != null)
- {
- await battleDeclaration.RunDeclarationCommandByMessage();
- }
-
- BattleProgress battleProgress = featureID switch
- {
- (uint)ChannelFeatureType.ProgressBoss1ID => new(m_PlayerClanData, message, (byte)BossNumberType.Boss1Number),
- (uint)ChannelFeatureType.ProgressBoss2ID => new(m_PlayerClanData, message, (byte)BossNumberType.Boss2Number),
- (uint)ChannelFeatureType.ProgressBoss3ID => new(m_PlayerClanData, message, (byte)BossNumberType.Boss3Number),
- (uint)ChannelFeatureType.ProgressBoss4ID => new(m_PlayerClanData, message, (byte)BossNumberType.Boss4Number),
- (uint)ChannelFeatureType.ProgressBoss5ID => new(m_PlayerClanData, message, (byte)BossNumberType.Boss5Number),
- _ => null,
- };
-
- if (battleProgress != null)
- {
- await battleProgress.RunByMessage();
- }
- }
- }
-}
diff --git a/Script/Utility/CommandMapper.cs b/Script/Utility/CommandMapper.cs
new file mode 100644
index 00000000..a1500ec4
--- /dev/null
+++ b/Script/Utility/CommandMapper.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using PriconneBotConsoleApp.Attribute;
+using PriconneBotConsoleApp.DataModel;
+using PriconneBotConsoleApp.DataType;
+using PriconneBotConsoleApp.Extension;
+
+namespace PriconneBotConsoleApp.Script
+{
+ public static class CommandMapper
+ {
+ /// コマンドキャッシュのキーの型
+ /// 対応するチャンネル
+ /// 対応するコマンド名
+ private record CacheKey(ChannelFeatureType ChannelFeature, string Name);
+
+ /// コマンドキャッシュの要素
+ private class CacheValue
+ {
+ internal CacheValue(MethodInfo methodInfo)
+ {
+ Info = methodInfo.GetCustomAttribute(false);
+
+ if (Info != null)
+ {
+ IsValid = true;
+ Handler = (Func)Delegate.CreateDelegate(typeof(Func), methodInfo);
+ }
+ }
+
+ /// 対象のにがつけられているかどうか
+ internal bool IsValid { get; }
+
+ /// 対象のにつけられた
+ internal CommandAttribute Info { get; }
+
+ /// 対象のの実体
+ internal Func Handler { get; }
+ }
+
+ private static ConcurrentDictionary m_CommandCache;
+
+ public static void InitCommandCache()
+ => m_CommandCache = new(
+ typeof(Commands)
+ .GetMethods(BindingFlags.Static | BindingFlags.Public)
+ .Select(methodInfo => new CacheValue(methodInfo))
+ .Where(cacheValue => cacheValue.IsValid)
+ .SelectMany(
+ valueTuple => valueTuple.Info.CompatibleChannels.SelectMany(
+ _ => valueTuple.Info.Names,
+ (channelFeature, name) => new CacheKey(channelFeature, name)
+ ),
+ (valueTuple, keyTuple) => (keyTuple, valueTuple))
+ .ToDictionary(keyValueTuple => keyValueTuple.keyTuple, keyValueTuple => keyValueTuple.valueTuple)
+ );
+
+ public static async Task Invoke(CommandEventArgs commandEventArgs)
+ {
+ if (!m_CommandCache.TryGetValueMany(
+ out var functionData,
+ new(commandEventArgs.ChannelFeatureType, commandEventArgs.Name),
+ new(ChannelFeatureType.All, commandEventArgs.Name),
+ new(commandEventArgs.ChannelFeatureType, string.Empty)))
+ {
+ throw new KeyNotFoundException(commandEventArgs.SocketUserMessage.Content);
+ }
+
+ if (!functionData.Info.IsCompatibleArgumentLength(commandEventArgs.Arguments.Count))
+ {
+ throw new ArgumentException(
+ $"Argument length {commandEventArgs.Arguments.Count} is incompatible; Expect : between {functionData.Info.MinArgumentLength} and {functionData.Info.MaxArgumentLength}\n{commandEventArgs.SocketUserMessage.Content}"
+ );
+ }
+
+ await functionData.Handler(commandEventArgs);
+ }
+ }
+}
diff --git a/Script/Utility/Dice.cs b/Script/Utility/Dice.cs
index c92640d2..6e28c5e5 100644
--- a/Script/Utility/Dice.cs
+++ b/Script/Utility/Dice.cs
@@ -1,38 +1,29 @@
-using Discord.WebSocket;
-using PriconneBotConsoleApp.Define;
-using PriconneBotConsoleApp.Extension;
-using System;
+using System;
using System.Threading.Tasks;
+using PriconneBotConsoleApp.DataModel;
+using PriconneBotConsoleApp.Define;
namespace PriconneBotConsoleApp.Script
{
public class Dice
{
- private SocketMessage m_UserMessage;
+ private CommandEventArgs m_CommandEventArgs;
- public Dice(SocketMessage message)
- {
- m_UserMessage = message;
- }
+ public Dice(CommandEventArgs commandEventArgs)
+ => m_CommandEventArgs = commandEventArgs;
public async Task Run()
{
- var splitMessage = m_UserMessage.Content.ZenToHan().Split(' ', StringSplitOptions.RemoveEmptyEntries);
var diceMax = UtilityDefine.DefaultMaxDiceNumber;
- if (splitMessage.Length == 0 || splitMessage[0] != "!dice")
- {
- return;
- }
-
- if (splitMessage.Length == 2 && int.TryParse(splitMessage[1], out var number))
+ if (m_CommandEventArgs.Arguments.Count == 1 && int.TryParse(m_CommandEventArgs.Arguments[0], out var number))
{
diceMax = number;
}
var diceResult = new Random().Next(UtilityDefine.DefaultMinDiceNumber, diceMax);
var sendMessage = $"{diceResult}";
- await m_UserMessage.Channel.SendMessageAsync(sendMessage);
+ await m_CommandEventArgs.Channel.SendMessageAsync(sendMessage);
}
}
}
diff --git a/Script/Utility/EnumMapper.cs b/Script/Utility/EnumMapper.cs
index 42826580..588b2a58 100644
--- a/Script/Utility/EnumMapper.cs
+++ b/Script/Utility/EnumMapper.cs
@@ -35,10 +35,10 @@ public static string ToLabel(this T data) where T : Enum
};
private static MultiDescriptionData GetMultiDescriptionData(T data) where T : Enum
- => m_MultiDescriptionDictionary.GetValueOrInitialize((typeof(T), data), data.GetMultiDescripion);
+ => m_MultiDescriptionDictionary.GetValueOrInitialize((typeof(T), data), () => data.GetMultiDescription());
private static string ToSingleLabel(this T data) where T : Enum
- => m_SingleDescriptionDictionary.GetValueOrInitialize((typeof(T), data), data.GetDescription);
+ => m_SingleDescriptionDictionary.GetValueOrInitialize((typeof(T), data), () => data.GetDescription());
public static string ToLongLabel(this T data) where T : Enum
=> GetMultiDescriptionData(data).LongDescription;
@@ -46,13 +46,13 @@ public static string ToLongLabel(this T data) where T : Enum
public static string ToShortLabel(this T data) where T : Enum
=> GetMultiDescriptionData(data).ShortDescription;
- private static string[] GetAliases(this T data) where T : Enum
+ private static IReadOnlyList GetAliases(this T data) where T : Enum
=> GetMultiDescriptionData(data).Aliases;
public static Emoji ToEmoji(this ButtonType buttonType)
=> new(buttonType.ToShortLabel());
- public static Emoji emoji(this ReactionType reactionType)
+ public static Emoji ToEmoji(this ReactionType reactionType)
=> new(reactionType.ToLabel());
private static DescriptionType GetDescriptionType() where T : Enum
diff --git a/Script/Utility/PriconneEventViewer.cs b/Script/Utility/PriconneEventViewer.cs
index 1ec68142..18185241 100644
--- a/Script/Utility/PriconneEventViewer.cs
+++ b/Script/Utility/PriconneEventViewer.cs
@@ -4,6 +4,7 @@
using System.Threading.Tasks;
using Discord;
using PriconneBotConsoleApp.Database;
+using PriconneBotConsoleApp.DataModel;
using PriconneBotConsoleApp.DataType;
using PriconneBotConsoleApp.Extension;
@@ -11,21 +12,14 @@ namespace PriconneBotConsoleApp.Script
{
public class PriconneEventViewer
{
- private IMessage m_UserMessage;
- public PriconneEventViewer(IMessage message)
- {
- m_UserMessage = message;
- }
+ private CommandEventArgs m_CommandEventArgs;
+ public PriconneEventViewer(CommandEventArgs commandEventArgs)
+ => m_CommandEventArgs = commandEventArgs;
public async Task SendEventInfomationByMessage()
{
- if (m_UserMessage.Content != "!today")
- {
- return;
- }
-
var eventString = EventString();
- await m_UserMessage.Channel.SendMessageAsync(text: eventString) ;
+ await m_CommandEventArgs.Channel.SendMessageAsync(text: eventString) ;
}
public string EventString()
diff --git a/Script/Utility/TimeLineConversion.cs b/Script/Utility/TimeLineConversion.cs
index 4e0ee822..f70b73c3 100644
--- a/Script/Utility/TimeLineConversion.cs
+++ b/Script/Utility/TimeLineConversion.cs
@@ -1,17 +1,17 @@
using System;
-using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;
+using PriconneBotConsoleApp.DataModel;
using PriconneBotConsoleApp.Define;
namespace PriconneBotConsoleApp.Script
{
public class TimeLineConversion
{
- private IMessage m_userMessage;
+ private CommandEventArgs m_CommandEventArgs;
private class ConvertData
{
@@ -22,19 +22,12 @@ private class ConvertData
public IMessage Message = null;
}
- public TimeLineConversion(IMessage message)
- {
- m_userMessage = message;
- }
+ public TimeLineConversion(CommandEventArgs commandEventArgs)
+ => m_CommandEventArgs = commandEventArgs;
public async Task RunByMessage()
{
- if (m_userMessage == null || !m_userMessage.Content.StartsWith("!tl"))
- {
- return;
- }
-
- var messageData = await LoadTimeLineMessage(m_userMessage);
+ var messageData = await LoadTimeLineMessage();
if (messageData == null)
{
@@ -42,9 +35,7 @@ public async Task RunByMessage()
}
var convertMessage = ConversionMessage(messageData.Message.Content, messageData.Time);
- var userChannelData = m_userMessage.Channel as ISocketMessageChannel;
- await userChannelData.SendMessageAsync(convertMessage);
- return;
+ await m_CommandEventArgs.Channel.SendMessageAsync(convertMessage);
}
///
@@ -53,11 +44,10 @@ public async Task RunByMessage()
///
///
///
- private async Task LoadTimeLineMessage(IMessage message)
+ private async Task LoadTimeLineMessage()
{
- var splitMessageContent = message.Content.Split( new[] { " ", " " }, StringSplitOptions.RemoveEmptyEntries);
-
- if (splitMessageContent.Length != 3 || !int.TryParse(splitMessageContent[2], out int timeData) || timeData < CommonDefine.MinBattleTime || timeData > CommonDefine.MaxBattleTime )
+ if (!int.TryParse(m_CommandEventArgs.Arguments[1], out int timeData)
+ || !CommonDefine.IsValidBattleTime(timeData))
{
return null;
}
@@ -67,10 +57,10 @@ private async Task LoadTimeLineMessage(IMessage message)
Time = timeData,
};
- var uriData = new Uri(splitMessageContent[1]);
+ var uriData = new Uri(m_CommandEventArgs.Arguments[0]);
var discordID = uriData.Segments;
- if (discordID.Count() != 5)
+ if (discordID.Length != 5)
{
return null;
}
@@ -79,8 +69,7 @@ private async Task LoadTimeLineMessage(IMessage message)
convertData.MessageChannelID = discordID[3].Replace("/", "");
convertData.MessageID = discordID[4];
- var userChannelData = message.Channel as SocketGuildChannel;
- var timeLineChannelData = userChannelData.Guild.GetChannel(ulong.Parse(convertData.MessageChannelID)) as SocketTextChannel;
+ var timeLineChannelData = m_CommandEventArgs.Role.Guild.GetChannel(ulong.Parse(convertData.MessageChannelID)) as SocketTextChannel;
convertData.Message = await timeLineChannelData.GetMessageAsync(ulong.Parse(convertData.MessageID));
if (convertData.Message == null)
@@ -157,8 +146,6 @@ private string ConversionMessage(string messageData, int timeData)
{
afterLineMessageContent = afterLineMessageContent.Replace(matchTimeData.Value, $"{afterSeconds:D2}{matchTimeData.Groups[2]}");
}
-
-
}
sendMessageContent.AppendLine(afterLineMessageContent);