using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Threading; using ActorCore; using GameData; using ObjectModel.User; using Server.AliyunSDK.SLSLog; using Server.Core; using Server.Data.Module; using Server.DB.Sql; namespace Server { public partial class PropManager : SingleInstance, IDisposable { private const string TableName = "UserProps"; private const string PropIdFiledName = "PropId"; private const string CountFiledName = "Count"; private Timer _timer; public PropManager() { GameDispatcher.Instance.AddListener(GameMsgId.UserPropChange, OnUserPropChange); GameCenterMainActorId = new ActorId((byte)ModuleType.GameCenter, 0, ActorTypeId.Main); _timer = new Timer(OnSecondTime, null, 1000, 3 * 1000); } private Dictionary SelectUserProp(int userid) { Dictionary dic = new Dictionary(); string sql = $"SELECT * FROM {TableName} where UserId = @userid"; DataSet ds = new DataSet(); GameDB.Instance.ExceSql(dbbase.gamedb, sql, new SqlParameter[] { new SqlParameter("@userid", userid) }, ds); if (ds.Tables.Count > 0) { for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { int propId = (int)ds.Tables[0].Rows[i][PropIdFiledName]; int count = (int)ds.Tables[0].Rows[i][CountFiledName]; dic.Add(propId, count); } } return dic; } #region 道具日志 private readonly UserPropLogInfo logBasicInfo = new UserPropLogInfo(); private readonly UserGoldLogInfo logGoldInfo = new UserGoldLogInfo(); private readonly ConcurrentQueue _propLogQueue = new ConcurrentQueue(); private readonly ConcurrentListPool _listPool = new ConcurrentListPool(); /// /// 秒级定时器 /// private void OnSecondTime(object state) { SaveUserPropLog(); } private async void SaveUserPropLog() { if (_propLogQueue.Count <= 0) { return; } List propList = _listPool.Get(); List goldList = _listPool.Get(); while (_propLogQueue.TryDequeue(out var item)) { if (item is UserGoldLogData) goldList.Add(item); else if (item is UserPropLogData) propList.Add(item); } //保存日志 await SLSLogManager.Instance.ReportLog(logBasicInfo, propList); await SLSLogManager.Instance.ReportLog(logGoldInfo, goldList); foreach (var item in propList) { item.Dispose(); } foreach (var item in goldList) { item.Dispose(); } _listPool.Recycle(propList); _listPool.Recycle(goldList); } public void AddLog(int userid, int propId, long changeCount, long finalValue, string tag) { UserPropLogData data = UserPropLogData.Create(userid, propId, changeCount, finalValue, ServerConfigManager.Instance.NodeId, ServerConfigManager.Instance.NodeNum, tag); _propLogQueue.Enqueue(data); } public void AddGoldLog(int userid, long changeCount, long finalValue, UserGoldLogType logType, string tag) { UserGoldLogData data = UserGoldLogData.Create(userid, ResName.Gold, logType, changeCount, finalValue, ServerConfigManager.Instance.NodeId, ServerConfigManager.Instance.NodeNum, tag); _propLogQueue.Enqueue(data); } public void AddLog(int userid,List logs) { foreach (var log in logs) { if (log.Id == ResName.Gold) { AddGoldLog(userid,log.ChangeValue,log.FinValue,log.GoldLogType,log.Tag); } else { AddLog(userid,log.Id,log.ChangeValue,log.FinValue,log.Tag); } } } public void Dispose() { _timer?.Dispose(); SaveUserPropLog(); SaveUserPropCaches(); } #endregion } }