194 lines
6.4 KiB
C#
194 lines
6.4 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using NeoSmart.AsyncLock;
|
|
using Google.Protobuf.WellKnownTypes;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
|
using ServerCore; using ServerBase;
|
|
|
|
|
|
using META_ID = System.UInt32;
|
|
|
|
|
|
namespace ServerCommon
|
|
{
|
|
public class BuffAttribute : EntityAttributeBase, ICopyEntityAttributeFromCache
|
|
{
|
|
public class BuffInfo
|
|
{
|
|
[JsonProperty]
|
|
public META_ID BuffMetaID { get; set; } = 0;
|
|
[JsonProperty]
|
|
public DateTime BuffStartTime { get; set; } = new();
|
|
|
|
public BuffInfo()
|
|
{ }
|
|
|
|
public BuffInfo(BuffInfo buffInfo)
|
|
{
|
|
BuffMetaID = buffInfo.BuffMetaID;
|
|
BuffStartTime = buffInfo.BuffStartTime;
|
|
}
|
|
|
|
}
|
|
|
|
[JsonProperty]
|
|
public Dictionary<MetaAssets.EBuffCategory, Dictionary<int, BuffInfo>> BuffInfos = new();
|
|
|
|
private AsyncLock m_lock = new();
|
|
|
|
public BuffAttribute(EntityBase owner)
|
|
: base(owner)
|
|
{
|
|
foreach (MetaAssets.EBuffCategory category in System.Enum.GetValues(typeof(MetaAssets.EBuffCategory)))
|
|
{
|
|
var buff_channel_Info = new Dictionary<int, BuffInfo>();
|
|
BuffInfos.TryAdd(category, buff_channel_Info);
|
|
}
|
|
}
|
|
public override void onClear()
|
|
{
|
|
foreach(var buff_infos in BuffInfos.Values)
|
|
{
|
|
buff_infos.Clear();
|
|
}
|
|
}
|
|
|
|
public bool copyEntityAttributeFromCache(CacheBase cacheBase)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
var to_cast_string = typeof(BuffCache).Name;
|
|
|
|
var buff_cache = cacheBase as BuffCache;
|
|
if (null == buff_cache)
|
|
{
|
|
err_msg = $"Failed to copyEntityAttributeFromCache() !!!, buff_cache is null :{to_cast_string}";
|
|
Log.getLogger().error(err_msg);
|
|
return false;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// Cache => Attribute
|
|
//=====================================================================================
|
|
|
|
foreach(var channel_buff in buff_cache.buff_cache_Infos)
|
|
{
|
|
foreach(var buff_info_cache in channel_buff.Value)
|
|
{
|
|
if (false == MetaData.Instance._BuffTable.TryGetValue((int)buff_info_cache.Value.BuffMetaID, out var buffMetaData))
|
|
{
|
|
err_msg = $"Not found BuffMeta !!! : buffMetaId:{buff_info_cache.Value.BuffMetaID}";
|
|
result.setFail(ServerErrorCode.BuffMetaDataNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
continue;
|
|
}
|
|
|
|
if (BuffInfos.TryGetValue(channel_buff.Key, out var attribute_channel_buffs) == false)
|
|
{
|
|
attribute_channel_buffs = new Dictionary<int, BuffInfo>();
|
|
BuffInfos.TryAdd(channel_buff.Key, attribute_channel_buffs);
|
|
}
|
|
|
|
var buff = new BuffInfo();
|
|
buff.BuffMetaID = buff_info_cache.Value.BuffMetaID;
|
|
buff.BuffStartTime = buff_info_cache.Value.BuffStartTime;
|
|
|
|
attribute_channel_buffs.TryAdd(buff_info_cache.Key, buff);
|
|
{
|
|
err_msg = $"Duplicated buff in channel !!! : buffMetaId:{buff_info_cache.Value.BuffMetaID}";
|
|
result.setFail(ServerErrorCode.BuffCacheLoadDuplicatedBuff, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool AddBuff(MetaAssets.EBuffCategory eBuffCategory, int channel, int buffId, [MaybeNullWhen(false)] out BuffInfo addBuff)
|
|
{
|
|
addBuff = null;
|
|
if (BuffInfos.TryGetValue(eBuffCategory, out var buffchannelInfo) == false)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var buff = new BuffInfo();
|
|
buff.BuffMetaID = (META_ID)buffId;
|
|
buff.BuffStartTime = DateTimeHelper.Current;
|
|
|
|
using (m_lock.Lock())
|
|
{
|
|
if (buffchannelInfo.TryAdd(channel, buff) == false)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
addBuff = buff;
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool RemoveBuff(MetaAssets.EBuffCategory eBuffCategory, int channel, [MaybeNullWhen(false)] out BuffInfo delBuff)
|
|
{
|
|
delBuff = null;
|
|
if (BuffInfos.TryGetValue(eBuffCategory, out var buffchannelInfo) == false)
|
|
{
|
|
return false;
|
|
}
|
|
using (m_lock.Lock())
|
|
{
|
|
if (buffchannelInfo.Remove(channel, out delBuff) == false)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public override EntityAttributeBase onCloned()
|
|
{
|
|
var buff_attribute = new BuffAttribute(getOwner());
|
|
|
|
foreach (var buff_channels in BuffInfos)
|
|
{
|
|
buff_attribute.BuffInfos[buff_channels.Key] = new Dictionary<int, BuffInfo>(buff_channels.Value.ToDictionary(a => a.Key, b => new BuffInfo(b.Value)));
|
|
}
|
|
|
|
return buff_attribute;
|
|
}
|
|
|
|
public override IEntityAttributeTransactor onNewEntityAttributeTransactor()
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var player = owner.getRootParent() as UserBase;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
|
|
|
|
return new BuffAttributeTransactor(player);
|
|
}
|
|
}
|
|
|
|
public class BuffAttributeTransactor : EntityAttributeTransactorBase<BuffAttribute>
|
|
{
|
|
public BuffAttributeTransactor(UserBase owner)
|
|
: base(owner)
|
|
{
|
|
}
|
|
}
|
|
}
|