using System; using System.Threading; using System.Collections.Concurrent; using Sog.Service; using Sog; using ProtoCSStruct; using System.Text.RegularExpressions; using System.Collections.Generic; using System.IO; namespace PlayerOp { public class ExchangeSaveData { public int type; // 0 新增, 1 修改 public ExchangeConfigure Config; } public class ExchangeSvc : BaseReloadableService { private ExchangeCodeManager m_exchangeManger; //每次最大加载数 private const int Max_Load_Count = 100; private ConcurrentQueue m_dbThreadPacketQueue; public static Object m_locker = new Object(); private ExchangeCodeStrcut emptyExchangeCode = new ExchangeCodeStrcut { m_objectID = -1 }; public override int GetServiceType() { return PlayerOpServiceType.ExchangeSvc; } public override void Dispose() { } public ExchangeSvc() { m_exchangeManger = new ExchangeCodeManager(); m_dbThreadPacketQueue = new ConcurrentQueue(); } public ExchangeCodeManager GetExchangeCodeManager() { return m_exchangeManger; } public void OnTick(long nowSec, long nowMs) { DoMsgTick(); m_exchangeManger.OnTickSaveCode(nowMs); } public bool IsAllDataSave() { var data = PlayerOpServerData.GetExchangeCodeCache(); return data.m_codeIdMap.Count == 0; } public bool IsAllReqHandle() { return m_dbThreadPacketQueue.IsEmpty; } public void OnExchangeCodeTakeReq(uint serverID, StructPacket packet) { ref SSExchangeCodeTakeReq req = ref packet.GetMessage(); string code = req.Code.GetString(); code = code.Replace(" ", ""); TraceLog.Debug("ExchangeSvc.OnExchangeCodeTakeReq - Code:{0} - uid:{1}", code, req.Uid); var data = PlayerOpServerData.GetExchangeCodeCache().m_uidCodeMap; if(data.ContainsKey(code)) { if(data[code] == req.Uid) { SSExchangeCodeTakeRes res = new SSExchangeCodeTakeRes(); res.CodeId = req.CodeId; res.Ret = (int)CSErrCode.ExchangeCodeReceived; PlayerOpServerUtils.GetPacketSender().SendToServerByID(serverID, (int)SSGameMsgID.ExchangeCodeTakeRes, ref res, packet.ObjectID, packet.Header.ServerID); TraceLog.Error("ExchangeSvc.OnExchangeCodeTakeReq error - Code:{0}, uid:{1}", req.Code.GetString(), req.Uid); return; } } // 到DB查询判定 StructPacket dbPacket = new StructPacket(); dbPacket.Header.Type = (int)SSGameMsgID.ExchangeRecordQueryDbReq; dbPacket.Header.ServerID = packet.Header.ServerID; dbPacket.Header.ObjectID = packet.ObjectID; StructMessageParser parser = new StructMessageParser(); dbPacket.Parser = parser; ref SSExchangeRecordQueryDbReq dbReq = ref dbPacket.GetMessage(); dbReq.CodeId = 0; dbReq.Code.SetString(code); dbReq.GroupId = 0; dbReq.Index = 0; dbReq.Uid = req.Uid; PlayerOpMsgHandler.AddMessageTaskDistributor(serverID, dbPacket); } public void OnExchangeRecordQueryDbRes(uint serverID, StructPacket packet) { ref SSExchangeRecordQueryDbRes req = ref packet.GetMessage(); SSExchangeCodeTakeRes res = new SSExchangeCodeTakeRes(); res.CodeId = req.CodeId; res.GroupId = req.GroupId; if (req.Ret != 0) { res.Ret = req.Ret; PlayerOpServerUtils.GetPacketSender().SendToServerByID(serverID, (int)SSGameMsgID.ExchangeCodeTakeRes , ref res, packet.ObjectID, packet.Header.ServerID); return; } // 这里有问题 暂时拿掉验证 //var data = PlayerOpServerData.GetExchangeCodeCache().m_uidCodeMap; //data.Add(req.Code.GetString(), req.Uid); for (int i = 0; i < req.Content.AddGoods.Count; i++) { ref var it = ref req.Content.AddGoods[i]; res.RewardList.Add(ref it); } for (int i = 0; i < req.Content.Groups.Count; i++) { var group = req.Content.Groups[i]; if (res.GroupId != group.GroupId) { continue; } for (int j = 0; j < group.AddGoods.Count; j++) { ref var it = ref group.AddGoods[j]; res.RewardList.Add(ref it); } } PlayerOpServerUtils.GetPacketSender().SendToServerByID(serverID, (int)SSGameMsgID.ExchangeCodeTakeRes , ref res, packet.ObjectID, packet.Header.ServerID); } public void OnExchangeQueryDbRes(uint serverID, StructPacket packet) { ref SSExchangeCodeQueryDbRes res = ref packet.GetMessage(); PlayerOpServerUtils.GetPacketSender().SendToServerByID(serverID, (int)SSGameMsgID.ExchangeQueryDbRes , ref res, packet.ObjectID, packet.Header.ServerID); } public void OnExchangeSaveDbRes(uint serverID, StructPacket packet) { ref SSExchangeCodeSaveDbRes res = ref packet.GetMessage(); PlayerOpServerUtils.GetPacketSender().SendToServerByID(serverID, (int)SSGameMsgID.ExchangeSaveDbRes , ref res, packet.ObjectID, packet.Header.ServerID); } public void OnExchangeChangeStatusDbRes(uint serverID, StructPacket packet) { ref SSExchangeStatusChangeRes res = ref packet.GetMessage(); PlayerOpServerUtils.GetPacketSender().SendToServerByID(serverID, (int)SSGameMsgID.ExchangeStatusChangeRes , ref res, packet.ObjectID, packet.Header.ServerID); } private void DoMsgTick() { int handleCount = 0; // 每次 tick 后在主线程处理 while (!m_dbThreadPacketQueue.IsEmpty) { if (handleCount++ > 100) { break; } StructPacketData packetData; bool bDequeueSuccess = m_dbThreadPacketQueue.TryDequeue(out packetData); if (bDequeueSuccess) { try { switch (packetData.Packet.MsgID) { case (int)SSGameMsgID.ExchangeRecordQueryDbRes: OnExchangeRecordQueryDbRes(packetData.RemoteApp, packetData.Packet); break; case (int)SSGameMsgID.ExchangeSaveDbRes: OnExchangeSaveDbRes(packetData.RemoteApp, packetData.Packet); break; case (int)SSGameMsgID.ExchangeQueryDbRes: OnExchangeQueryDbRes(packetData.RemoteApp, packetData.Packet); break; case (int)SSGameMsgID.ExchangeStatusChangeRes: OnExchangeChangeStatusDbRes(packetData.RemoteApp, packetData.Packet); break; default: break; } } catch (Exception ex) { TraceLog.Error("ExchangeSvc.DoMsgTick handler packet msgid {0} throw exception!", packetData.Packet.MsgID); TraceLog.Exception(ex); } } } } public void AddRequestPacket(uint remoteApp, StructPacket packet) { m_dbThreadPacketQueue.Enqueue(new StructPacketData(remoteApp, packet)); } public void SaveExchangeCodeData(ref ExchangeConfigure one, uint reqId) { TraceLog.Trace("ExchangeSvc.SaveExchangeCodeData reqId {0}", reqId); StructPacket dbPacket = new StructPacket(); dbPacket.Header.Type = (int)SSGameMsgID.ExchangeSaveDbReq; StructMessageParser parser = new StructMessageParser(); dbPacket.Parser = parser; ref SSExchangeCodeSaveDbReq dbReq = ref dbPacket.GetMessage(); dbReq.Data.CopyFrom(ref one); dbReq.Seq = reqId; PlayerOpMsgHandler.AddMessageTaskDistributor(0, dbPacket); } public bool CodeCheck(string code, int maxLen, int minLen) { string pattern = @"^[a-zA-Z0-9]*$"; if(code.Length <= minLen | code.Length >= maxLen) { return false; } if(!Regex.IsMatch(code, pattern)) { return false; } return true; } public bool CreateGroupCode(ref ExchangeConfigure Config) { int seed = (int)PlayerOpServerUtils.GetTimeSecond(); var codeManger = PlayerOpServerUtils.GetExchangeSvc().GetExchangeCodeManager(); string exchangeCodePre = Config.ExchangeCode.GetString(); var exchangeCodesTmp = new List(); for (int i = 0; i < Config.Content.Groups.Count; i++) { var group = Config.Content.Groups[i]; int groupId = group.GroupId; int groupCodeCount = group.GroupCount; // 组兑换码添加到存储队列 var createCodes = DynamicExchangeSvc.CreateCodes(groupId, groupCodeCount, seed); Dictionary exchangeCodes = new Dictionary(); foreach (var item in createCodes) { string tempCode = exchangeCodePre + item.Value; if (exchangeCodes.ContainsValue(tempCode)) { TraceLog.Error("ExchangeSvc.CreateGroupCode CreateCodes error: 激活码错误."); break; } exchangeCodes.Add(item.Key, tempCode); exchangeCodesTmp.Add( tempCode + "," + groupId); } if (!codeManger.CreateExchangeCodeGroup(groupId, exchangeCodes, exchangeCodePre, Config.Id)) { return false; } } //先将激活码成功写入本地文件留做备份保存 string filename = "exchangeCode_" + exchangeCodePre + "_" + Config.Id+ ".csv"; string fullPath = PlayerOpServerUtils.GetServerConfig().codefliepath + filename; try { WriteCodeToFile(fullPath, exchangeCodesTmp); } catch (Exception ex) { TraceLog.Error("ExchangeSvc.CreateGroupCode CreateCodes error: 激活码保存失败. error:{0}", ex.Message); return false; } // 将新增添加到保存队列 ExchangeSaveData saveData = new ExchangeSaveData() { type = 0, Config = Config }; // 开始tick保存 PlayerOpServerUtils.GetExchangeSvc().GetExchangeCodeManager().SetIsTick(true); return true; } public bool WriteCodeToFile(string fileName, List content) { string strContent = "CODE,GROUP"+"\r\n"; foreach (var item in content) { strContent = strContent + item + "\r\n"; } if (File.Exists(fileName)) { TraceLog.Error("ExchangeSvc.WriteCodeToFile error: file Exists fileName:{0}", fileName); return false; } try { File.WriteAllText(fileName, strContent); } catch (Exception ex) { TraceLog.Error("ExchangeSvc.WriteCodeToFile error: WriteAllText error : {0}", ex.Message); return false; } return true; } } }