服务器插件优化;物品添加魔法技能组,文本优化 (#100)

* 添加了 SQLHelperFactory;完善了物品的描述信息;一些代码风格修改

* 构造的物品默认 1 级;为服务器插件添加控制器;添加邮件发送器的工厂;在物品中添加魔法技能组
This commit is contained in:
milimoe 2024-11-13 09:18:58 +08:00 committed by GitHub
parent 3477b08a6c
commit b25698d91b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 667 additions and 259 deletions

View File

@ -12,7 +12,10 @@ namespace Milimoe.FunGame.Core.Api.OpenEntityAdapter
if (config[key] is Item prev) if (config[key] is Item prev)
{ {
Item next = prev.Copy(); Item next = prev.Copy();
if (next is T t) config[key] = t; if (next is T t)
{
config[key] = t;
}
} }
} }
} }

View File

@ -38,47 +38,47 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
/// <summary> /// <summary>
/// 创建邮件服务 /// 创建邮件服务
/// </summary> /// </summary>
/// <param name="SenderMailAddress"></param> /// <param name="senderMailAddress"></param>
/// <param name="SenderName"></param> /// <param name="senderName"></param>
/// <param name="SenderPassword"></param> /// <param name="senderPassword"></param>
/// <param name="Host"></param> /// <param name="host"></param>
/// <param name="Port"></param> /// <param name="port"></param>
/// <param name="OpenSSL"></param> /// <param name="ssl"></param>
public MailSender(string SenderMailAddress, string SenderName, string SenderPassword, string Host, int Port, bool OpenSSL) public MailSender(string senderMailAddress, string senderName, string senderPassword, string host, int port, bool ssl)
{ {
MailSenderID = Guid.NewGuid(); MailSenderID = Guid.NewGuid();
_SmtpClientInfo = new SmtpClientInfo(SenderMailAddress, SenderName, SenderPassword, Host, Port, OpenSSL); _SmtpClientInfo = new SmtpClientInfo(senderMailAddress, senderName, senderPassword, host, port, ssl);
if (!MailManager.MailSenders.ContainsKey(MailSenderID)) MailManager.MailSenders.Add(MailSenderID, this); if (!MailManager.MailSenders.ContainsKey(MailSenderID)) MailManager.MailSenders.Add(MailSenderID, this);
} }
/// <summary> /// <summary>
/// 创建完整邮件对象 /// 创建完整邮件对象
/// </summary> /// </summary>
/// <param name="Subject"></param> /// <param name="subject"></param>
/// <param name="Body"></param> /// <param name="body"></param>
/// <param name="Priority"></param> /// <param name="priority"></param>
/// <param name="HTML"></param> /// <param name="html"></param>
/// <param name="ToList"></param> /// <param name="toList"></param>
/// <param name="CCList"></param> /// <param name="ccList"></param>
/// <param name="BCCList"></param> /// <param name="bccList"></param>
/// <returns></returns> /// <returns></returns>
public MailObject CreateMail(string Subject, string Body, MailPriority Priority, bool HTML, string[] ToList, string[]? CCList = null, string[]? BCCList = null) public MailObject CreateMail(string subject, string body, MailPriority priority, bool html, string[] toList, string[]? ccList = null, string[]? bccList = null)
{ {
return new MailObject(this, Subject, Body, Priority, HTML, ToList, CCList, BCCList); return new MailObject(this, subject, body, priority, html, toList, ccList, bccList);
} }
/// <summary> /// <summary>
/// 发送邮件 /// 发送邮件
/// </summary> /// </summary>
/// <param name="Mail"></param> /// <param name="mail"></param>
/// <returns></returns> /// <returns></returns>
public MailSendResult Send(MailObject Mail) public MailSendResult Send(MailObject mail)
{ {
_LastestResult = MailManager.Send(this, Mail, out _ErrorMsg); _LastestResult = MailManager.Send(this, mail, out _ErrorMsg);
return _LastestResult; return _LastestResult;
} }
private bool IsDisposed = false; private bool _isDisposed = false;
/// <summary> /// <summary>
/// 关闭邮件服务 /// 关闭邮件服务
@ -92,17 +92,17 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
/// <summary> /// <summary>
/// 关闭邮件服务 /// 关闭邮件服务
/// </summary> /// </summary>
/// <param name="Disposing"></param> /// <param name="disposing"></param>
protected void Dispose(bool Disposing) protected void Dispose(bool disposing)
{ {
if (!IsDisposed) if (!_isDisposed)
{ {
if (Disposing) if (disposing)
{ {
MailManager.Dispose(this); MailManager.Dispose(this);
} }
} }
IsDisposed = true; _isDisposed = true;
} }
} }
} }

View File

@ -8,7 +8,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
/// <summary> /// <summary>
/// 需要在Server中继承此类实现 /// 需要在Server中继承此类实现
/// </summary> /// </summary>
public abstract class SQLHelper : ISQLHelper public abstract class SQLHelper : ISQLHelper, IDisposable
{ {
public abstract FunGameInfo.FunGame FunGameType { get; } public abstract FunGameInfo.FunGame FunGameType { get; }
public abstract SQLMode Mode { get; } public abstract SQLMode Mode { get; }
@ -29,9 +29,9 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
/// <summary> /// <summary>
/// 执行一个指定的命令 /// 执行一个指定的命令
/// </summary> /// </summary>
/// <param name="Script">命令</param> /// <param name="script">命令</param>
/// <returns>影响的行数</returns> /// <returns>影响的行数</returns>
public abstract int Execute(string Script); public abstract int Execute(string script);
/// <summary> /// <summary>
/// 查询DataSet /// 查询DataSet
@ -42,9 +42,9 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
/// <summary> /// <summary>
/// 执行指定的命令查询DataSet /// 执行指定的命令查询DataSet
/// </summary> /// </summary>
/// <param name="Script">命令</param> /// <param name="script">命令</param>
/// <returns>结果集</returns> /// <returns>结果集</returns>
public abstract DataSet ExecuteDataSet(string Script); public abstract DataSet ExecuteDataSet(string script);
/// <summary> /// <summary>
/// 执行指定的命令查询DataRow可选实现 /// 执行指定的命令查询DataRow可选实现
@ -52,16 +52,21 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
/// <returns>结果行</returns> /// <returns>结果行</returns>
public virtual DataRow? ExecuteDataRow() public virtual DataRow? ExecuteDataRow()
{ {
return null; return ExecuteDataRow(Script);
} }
/// <summary> /// <summary>
/// 执行指定的命令查询DataRow可选实现 /// 执行指定的命令查询DataRow可选实现
/// </summary> /// </summary>
/// <param name="Script">命令</param> /// <param name="script">命令</param>
/// <returns>结果行</returns> /// <returns>结果行</returns>
public virtual DataRow? ExecuteDataRow(string Script) public virtual DataRow? ExecuteDataRow(string script)
{ {
DataSet dataSet = ExecuteDataSet(script);
if (dataSet.Tables.Count > 0 && dataSet.Tables[0].Rows.Count > 0)
{
return dataSet.Tables[0].Rows[0];
}
return null; return null;
} }
@ -84,5 +89,10 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
/// 回滚事务 /// 回滚事务
/// </summary> /// </summary>
public abstract void Rollback(); public abstract void Rollback();
/// <summary>
/// 释放资源
/// </summary>
public abstract void Dispose();
} }
} }

View File

@ -1,8 +1,10 @@
using System.Data; using System.Data;
using Milimoe.FunGame.Core.Api.EntityFactory; using Milimoe.FunGame.Core.Api.EntityFactory;
using Milimoe.FunGame.Core.Api.OpenEntityAdapter; using Milimoe.FunGame.Core.Api.OpenEntityAdapter;
using Milimoe.FunGame.Core.Api.Transmittal;
using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Library.Exception;
using Milimoe.FunGame.Core.Library.SQLScript.Entity; using Milimoe.FunGame.Core.Library.SQLScript.Entity;
namespace Milimoe.FunGame.Core.Api.Utility namespace Milimoe.FunGame.Core.Api.Utility
@ -80,78 +82,127 @@ namespace Milimoe.FunGame.Core.Api.Utility
if (typeof(T) == typeof(Character)) if (typeof(T) == typeof(Character))
{ {
foreach (EntityFactoryDelegate<Character> d in CharacterFactories) foreach (EntityFactoryDelegate<Character> d in CharacterFactories)
{
try
{ {
if (d.Invoke(id, name, args) is T character) if (d.Invoke(id, name, args) is T character)
{ {
return character; return character;
} }
} }
catch (Exception e)
{
TXTHelper.AppendErrorLog(e.GetErrorInfo());
}
}
return (T)(object)GetCharacter(); return (T)(object)GetCharacter();
} }
if (typeof(T) == typeof(Inventory)) if (typeof(T) == typeof(Inventory))
{ {
foreach (EntityFactoryDelegate<Inventory> d in InventoryFactories) foreach (EntityFactoryDelegate<Inventory> d in InventoryFactories)
{
try
{ {
if (d.Invoke(id, name, args) is T inventory) if (d.Invoke(id, name, args) is T inventory)
{ {
return inventory; return inventory;
} }
} }
catch (Exception e)
{
TXTHelper.AppendErrorLog(e.GetErrorInfo());
}
}
return (T)(object)GetInventory(); return (T)(object)GetInventory();
} }
if (typeof(T) == typeof(Skill)) if (typeof(T) == typeof(Skill))
{ {
foreach (EntityFactoryDelegate<Skill> d in SkillFactories) foreach (EntityFactoryDelegate<Skill> d in SkillFactories)
{
try
{ {
if (d.Invoke(id, name, args) is T skill) if (d.Invoke(id, name, args) is T skill)
{ {
return skill; return skill;
} }
} }
catch (Exception e)
{
TXTHelper.AppendErrorLog(e.GetErrorInfo());
}
}
return (T)(object)new OpenSkill(id, name, args); return (T)(object)new OpenSkill(id, name, args);
} }
if (typeof(T) == typeof(Effect)) if (typeof(T) == typeof(Effect))
{ {
foreach (EntityFactoryDelegate<Effect> d in EffectFactories) foreach (EntityFactoryDelegate<Effect> d in EffectFactories)
{
try
{ {
if (d.Invoke(id, name, args) is T effect) if (d.Invoke(id, name, args) is T effect)
{ {
return effect; return effect;
} }
} }
catch (Exception e)
{
TXTHelper.AppendErrorLog(e.GetErrorInfo());
}
}
return (T)(object)GetEffect(); return (T)(object)GetEffect();
} }
if (typeof(T) == typeof(Item)) if (typeof(T) == typeof(Item))
{ {
foreach (EntityFactoryDelegate<Item> d in ItemFactories) foreach (EntityFactoryDelegate<Item> d in ItemFactories)
{
try
{ {
if (d.Invoke(id, name, args) is T item) if (d.Invoke(id, name, args) is T item)
{ {
return item; return item;
} }
} }
catch (Exception e)
{
TXTHelper.AppendErrorLog(e.GetErrorInfo());
}
}
return (T)(object)GetItem(); return (T)(object)GetItem();
} }
if (typeof(T) == typeof(Room)) if (typeof(T) == typeof(Room))
{ {
foreach (EntityFactoryDelegate<Room> d in RoomFactories) foreach (EntityFactoryDelegate<Room> d in RoomFactories)
{
try
{ {
if (d.Invoke(id, name, args) is T room) if (d.Invoke(id, name, args) is T room)
{ {
return room; return room;
} }
} }
catch (Exception e)
{
TXTHelper.AppendErrorLog(e.GetErrorInfo());
}
}
return (T)(object)GetRoom(); return (T)(object)GetRoom();
} }
if (typeof(T) == typeof(User)) if (typeof(T) == typeof(User))
{ {
foreach (EntityFactoryDelegate<User> d in UserFactories) foreach (EntityFactoryDelegate<User> d in UserFactories)
{
try
{ {
if (d.Invoke(id, name, args) is T user) if (d.Invoke(id, name, args) is T user)
{ {
return user; return user;
} }
} }
catch (Exception e)
{
TXTHelper.AppendErrorLog(e.GetErrorInfo());
}
}
return (T)(object)GetUser(); return (T)(object)GetUser();
} }
throw new NotSupportedInstanceClassException(); throw new NotSupportedInstanceClassException();
@ -197,6 +248,78 @@ namespace Milimoe.FunGame.Core.Api.Utility
config.SaveConfig(); config.SaveConfig();
} }
internal HashSet<SQLHelperFactoryDelegate> SQLHelperFactories { get; } = [];
public delegate SQLHelper? SQLHelperFactoryDelegate();
/// <summary>
/// 注册工厂方法 [SQLHelper]
/// </summary>
/// <param name="d"></param>
public void RegisterFactory(SQLHelperFactoryDelegate d)
{
SQLHelperFactories.Add(d);
}
/// <summary>
/// 构造一个 SQLHelper 实例
/// </summary>
/// <returns></returns>
public SQLHelper? GetSQLHelper()
{
foreach (SQLHelperFactoryDelegate d in SQLHelperFactories)
{
try
{
if (d.Invoke() is SQLHelper helper)
{
return helper;
}
}
catch (Exception e)
{
TXTHelper.AppendErrorLog(e.GetErrorInfo());
}
}
return null;
}
internal HashSet<MailSenderFactoryDelegate> MailSenderFactories { get; } = [];
public delegate MailSender? MailSenderFactoryDelegate();
/// <summary>
/// 注册工厂方法 [MailSender]
/// </summary>
/// <param name="d"></param>
public void RegisterFactory(MailSenderFactoryDelegate d)
{
MailSenderFactories.Add(d);
}
/// <summary>
/// 构造一个 MailSender 实例
/// </summary>
/// <returns></returns>
public MailSender? GetMailSender()
{
foreach (MailSenderFactoryDelegate d in MailSenderFactories)
{
try
{
if (d.Invoke() is MailSender sender)
{
return sender;
}
}
catch (Exception e)
{
TXTHelper.AppendErrorLog(e.GetErrorInfo());
}
}
return null;
}
private readonly static CharacterFactory CharacterFactory = new(); private readonly static CharacterFactory CharacterFactory = new();
private readonly static InventoryFactory InventoryFactory = new(); private readonly static InventoryFactory InventoryFactory = new();
private readonly static SkillFactory SkillFactory = new(); private readonly static SkillFactory SkillFactory = new();

View File

@ -398,6 +398,27 @@ namespace Milimoe.FunGame.Core.Api.Utility
return $"{month}. {day}, {lastWriteTime.Year} {time}"; return $"{month}. {day}, {lastWriteTime.Year} {time}";
} }
/// <summary>
/// 获取下一次可交易的时间
/// </summary>
/// <returns></returns>
public static DateTime GetTradableTime(DateTime? date = null)
{
date ??= DateTime.Now;
if (date is DateTime d)
{
if (d.Hour < 15)
{
return d.Date.AddDays(1).AddHours(15);
}
else
{
return d.Date.AddDays(2).AddHours(9);
}
}
return DateTime.MinValue;
}
} }
#endregion #endregion

View File

@ -125,7 +125,7 @@ namespace Milimoe.FunGame.Core.Api.Utility
WriteINI("Mailer", "Password", ""); WriteINI("Mailer", "Password", "");
WriteINI("Mailer", "Host", ""); WriteINI("Mailer", "Host", "");
WriteINI("Mailer", "Port", "587"); WriteINI("Mailer", "Port", "587");
WriteINI("Mailer", "OpenSSL", "true"); WriteINI("Mailer", "SSL", "true");
break; break;
} }
} }

View File

@ -105,10 +105,10 @@ namespace Milimoe.FunGame.Core.Controller
/// <param name="delegates"></param> /// <param name="delegates"></param>
public AddonController(IAddon addon, Dictionary<string, object> delegates) : base(addon, delegates) public AddonController(IAddon addon, Dictionary<string, object> delegates) : base(addon, delegates)
{ {
if (delegates.ContainsKey("NewDataRequest")) MaskMethod_NewDataRequest = delegates["NewDataRequest"] != null ? (Func<DataRequestType, DataRequest>)delegates["NewDataRequest"]! : new(DefaultNewDataRequest); if (delegates.TryGetValue("NewDataRequest", out object? value)) MaskMethod_NewDataRequest = value != null ? (Func<DataRequestType, DataRequest>)value : new(DefaultNewDataRequest);
if (delegates.ContainsKey("NewLongRunningDataRequest")) MaskMethod_NewLongRunningDataRequest = delegates["NewLongRunningDataRequest"] != null ? (Func<DataRequestType, DataRequest>)delegates["NewLongRunningDataRequest"]! : new(DefaultNewDataRequest); if (delegates.TryGetValue("NewLongRunningDataRequest", out value)) MaskMethod_NewLongRunningDataRequest = value != null ? (Func<DataRequestType, DataRequest>)value : new(DefaultNewDataRequest);
if (delegates.ContainsKey("NewGamingRequest")) MaskMethod_NewGamingRequest = delegates["NewGamingRequest"] != null ? (Func<GamingType, DataRequest>)delegates["NewGamingRequest"]! : new(DefaultNewDataRequest); if (delegates.TryGetValue("NewGamingRequest", out value)) MaskMethod_NewGamingRequest = value != null ? (Func<GamingType, DataRequest>)value : new(DefaultNewDataRequest);
if (delegates.ContainsKey("NewLongRunningGamingRequest")) MaskMethod_NewLongRunningGamingRequest = delegates["NewLongRunningGamingRequest"] != null ? (Func<GamingType, DataRequest>)delegates["NewLongRunningGamingRequest"]! : new(DefaultNewDataRequest); if (delegates.TryGetValue("NewLongRunningGamingRequest", out value)) MaskMethod_NewLongRunningGamingRequest = value != null ? (Func<GamingType, DataRequest>)value : new(DefaultNewDataRequest);
MaskMethod_NewDataRequest ??= new(DefaultNewDataRequest); MaskMethod_NewDataRequest ??= new(DefaultNewDataRequest);
MaskMethod_NewLongRunningDataRequest ??= new(DefaultNewDataRequest); MaskMethod_NewLongRunningDataRequest ??= new(DefaultNewDataRequest);
MaskMethod_NewGamingRequest ??= new(DefaultNewDataRequest); MaskMethod_NewGamingRequest ??= new(DefaultNewDataRequest);

View File

@ -0,0 +1,111 @@
using Milimoe.FunGame.Core.Api.Transmittal;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Interface.Addons;
using Milimoe.FunGame.Core.Library.SQLScript.Common;
namespace Milimoe.FunGame.Core.Controller
{
/// <summary>
/// 这个控制器在 Base 的基础上添加了 SQLHelper 和 MailSender
/// </summary>
/// <typeparam name="T"></typeparam>
/// <remarks>
/// 新建一个ServerAddonController
/// </remarks>
/// <param name="addon"></param>
/// <param name="delegates"></param>
public class ServerAddonController<T>(IAddon addon, Dictionary<string, object> delegates) : BaseAddonController<T>(addon, delegates), IServerAddon where T : IAddon
{
/// <summary>
/// 数据库连接器
/// </summary>
public SQLHelper? SQLHelper => _sqlHelper;
/// <summary>
/// 邮件发送器
/// </summary>
public MailSender? MailSender => _mailSender;
private SQLHelper? _sqlHelper = null;
private MailSender? _mailSender = null;
private Task? _sqlPolling = null;
private CancellationTokenSource? _cts = null;
/// <summary>
/// 新建 SQLHelper
/// </summary>
public void NewSQLHelper()
{
if (_sqlHelper is null)
{
// 创建持久化 SQLHelper
_sqlHelper = Factory.OpenFactory.GetSQLHelper();
if (_sqlHelper != null)
{
_cts = new();
_sqlPolling = Task.Run(async () =>
{
await Task.Delay(30);
while (true)
{
if (_cts.Token.IsCancellationRequested)
{
break;
}
// 每两小时触发一次SQL服务器的心跳查询防止SQL服务器掉线
try
{
await Task.Delay(2 * 1000 * 3600);
_sqlHelper?.ExecuteDataSet(ServerLoginLogs.Select_GetLastLoginTime());
}
catch (OperationCanceledException)
{
break;
}
catch (Exception e)
{
Error(e);
}
}
}, _cts.Token);
}
}
else
{
WriteLine("已经创建过 SQLHelper 实例。");
}
}
/// <summary>
/// 新建 MailSender
/// </summary>
public void NewMailSender()
{
if (_mailSender is null)
{
_mailSender = Factory.OpenFactory.GetMailSender();
}
else
{
WriteLine("已经创建过 MailSender 实例。");
}
}
/// <summary>
/// 关闭插件的服务
/// </summary>
public async void Close()
{
_mailSender?.Dispose();
_mailSender = null;
_cts?.Cancel();
if (_sqlPolling != null)
{
await _sqlPolling;
_sqlPolling.Dispose();
_sqlPolling = null;
}
_cts?.Dispose();
}
}
}

View File

@ -1,5 +1,4 @@
using System.IO; using System.Text;
using System.Text;
using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Interface.Entity; using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;

View File

@ -48,6 +48,23 @@
} }
} }
/// <summary>
/// 增加所有抗性,传入负数来减少
/// </summary>
/// <param name="value"></param>
public void AddAllValue(double value)
{
None += value;
Particle += value;
Fleabane += value;
Element += value;
Shadow += value;
Bright += value;
PurityContemporary += value;
PurityNatural += value;
Starmark += value;
}
/// <summary> /// <summary>
/// 复制一个魔法抗性对象 /// 复制一个魔法抗性对象
/// </summary> /// </summary>

View File

@ -1,5 +1,4 @@
using System.Net.NetworkInformation; using System.Text;
using System.Text;
using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Interface.Base; using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Interface.Entity; using Milimoe.FunGame.Core.Interface.Entity;
@ -140,6 +139,14 @@ namespace Milimoe.FunGame.Core.Entity
e.Source = _character; e.Source = _character;
} }
} }
foreach (Skill skill in Skills.Magics)
{
skill.Character = _character;
foreach (Effect e in skill.Effects)
{
e.Source = _character;
}
}
} }
} }
@ -153,6 +160,11 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary> /// </summary>
public SkillGroup Skills { get; set; } = new(); public SkillGroup Skills { get; set; } = new();
/// <summary>
/// 其他内容
/// </summary>
public Dictionary<string, object> Others { get; set; } = [];
/// <summary> /// <summary>
/// 当装备物品时 /// 当装备物品时
/// </summary> /// </summary>
@ -175,6 +187,13 @@ namespace Milimoe.FunGame.Core.Entity
} }
} }
} }
foreach (Skill skill in Skills.Magics)
{
if (Character != null && skill.IsMagic && skill.Level > 0)
{
Character.Skills.Add(skill);
}
}
if (Character != null) OnItemEquipped(Character, this, type); if (Character != null) OnItemEquipped(Character, this, type);
} }
@ -185,15 +204,6 @@ namespace Milimoe.FunGame.Core.Entity
{ {
if (Character != null) if (Character != null)
{ {
if (Skills.Active != null)
{
List<Effect> effects = Character.Effects.Where(e => e.Skill == Skills.Active && e.Level > 0).ToList();
foreach (Effect e in effects)
{
Character.Effects.Remove(e);
e.OnEffectLost(Character);
}
}
foreach (Skill skill in Skills.Passives) foreach (Skill skill in Skills.Passives)
{ {
List<Effect> effects = Character.Effects.Where(e => e.Skill == skill && e.Level > 0).ToList(); List<Effect> effects = Character.Effects.Where(e => e.Skill == skill && e.Level > 0).ToList();
@ -203,6 +213,10 @@ namespace Milimoe.FunGame.Core.Entity
e.OnEffectLost(Character); e.OnEffectLost(Character);
} }
} }
foreach (Skill skill in Skills.Magics)
{
Character.Skills.Remove(skill);
}
switch (type) switch (type)
{ {
case EquipSlotType.MagicCardPack: case EquipSlotType.MagicCardPack:
@ -241,6 +255,10 @@ namespace Milimoe.FunGame.Core.Entity
{ {
skill.GamingQueue = queue; skill.GamingQueue = queue;
} }
foreach (Skill skill in Skills.Magics)
{
skill.GamingQueue = queue;
}
} }
/// <summary> /// <summary>
@ -346,19 +364,44 @@ namespace Milimoe.FunGame.Core.Entity
/// 显示物品的详细信息 /// 显示物品的详细信息
/// </summary> /// </summary>
/// <param name="isShowGeneralDescription">是否显示通用描述,而不是描述</param> /// <param name="isShowGeneralDescription">是否显示通用描述,而不是描述</param>
/// <param name="isShowInStore">是否在商店中显示</param>
/// <returns></returns> /// <returns></returns>
public string ToString(bool isShowGeneralDescription) public string ToString(bool isShowGeneralDescription, bool isShowInStore = false)
{ {
StringBuilder builder = new(); StringBuilder builder = new();
builder.AppendLine($"【{Name}】"); builder.AppendLine($"【{Name}】");
builder.AppendLine($"{ItemSet.GetItemTypeName(ItemType) + (ItemType == ItemType.Weapon && WeaponType != WeaponType.None ? "-" + ItemSet.GetWeaponTypeName(WeaponType) : "")}" + (IsPurchasable && Price > 0 ? $" 售价:{Price}" : ""));
string itemquality = ItemSet.GetQualityTypeName(QualityType);
string itemtype = ItemSet.GetItemTypeName(ItemType) + (ItemType == ItemType.Weapon && WeaponType != WeaponType.None ? "-" + ItemSet.GetWeaponTypeName(WeaponType) : "");
if (itemtype != "") itemtype = $" {itemtype}";
builder.AppendLine($"{itemquality + itemtype}");
if (isShowInStore && Price > 0)
{
builder.AppendLine($"售价:{Price} {General.GameplayEquilibriumConstant.InGameCurrency}");
}
if (RemainUseTimes > 0) if (RemainUseTimes > 0)
{ {
builder.AppendLine($"剩余可用次数:{RemainUseTimes}"); builder.AppendLine($"{(isShowInStore ? "" : "")}可用次数:{RemainUseTimes}");
} }
if (isShowInStore)
{
if (IsSellable)
{
builder.AppendLine($"购买此物品后可立即出售");
}
if (IsTradable)
{
DateTime date = DateTimeUtility.GetTradableTime();
builder.AppendLine($"购买此物品后将在 {date.ToString(General.GeneralDateTimeFormatChinese)} 后可交易");
}
}
else
{
List<string> sellandtrade = [""]; List<string> sellandtrade = [""];
if (IsSellable) if (IsSellable)
{ {
@ -368,17 +411,27 @@ namespace Milimoe.FunGame.Core.Entity
{ {
sellandtrade.Add("可交易"); sellandtrade.Add("可交易");
} }
builder.AppendLine(string.Join(" ", sellandtrade).Trim());
if (!IsSellable && NextSellableTime != DateTime.MinValue) if (!IsSellable && NextSellableTime != DateTime.MinValue)
{ {
builder.AppendLine($"此物品将在 {NextSellableTime.ToString(General.GeneralDateTimeFormatChinese)} 后可出售"); builder.AppendLine($"此物品将在 {NextSellableTime.ToString(General.GeneralDateTimeFormatChinese)} 后可出售");
} }
else if (!IsSellable)
{
sellandtrade.Add("不可出售");
}
if (!IsTradable && NextTradableTime != DateTime.MinValue) if (!IsTradable && NextTradableTime != DateTime.MinValue)
{ {
builder.AppendLine($"此物品将在 {NextTradableTime.ToString(General.GeneralDateTimeFormatChinese)} 后可交易"); builder.AppendLine($"此物品将在 {NextTradableTime.ToString(General.GeneralDateTimeFormatChinese)} 后可交易");
} }
else if (!IsTradable)
{
sellandtrade.Add("不可交易");
}
builder.AppendLine(string.Join(" ", sellandtrade).Trim());
}
if (isShowGeneralDescription && GeneralDescription != "") if (isShowGeneralDescription && GeneralDescription != "")
{ {
@ -388,6 +441,12 @@ namespace Milimoe.FunGame.Core.Entity
{ {
builder.AppendLine("物品描述:" + Description); builder.AppendLine("物品描述:" + Description);
} }
if (ItemType == ItemType.MagicCardPack && Skills.Magics.Count > 0)
{
builder.AppendLine("== 魔法卡 ==\r\n" + string.Join("\r\n", Skills.Magics.Select(m => m.ToString().Trim())));
}
builder.AppendLine("== 物品技能 ==");
if (Skills.Active != null) builder.AppendLine($"{Skills.Active.ToString().Trim()}"); if (Skills.Active != null) builder.AppendLine($"{Skills.Active.ToString().Trim()}");
foreach (Skill skill in Skills.Passives) foreach (Skill skill in Skills.Passives)
@ -461,17 +520,24 @@ namespace Milimoe.FunGame.Core.Entity
item.NextTradableTime = NextTradableTime; item.NextTradableTime = NextTradableTime;
item.RemainUseTimes = RemainUseTimes; item.RemainUseTimes = RemainUseTimes;
item.Skills.Active = Skills.Active?.Copy(); item.Skills.Active = Skills.Active?.Copy();
if (item.Skills.Active != null && copyLevel) if (item.Skills.Active != null)
{ {
item.Skills.Active.Level = Skills.Active?.Level ?? 0; item.Skills.Active.Level = copyLevel ? (Skills.Active?.Level ?? 1) : 1;
} }
foreach (Skill skill in Skills.Passives) foreach (Skill skill in Skills.Passives)
{ {
Skill newskill = skill.Copy(); Skill newskill = skill.Copy();
newskill.Item = item; newskill.Item = item;
newskill.Level = copyLevel ? skill.Level : 0; newskill.Level = copyLevel ? skill.Level : 1;
item.Skills.Passives.Add(newskill); item.Skills.Passives.Add(newskill);
} }
foreach (Skill skill in Skills.Magics)
{
Skill newskill = skill.Copy();
newskill.Item = item;
newskill.Level = copyLevel ? skill.Level : 1;
item.Skills.Magics.Add(newskill);
}
return item; return item;
} }
@ -491,6 +557,22 @@ namespace Milimoe.FunGame.Core.Entity
} }
} }
/// <summary>
/// 设置所有魔法的等级
/// </summary>
/// <param name="level"></param>
public void SetMagicsLevel(int level)
{
if (Skills.Active != null)
{
Skills.Active.Level = level;
}
foreach (Skill skill in Skills.Magics)
{
skill.Level = level;
}
}
/// <summary> /// <summary>
/// 所属的角色 /// 所属的角色
/// </summary> /// </summary>

View File

@ -2,6 +2,7 @@
{ {
/// <summary> /// <summary>
/// 物品只有一个主动技能,但是可以有很多个被动技能 /// 物品只有一个主动技能,但是可以有很多个被动技能
/// <para>魔法卡包具有很多个魔法技能</para>
/// </summary> /// </summary>
public class SkillGroup public class SkillGroup
{ {
@ -14,5 +15,10 @@
/// 被动技能组 /// 被动技能组
/// </summary> /// </summary>
public HashSet<Skill> Passives { get; set; } = []; public HashSet<Skill> Passives { get; set; } = [];
/// <summary>
/// 魔法技能组
/// </summary>
public HashSet<Skill> Magics { get; set; } = [];
} }
} }

View File

@ -4,7 +4,7 @@ using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Interface.Addons namespace Milimoe.FunGame.Core.Interface.Addons
{ {
public interface IGameModuleServer : IAddon, IServerAddon, IAddonController<IGameModuleServer>, IGameModuleDepend public interface IGameModuleServer : IAddon, IAddonController<IGameModuleServer>, IGameModuleDepend
{ {
public bool StartServer(string GameModule, Room Room, List<User> Users, IServerModel RoomMasterServerModel, Dictionary<string, IServerModel> ServerModels, params object[] args); public bool StartServer(string GameModule, Room Room, List<User> Users, IServerModel RoomMasterServerModel, Dictionary<string, IServerModel> ServerModels, params object[] args);

View File

@ -1,5 +1,3 @@
using Milimoe.FunGame.Core.Api.Transmittal;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Controller; using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Addons; using Milimoe.FunGame.Core.Interface.Addons;
@ -44,26 +42,25 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// <summary> /// <summary>
/// 包含了一些常用方法的控制器 /// 包含了一些常用方法的控制器
/// </summary> /// </summary>
public BaseAddonController<IGameModuleServer> Controller public ServerAddonController<IGameModuleServer> Controller
{ {
get => _Controller ?? throw new NotImplementedException(); get => _Controller ?? throw new NotImplementedException();
set => _Controller = value; internal set => _Controller = value;
}
/// <summary>
/// base控制器
/// </summary>
BaseAddonController<IGameModuleServer> IAddonController<IGameModuleServer>.Controller
{
get => Controller;
set => _Controller = (ServerAddonController<IGameModuleServer>?)value;
} }
/// <summary> /// <summary>
/// 控制器内部变量 /// 控制器内部变量
/// </summary> /// </summary>
private BaseAddonController<IGameModuleServer>? _Controller; private ServerAddonController<IGameModuleServer>? _Controller;
/// <summary>
/// 全局数据库连接器
/// </summary>
public SQLHelper? SQLHelper => Singleton.Get<SQLHelper>();
/// <summary>
/// 全局邮件发送器
/// </summary>
public MailSender? MailSender => Singleton.Get<MailSender>();
/// <summary> /// <summary>
/// 启动服务器监听 请在此处实现服务器逻辑 /// 启动服务器监听 请在此处实现服务器逻辑

View File

@ -1,13 +1,11 @@
using Milimoe.FunGame.Core.Api.Transmittal; using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Interface; using Milimoe.FunGame.Core.Interface;
using Milimoe.FunGame.Core.Interface.Addons; using Milimoe.FunGame.Core.Interface.Addons;
using Milimoe.FunGame.Core.Library.Common.Event; using Milimoe.FunGame.Core.Library.Common.Event;
namespace Milimoe.FunGame.Core.Library.Common.Addon namespace Milimoe.FunGame.Core.Library.Common.Addon
{ {
public abstract class ServerPlugin : IPlugin, IServerAddon public abstract class ServerPlugin : IPlugin
{ {
/// <summary> /// <summary>
/// 插件名称 /// 插件名称
@ -32,26 +30,25 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// <summary> /// <summary>
/// 包含了一些常用方法的控制器 /// 包含了一些常用方法的控制器
/// </summary> /// </summary>
public BaseAddonController<IPlugin> Controller public ServerAddonController<IPlugin> Controller
{ {
get => _Controller ?? throw new NotImplementedException(); get => _Controller ?? throw new NotImplementedException();
set => _Controller = value; internal set => _Controller = value;
} }
/// <summary> /// <summary>
/// 全局数据库连接 /// base控制
/// </summary> /// </summary>
public SQLHelper? SQLHelper => Singleton.Get<SQLHelper>(); BaseAddonController<IPlugin> IAddonController<IPlugin>.Controller
{
/// <summary> get => Controller;
/// 全局邮件发送器 set => _Controller = (ServerAddonController<IPlugin>?)value;
/// </summary> }
public MailSender? MailSender => Singleton.Get<MailSender>();
/// <summary> /// <summary>
/// 控制器内部变量 /// 控制器内部变量
/// </summary> /// </summary>
private BaseAddonController<IPlugin>? _Controller; private ServerAddonController<IPlugin>? _Controller;
/// <summary> /// <summary>
/// 加载标记 /// 加载标记

View File

@ -1,11 +1,9 @@
using Milimoe.FunGame.Core.Api.Transmittal; using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Controller;
using Milimoe.FunGame.Core.Interface.Addons; using Milimoe.FunGame.Core.Interface.Addons;
namespace Milimoe.FunGame.Core.Library.Common.Addon namespace Milimoe.FunGame.Core.Library.Common.Addon
{ {
public abstract class WebAPIPlugin : IAddon, IServerAddon, IAddonController<IAddon> public abstract class WebAPIPlugin : IAddon, IAddonController<IAddon>
{ {
/// <summary> /// <summary>
/// 插件名称 /// 插件名称
@ -30,38 +28,37 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
/// <summary> /// <summary>
/// 包含了一些常用方法的控制器 /// 包含了一些常用方法的控制器
/// </summary> /// </summary>
public BaseAddonController<IAddon> Controller public ServerAddonController<IAddon> Controller
{ {
get => _Controller ?? throw new NotImplementedException(); get => _Controller ?? throw new NotImplementedException();
set => _Controller = value; internal set => _Controller = value;
}
/// <summary>
/// base控制器
/// </summary>
BaseAddonController<IAddon> IAddonController<IAddon>.Controller
{
get => Controller;
set => _Controller = (ServerAddonController<IAddon>?)value;
} }
/// <summary> /// <summary>
/// 控制器内部变量 /// 控制器内部变量
/// </summary> /// </summary>
private BaseAddonController<IAddon>? _Controller; private ServerAddonController<IAddon>? _Controller;
/// <summary>
/// 全局数据库连接器
/// </summary>
public SQLHelper? SQLHelper => Singleton.Get<SQLHelper>();
/// <summary>
/// 全局邮件发送器
/// </summary>
public MailSender? MailSender => Singleton.Get<MailSender>();
/// <summary> /// <summary>
/// 加载标记 /// 加载标记
/// </summary> /// </summary>
private bool IsLoaded = false; private bool _isLoaded = false;
/// <summary> /// <summary>
/// 加载插件 /// 加载插件
/// </summary> /// </summary>
public bool Load(params object[] objs) public bool Load(params object[] objs)
{ {
if (IsLoaded) if (_isLoaded)
{ {
return false; return false;
} }
@ -69,9 +66,9 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
if (BeforeLoad(objs)) if (BeforeLoad(objs))
{ {
// 插件加载后,不允许再次加载此插件 // 插件加载后,不允许再次加载此插件
IsLoaded = true; _isLoaded = true;
} }
return IsLoaded; return _isLoaded;
} }
/// <summary> /// <summary>

View File

@ -94,6 +94,14 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
SkillGroup skills = NetworkUtility.JsonDeserialize<SkillGroup>(ref reader, options) ?? new(); SkillGroup skills = NetworkUtility.JsonDeserialize<SkillGroup>(ref reader, options) ?? new();
result.Skills.Active = skills.Active; result.Skills.Active = skills.Active;
result.Skills.Passives = skills.Passives; result.Skills.Passives = skills.Passives;
result.Skills.Magics = skills.Magics;
break;
case nameof(Item.Others):
Dictionary<string, object> values = NetworkUtility.JsonDeserialize<Dictionary<string, object>>(ref reader, options) ?? [];
foreach (string key in values.Keys)
{
result.Others.Add(key, values[key]);
}
break; break;
} }
} }
@ -129,6 +137,8 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
} }
writer.WritePropertyName(nameof(Item.Skills)); writer.WritePropertyName(nameof(Item.Skills));
JsonSerializer.Serialize(writer, value.Skills, options); JsonSerializer.Serialize(writer, value.Skills, options);
writer.WritePropertyName(nameof(Item.Others));
JsonSerializer.Serialize(writer, value.Others, options);
writer.WriteEndObject(); writer.WriteEndObject();
} }

View File

@ -39,17 +39,17 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
/// <summary> /// <summary>
/// 收件人列表 /// 收件人列表
/// </summary> /// </summary>
public List<string> ToList { get; } = new(); public List<string> ToList { get; } = [];
/// <summary> /// <summary>
/// 抄送列表 /// 抄送列表
/// </summary> /// </summary>
public List<string> CCList { get; } = new(); public List<string> CCList { get; } = [];
/// <summary> /// <summary>
/// 密送列表 /// 密送列表
/// </summary> /// </summary>
public List<string> BCCList { get; } = new(); public List<string> BCCList { get; } = [];
public MailObject() public MailObject()
{ {
@ -59,80 +59,80 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
/// <summary> /// <summary>
/// 使用MailSender工具类创建邮件对象 /// 使用MailSender工具类创建邮件对象
/// </summary> /// </summary>
/// <param name="Sender"></param> /// <param name="sender"></param>
public MailObject(MailSender Sender) public MailObject(MailSender sender)
{ {
this.Sender = Sender.SmtpClientInfo.SenderMailAddress; this.Sender = sender.SmtpClientInfo.SenderMailAddress;
this.SenderName = Sender.SmtpClientInfo.SenderName; this.SenderName = sender.SmtpClientInfo.SenderName;
} }
/// <summary> /// <summary>
/// 使用地址和名称创建邮件对象 /// 使用地址和名称创建邮件对象
/// </summary> /// </summary>
/// <param name="Sender"></param> /// <param name="sender"></param>
/// <param name="SenderName"></param> /// <param name="senderName"></param>
public MailObject(string Sender, string SenderName) public MailObject(string sender, string senderName)
{ {
this.Sender = Sender; this.Sender = sender;
this.SenderName = SenderName; this.SenderName = senderName;
} }
/// <summary> /// <summary>
/// 使用地址和名称创建邮件对象,同时写主题、内容、单个收件人 /// 使用地址和名称创建邮件对象,同时写主题、内容、单个收件人
/// </summary> /// </summary>
/// <param name="Sender"></param> /// <param name="sender"></param>
/// <param name="Subject"></param> /// <param name="subject"></param>
/// <param name="Body"></param> /// <param name="body"></param>
/// <param name="To"></param> /// <param name="to"></param>
public MailObject(MailSender Sender, string Subject, string Body, string To) public MailObject(MailSender sender, string subject, string body, string to)
{ {
this.Sender = Sender.SmtpClientInfo.SenderMailAddress; this.Sender = sender.SmtpClientInfo.SenderMailAddress;
this.SenderName = Sender.SmtpClientInfo.SenderName; this.SenderName = sender.SmtpClientInfo.SenderName;
this.Subject = Subject; this.Subject = subject;
this.Body = Body; this.Body = body;
ToList.Add(To); ToList.Add(to);
} }
/// <summary> /// <summary>
/// 使用地址和名称创建邮件对象,同时写主题、内容、单个收件人、单个抄送 /// 使用地址和名称创建邮件对象,同时写主题、内容、单个收件人、单个抄送
/// </summary> /// </summary>
/// <param name="Sender"></param> /// <param name="sender"></param>
/// <param name="Subject"></param> /// <param name="subject"></param>
/// <param name="Body"></param> /// <param name="body"></param>
/// <param name="To"></param> /// <param name="to"></param>
/// <param name="CC"></param> /// <param name="cc"></param>
public MailObject(MailSender Sender, string Subject, string Body, string To, string CC) public MailObject(MailSender sender, string subject, string body, string to, string cc)
{ {
this.Sender = Sender.SmtpClientInfo.SenderMailAddress; this.Sender = sender.SmtpClientInfo.SenderMailAddress;
this.SenderName = Sender.SmtpClientInfo.SenderName; this.SenderName = sender.SmtpClientInfo.SenderName;
this.Subject = Subject; this.Subject = subject;
this.Body = Body; this.Body = body;
ToList.Add(To); ToList.Add(to);
CCList.Add(CC); CCList.Add(cc);
} }
/// <summary> /// <summary>
/// 完整的创建邮件对象 /// 完整的创建邮件对象
/// </summary> /// </summary>
/// <param name="Sender"></param> /// <param name="sender"></param>
/// <param name="Subject"></param> /// <param name="subject"></param>
/// <param name="Body"></param> /// <param name="body"></param>
/// <param name="Priority"></param> /// <param name="priority"></param>
/// <param name="HTML"></param> /// <param name="html"></param>
/// <param name="ToList"></param> /// <param name="toList"></param>
/// <param name="CCList"></param> /// <param name="ccList"></param>
/// <param name="BCCList"></param> /// <param name="bccList"></param>
public MailObject(MailSender Sender, string Subject, string Body, MailPriority Priority, bool HTML, string[] ToList, string[]? CCList = null, string[]? BCCList = null) public MailObject(MailSender sender, string subject, string body, MailPriority priority, bool html, string[] toList, string[]? ccList = null, string[]? bccList = null)
{ {
this.Sender = Sender.SmtpClientInfo.SenderMailAddress; Sender = sender.SmtpClientInfo.SenderMailAddress;
this.SenderName = Sender.SmtpClientInfo.SenderName; SenderName = sender.SmtpClientInfo.SenderName;
this.Subject = Subject; Subject = subject;
this.Body = Body; Body = body;
this.Priority = Priority; Priority = priority;
this.HTML = HTML; HTML = html;
AddTo(ToList); AddTo(toList);
if (CCList != null) AddCC(CCList); if (ccList != null) AddCC(ccList);
if (BCCList != null) AddBCC(BCCList); if (bccList != null) AddBCC(bccList);
} }
/// <summary> /// <summary>

View File

@ -482,6 +482,34 @@ namespace Milimoe.FunGame.Core.Library.Constant
_ => EquipSlotType.None _ => EquipSlotType.None
}; };
} }
public static string GetQualityTypeName(QualityType type)
{
return type switch
{
QualityType.Green => "优秀",
QualityType.Blue => "稀有",
QualityType.Purple => "史诗",
QualityType.Orange => "传说",
QualityType.Red => "神话",
QualityType.Gold => "不朽",
_ => "普通"
};
}
public static QualityType GetQualityTypeFromName(string name)
{
return name switch
{
"优秀" => QualityType.Green,
"稀有" => QualityType.Blue,
"史诗" => QualityType.Purple,
"传说" => QualityType.Orange,
"神话" => QualityType.Red,
"不朽" => QualityType.Gold,
_ => QualityType.White
};
}
} }
public class SkillSet public class SkillSet

View File

@ -28,6 +28,19 @@
public const string FunGame_Version = "v1.0"; public const string FunGame_Version = "v1.0";
public const string FunGame_VersionPatch = ""; public const string FunGame_VersionPatch = "";
public const string FunGameCoreTitle = @" _____ _ _ _ _ ____ _ __ __ _____ ____ ___ ____ _____
| ___| | | | \ | |/ ___| / \ | \/ | ____| / ___/ _ \| _ \| ____|
| |_ | | | | \| | | _ / _ \ | |\/| | _| | | | | | | |_) | _|
| _| | |_| | |\ | |_| |/ ___ \| | | | |___ | |__| |_| | _ <| |___
|_| \___/|_| \_|\____/_/ \_\_| |_|_____| \____\___/|_| \_\_____|
";
public const string FunGameServerTitle = @" _____ _ _ _ _ ____ _ __ __ _____ ____ _____ ______ _______ ____
| ___| | | | \ | |/ ___| / \ | \/ | ____| / ___|| ____| _ \ \ / / ____| _ \
| |_ | | | | \| | | _ / _ \ | |\/| | _| \___ \| _| | |_) \ \ / /| _| | |_) |
| _| | |_| | |\ | |_| |/ ___ \| | | | |___ ___) | |___| _ < \ V / | |___| _ <
|_| \___/|_| \_|\____/_/ \_\_| |_|_____| |____/|_____|_| \_\ \_/ |_____|_| \_\
";
public static string GetInfo(FunGame FunGameType) public static string GetInfo(FunGame FunGameType)
{ {
string type = FunGameType switch string type = FunGameType switch

View File

@ -753,7 +753,8 @@ namespace Milimoe.FunGame.Core.Library.Constant
Blue, Blue,
Purple, Purple,
Orange, Orange,
Red Red,
Gold
} }
public enum RarityType public enum RarityType

View File

@ -4,28 +4,21 @@ namespace Milimoe.FunGame.Core.Model
{ {
public class SmtpClientInfo : IMailSender public class SmtpClientInfo : IMailSender
{ {
public string Host => _Host; public string SenderMailAddress { get; set; } = "";
public int Port => _Port; public string SenderName { get; set; } = "";
public bool OpenSSL => _OpenSSL; public string SenderPassword { get; set; } = "";
public string SenderMailAddress => _SenderMailAddress; public string Host { get; set; } = "";
public string SenderName => _SenderName; public int Port { get; set; } = 587;
public string SenderPassword => _SenderPassword; public bool SSL { get; set; } = false;
private string _Host = ""; internal SmtpClientInfo(string senderMailAddress, string senderName, string senderPassword, string host, int port, bool ssl)
private int _Port = 587;
private bool _OpenSSL = true;
private string _SenderMailAddress = "";
private string _SenderName = "";
private string _SenderPassword = "";
internal SmtpClientInfo(string SenderMailAddress, string SenderName, string SenderPassword, string Host, int Port, bool OpenSSL)
{ {
_Host = Host; SenderMailAddress = senderMailAddress;
_Port = Port; SenderName = senderName;
_OpenSSL = OpenSSL; SenderPassword = senderPassword;
_SenderMailAddress = SenderMailAddress; Host = host;
_SenderName = SenderName; Port = port;
_SenderPassword = SenderPassword; SSL = ssl;
} }
} }
} }

View File

@ -25,11 +25,11 @@ namespace Milimoe.FunGame.Core.Service
/// <summary> /// <summary>
/// 获取某个已经保存过的邮件服务 /// 获取某个已经保存过的邮件服务
/// </summary> /// </summary>
/// <param name="MailSenderID"></param> /// <param name="mailSenderID"></param>
/// <returns></returns> /// <returns></returns>
internal static MailSender? GetSender(Guid MailSenderID) internal static MailSender? GetSender(Guid mailSenderID)
{ {
if (MailSenders.TryGetValue(MailSenderID, out MailSender? value)) if (MailSenders.TryGetValue(mailSenderID, out MailSender? value))
{ {
return value; return value;
} }
@ -39,60 +39,60 @@ namespace Milimoe.FunGame.Core.Service
/// <summary> /// <summary>
/// 统一调用此方法发送邮件 /// 统一调用此方法发送邮件
/// </summary> /// </summary>
/// <param name="Sender"></param> /// <param name="sender"></param>
/// <param name="Mail"></param> /// <param name="mail"></param>
/// <param name="ErrorMsg"></param> /// <param name="errorMsg"></param>
/// <returns></returns> /// <returns></returns>
internal static MailSendResult Send(MailSender Sender, MailObject Mail, out string ErrorMsg) internal static MailSendResult Send(MailSender sender, MailObject mail, out string errorMsg)
{ {
ErrorMsg = ""; errorMsg = "";
try try
{ {
SmtpClientInfo Info = Sender.SmtpClientInfo; SmtpClientInfo info = sender.SmtpClientInfo;
SmtpClient Smtp; SmtpClient smtp;
Guid MailSenderID = Sender.MailSenderID; Guid senderID = sender.MailSenderID;
if (!SmtpClients.TryGetValue(MailSenderID, out SmtpClient? value)) if (!SmtpClients.TryGetValue(senderID, out SmtpClient? value))
{ {
Smtp = new() smtp = new()
{ {
Host = Info.Host, Host = info.Host,
Port = Info.Port, Port = info.Port,
EnableSsl = Info.OpenSSL, EnableSsl = info.SSL,
DeliveryMethod = SmtpDeliveryMethod.Network, DeliveryMethod = SmtpDeliveryMethod.Network,
Credentials = new NetworkCredential(Info.SenderMailAddress, Info.SenderPassword) Credentials = new NetworkCredential(info.SenderMailAddress, info.SenderPassword)
}; };
SmtpClients.Add(MailSenderID, Smtp); SmtpClients.Add(senderID, smtp);
} }
else Smtp = value; else smtp = value;
MailMessage Msg = new() MailMessage Msg = new()
{ {
Subject = Mail.Subject, Subject = mail.Subject,
SubjectEncoding = General.DefaultEncoding, SubjectEncoding = General.DefaultEncoding,
Body = Mail.Body, Body = mail.Body,
BodyEncoding = General.DefaultEncoding, BodyEncoding = General.DefaultEncoding,
From = new MailAddress(Mail.Sender, Mail.SenderName, General.DefaultEncoding), From = new MailAddress(mail.Sender, mail.SenderName, General.DefaultEncoding),
IsBodyHtml = Mail.HTML, IsBodyHtml = mail.HTML,
Priority = Mail.Priority Priority = mail.Priority
}; };
foreach (string To in Mail.ToList) foreach (string To in mail.ToList)
{ {
if (To.Trim() != "") Msg.To.Add(To); if (To.Trim() != "") Msg.To.Add(To);
} }
foreach (string CC in Mail.CCList) foreach (string CC in mail.CCList)
{ {
if (CC.Trim() != "") Msg.CC.Add(CC); if (CC.Trim() != "") Msg.CC.Add(CC);
} }
foreach (string BCC in Mail.BCCList) foreach (string BCC in mail.BCCList)
{ {
if (BCC.Trim() != "") Msg.Bcc.Add(BCC); if (BCC.Trim() != "") Msg.Bcc.Add(BCC);
} }
Smtp.SendMailAsync(Msg); smtp.SendMailAsync(Msg);
return MailSendResult.Success; return MailSendResult.Success;
} }
catch (Exception e) catch (Exception e)
{ {
ErrorMsg = e.GetErrorInfo(); errorMsg = e.GetErrorInfo();
Api.Utility.TXTHelper.AppendErrorLog(ErrorMsg); Api.Utility.TXTHelper.AppendErrorLog(errorMsg);
return MailSendResult.Fail; return MailSendResult.Fail;
} }
} }
@ -100,18 +100,18 @@ namespace Milimoe.FunGame.Core.Service
/// <summary> /// <summary>
/// 关闭邮件服务 /// 关闭邮件服务
/// </summary> /// </summary>
/// <param name="Sender"></param> /// <param name="sender"></param>
/// <returns></returns> /// <returns></returns>
internal static bool Dispose(MailSender Sender) internal static bool Dispose(MailSender sender)
{ {
try try
{ {
Guid MailSenderID = Sender.MailSenderID; Guid senderID = sender.MailSenderID;
if (SmtpClients.TryGetValue(MailSenderID, out SmtpClient? value)) if (SmtpClients.TryGetValue(senderID, out SmtpClient? value))
{ {
value.Dispose(); value.Dispose();
SmtpClients.Remove(MailSenderID); SmtpClients.Remove(senderID);
MailSenders.Remove(MailSenderID); MailSenders.Remove(senderID);
return true; return true;
} }
return false; return false;