using Sog; using System; using System.Collections.Generic; using ProtoCSStruct; using System.Linq; using StackExchange.Redis; namespace DB { public partial class RedisDBOperator : DBOperator { public RedisDB m_redisDB; public RedisDBOperator(string dbname, string ip, string user, string password) { m_redisDB = new RedisDB(dbname, ip, password); } public override void Dispose() { if (m_redisDB != null) { m_redisDB.Dispose(); m_redisDB = null; } } public override void KeepAlive() { var latency = m_redisDB.Ping(); TraceLog.Trace("RedisDBOperator.KeepAlive exec at {0} latency {1}ms", DateTime.Now, latency.Milliseconds); } //================================================================================ tbaccount private string GetAccount_StringKey(int accountType, string accountID) { return m_redisDB.CreateKey("string:tbaccount:account", accountType.ToString(), accountID); } public override tbAccount QueryAccount(int accountType, string accountID) { TraceLog.Trace("RedisDBOperator.QueryAccount type {0} accountid {1}", accountType, accountID); return m_redisDB.StringGet(GetAccount_StringKey(accountType, accountID)); } public override bool UpdateAccountLastLoginRealm(int accountType, string accountID, tbAccount accountRecord, int lastLoginRealm) { accountRecord.LastLoginRealm = lastLoginRealm; bool ret = m_redisDB.StringSet(GetAccount_StringKey(accountType, accountID), accountRecord); if (ret) { TraceLog.Trace("RedisDBOperator.UpdateAccountLastLoginRealm type {0} accountid {1} succ", accountType, accountID); } else { TraceLog.Error("RedisDBOperator.UpdateAccountLastLoginRealm type {0} accountid {1} fail", accountType, accountID); } return ret; } public override bool UpdateAccountGrade(int accountType, string accountID, tbAccount accountRecord, int Grade) { accountRecord.Grade = Grade; bool ret = m_redisDB.StringSet(GetAccount_StringKey(accountType, accountID), accountRecord); if (ret) { TraceLog.Trace("RedisDBOperator.UpdateAccountComment type {0} accountid {1} succ", accountType, accountID); } else { TraceLog.Error("RedisDBOperator.UpdateAccountComment type {0} accountid {1} fail", accountType, accountID); } return ret; } public override bool UpdateAccountExData(int accountType, string accountID, tbAccount accountRecord, ref DBAccountExData exdata) { accountRecord.exData = StructMessageParseUtils.ToByteArray(ref exdata); bool ret = m_redisDB.StringSet(GetAccount_StringKey(accountType, accountID), accountRecord); if (ret) { TraceLog.Trace("RedisDBOperator.UpdateAccountExData type {0} accountid {1} succ", accountType, accountID); } else { TraceLog.Error("RedisDBOperator.UpdateAccountExData type {0} accountid {1} fail", accountType, accountID); } return ret; } public override bool InsertAccount(int accountType, string accountID, string accountToken, long createTime, string deviceId, uint ipAddr, string nick, int gender, string icon, int grade, ref DBAccountExData exData) { var accountRecord = new tbAccount { AccountType = accountType, AccountID = accountID, AccountToken = accountToken, CreateTime = createTime, CreateDeviceID = deviceId, CreateIpAddr = ipAddr, Nick = nick, Gender = gender, Icon = icon, Grade = grade, exData = StructMessageParseUtils.ToByteArray(ref exData), }; bool result = m_redisDB.StringSet(GetAccount_StringKey(accountType, accountID), accountRecord); if (result) { TraceLog.Trace("RedisDBOperator.InsertAccount type {0} accountid {1} succ", accountType, accountID); } else { TraceLog.Error("RedisDBOperator.InsertAccount type {0} accountid {1} fail", accountType, accountID); } return result; } //================================================================================ tbuid private string GetUid_StringKey(int accountTableIndex) { return m_redisDB.CreateKey("string:tbuid:account", accountTableIndex.ToString()); } private bool GetLastGameId(int accountTableIndex, out long lastUid) { lastUid = 0; string uidStr = m_redisDB.StringGet(GetUid_StringKey(accountTableIndex)); if (string.IsNullOrEmpty(uidStr)) { return false; } lastUid = long.Parse(uidStr); return true; } private bool SetNewGameId(int accountTableIndex, long newUid) { if (!m_redisDB.StringSet(GetUid_StringKey(accountTableIndex), newUid.ToString())) { TraceLog.Error("RedisDBOperator.SetnewUid insert to tbuid failed, subIndex {0}", accountTableIndex); return false; } return true; } public override long GenNewGameID(int accountTableIndex) { long newUid = 0; string lastUidStr = m_redisDB.StringGet(GetUid_StringKey(accountTableIndex)); if (string.IsNullOrEmpty(lastUidStr)) { newUid = 100000 + accountTableIndex; } else { var lastUid = long.Parse(lastUidStr); newUid = lastUid + TableIndexCalc.AccountTableCount; } if (!m_redisDB.StringSet(GetUid_StringKey(accountTableIndex), newUid.ToString())) { TraceLog.Error("RedisDBOperator.GenNewGameID insert to tbuid failed, subIndex {0}", accountTableIndex); return 0; } TraceLog.Trace("RedisDBOperator.GenNewGameID update tbuid {0} succ", newUid); return newUid; } //================================================================================ tbacc_realmuid_link // ["tbacc_realmuid_link:UID{0}"] = tbacc_realmuid_link private string GetUid2AccRealmuidLink_StringKey(T uid) { return m_redisDB.CreateKey("string:tbacc_realmuid_link:uid", uid.ToString()); } // ["tbacc_realmuid_link:{0}:{1}"] = [realmId] = uid // todo : u2一个区只有一个uid 可以这样,其他游戏多角色可以改数组 private string GetAccRealmuidLink_HashKey(int accountType, string accountID) { return m_redisDB.CreateKey("hash:tbacc_realmuid_link:account", accountType.ToString(), accountID); } public override List QueryAccountUid(int accountType, string accountID, int realmId) { if (realmId == 0) { return QueryAccountUidAll(accountType, accountID); } else { return QueryAccountUidOneRealm(accountType, accountID, realmId); } } private List QueryAccountUidAll(int accountType, string accountID) { TraceLog.Trace("RedisDBOperator.QueryAccountUidAll accountType {0} accountId {1}", accountType, accountID); List accountUids = new List(); var realmToUids = m_redisDB.HashGetAll(GetAccRealmuidLink_HashKey(accountType, accountID)); foreach (var item in realmToUids) { var tmp = m_redisDB.StringGet(GetUid2AccRealmuidLink_StringKey(item.Value)); if (tmp == null) { TraceLog.Error("RedisDBOperator.QueryAccountUidAll accountType {0} accountID {1} realmId {2} uid {3} fail" , accountType, accountID, item.Name, item.Value); continue; } accountUids.Add(tmp); } return accountUids; } private List QueryAccountUidOneRealm(int accountType, string accountID, int realmId) { TraceLog.Trace("RedisDBOperator.QueryAccountUidOneRealm accountType {0} accountId {1} realmId {2}", accountType, accountID, realmId); var uidStr = (string)m_redisDB.HashGet(GetAccRealmuidLink_HashKey(accountType, accountID), realmId.ToString()); if (uidStr == null) { TraceLog.Error("RedisDBOperator.QueryAccountUid accountType {0} accountID {1} realmId {2} fail" , accountType, accountID, realmId); return null; } var tmp = m_redisDB.StringGet(GetUid2AccRealmuidLink_StringKey(uidStr)); if (tmp == null) { TraceLog.Error("RedisDBOperator.QueryAccountUidAll accountType {0} accountID {1} realmId {2} uid {3} fail" , accountType, accountID, realmId, uidStr); return null; } return new List { tmp }; } public override bool InsertAccRealmUidLink(int accountType, string accountId, int realmId, long uid) { long lNow = DBServerUtils.GetTimeSecond(); tbacc_realmuid_link accountData = new tbacc_realmuid_link { accountType = accountType, accountId = accountId, realmId = realmId, uid = uid, lastLoginTime = lNow }; bool resStr = m_redisDB.StringSet(GetUid2AccRealmuidLink_StringKey(uid), accountData); if (!resStr) { TraceLog.Error("RedisDBOperator.InsertAccRealmUidLink type {0} accountid {1} realm {2} uid {3} fail" , accountType, accountId, realmId, uid); return false; } bool resHash = m_redisDB.HashSet(GetAccRealmuidLink_HashKey(accountType, accountId), realmId.ToString(), uid); if (!resHash) { TraceLog.Error("RedisDBOperator.InsertAccRealmUidLink type {0} accountid {1} realm {2} uid {3} fail" , accountType, accountId, realmId, uid); return false; } TraceLog.Trace("RedisDBOperator.InsertAccRealmUidLink type {0} accountid {1} realm {2} uid {3} succ" , accountType, accountId, realmId, uid); return true; } public override bool UpdateAccRealmUidLink(int accountType, string accountID, ref CSRoleBrief roleBrief) { long uid = roleBrief.Uid; string Nick = roleBrief.Nick.GetString(); string Icon = roleBrief.Icon.GetString(); int Level = roleBrief.Level; int IconFramId = roleBrief.IconFrameId; long lastLoginTime = roleBrief.LastLoginTime; var realmToUids = m_redisDB.HashGetAll(GetAccRealmuidLink_HashKey(accountType, accountID)); foreach (var item in realmToUids) { if (long.Parse(item.Value) == uid) { var record = m_redisDB.StringGet(GetUid2AccRealmuidLink_StringKey(uid)); if (record == null) { TraceLog.Error("RedisDBOperator.UpdateAccRealmUidLink type {0} accountid {1} uid {2} no record", accountType, accountID, uid); return false; } record.nick = Nick; record.icon = Icon; record.level = Level; record.iconFrameId = IconFramId; record.lastLoginTime = lastLoginTime; var res = m_redisDB.StringSet(GetUid2AccRealmuidLink_StringKey(uid), record); if (! res) { TraceLog.Error("RedisDBOperator.UpdateAccRealmUidLink type {0} accountid {1} fail" , accountType, accountID); return false; } TraceLog.Trace("RedisDBOperator.UpdateAccRealmUidLink type {0} accountid {1} succ", accountType, accountID); return true; } } return false; } public override bool UpdateAccRealmLinkUid(int accountType, string accountID, int realmId, long newUid) { var oldUid = m_redisDB.HashGet(GetAccRealmuidLink_HashKey(accountType, accountID), realmId.ToString()); if (oldUid == 0) { TraceLog.Error("RedisDBOperator.UpdateAccRealmUidLink type {0} accountid {1} get realm_uid fail", accountType, accountID); return false; } if (oldUid == newUid) { return true; } var accountUidInfo = m_redisDB.StringGet(GetUid2AccRealmuidLink_StringKey(oldUid)); if (accountUidInfo == null) { TraceLog.Error("RedisDBOperator.UpdateAccRealmUidLink type {0} accountid {1} add newUid fail", accountType, accountID); return false; } accountUidInfo.uid = newUid; var resAdd = m_redisDB.StringSet(GetUid2AccRealmuidLink_StringKey(newUid), accountUidInfo); if (!resAdd) { TraceLog.Error("RedisDBOperator.UpdateAccRealmUidLink type {0} accountid {1} add newUid fail", accountType, accountID); return false; } var resHashAdd = m_redisDB.HashSet(GetAccRealmuidLink_HashKey(accountType, accountID), realmId.ToString(), newUid); if (!resHashAdd) { TraceLog.Error("RedisDBOperator.UpdateAccRealmUidLink type {0} accountid {1} realmId {2} add newUid {3} hash fail", accountType, accountID, realmId, newUid); return false; } bool delOldStr = m_redisDB.KeyDelete(GetUid2AccRealmuidLink_StringKey(oldUid)); if (!delOldStr) { TraceLog.Error("RedisDBOperator.UpdateAccRealmUidLink type {0} accountid {1} realm {2} uid {3} del olduid fail" , accountType, accountID, realmId, newUid); } TraceLog.Trace("RedisDBOperator.UpdateAccRealmLinkUid type {0} accountid {1} new uid {2} succ" , accountType, accountID, newUid); return true; } public override void QueryRealmUidData(int realmId, ref SSQueryRealmUidDataRes res) { //todo 支持redis res.Ret = 0; res.RealmId = realmId; } public override int SaveRealmUidData(ref SSSaveRealmUidDataReq req) { //todo 支持redis return 0; } public override void QueryRealmDBData(ref SSRealmDBQueryRes res) { TraceLog.Trace("RedisDBOperator.QueryRealmDBData All realm"); res.Ret = 0; } public override int UpdateRealmPlayerNum(int realmId, int regNum) { return 0; } public override int UpdateRealmDBData(ref SSRealmDBSaveReq req, ref SSRealmDBSaveRes res) { return 0; } //public override bool UpdateAccRealmUidLinkLogoutTime(int accountType, string accountID, // int realmId, long uid, int lastLogoutTime) //{ // var record = m_redisDB.StringGet(GetUid2AccRealmuidLink_StringKey(uid)); // if (record == null) // { // TraceLog.Error("RedisDBOperator.UpdateAccRealmUidLinkLogoutTime uid {0} no record", uid); // return false; // } // record.lastLogoutTime = lastLogoutTime; // var res = m_redisDB.StringSet(GetUid2AccRealmuidLink_StringKey(uid), record); // if (! res) // { // TraceLog.Error("RedisDBOperator.UpdateAccRealmUidLinkLogoutTime uid {0} fail", uid); // return false; // } // TraceLog.Trace("RedisDBOperator.UpdateAccRealmUidLinkLogoutTime uid {0} lastLogoutTime {1} succ", uid, lastLogoutTime); // return true; //} public override tbacc_realmuid_link QueryAccountUidbyUid(int uid, int realmId) { var accountUidInfo = m_redisDB.StringGet(GetUid2AccRealmuidLink_StringKey(uid)); if (accountUidInfo == null) { TraceLog.Error("RedisDBOperator.QueryAccountUidbyUid uid {0} fail", uid); return null; } return accountUidInfo; } //================================================================================ tbpay private string GetPay_OrderId_StringKey(string orderId) { return m_redisDB.CreateKey("string:tbpay:orderId", orderId); } private string GetPay_uidStatus2OrderId_ListKey(long uid, int status = 1) { return m_redisDB.CreateKey("list:tbpay:uidStatus2OrderId", uid.ToString(), status.ToString()); } private void Delete_UidStatus2OrderId_List(long uid, int status, string orderId) { if (status != 1) { return; } var removeCount = m_redisDB.ListRemove(GetPay_uidStatus2OrderId_ListKey(uid, status), orderId); TraceLog.Debug("RedisDBOperator.Delete_UidStatus2OrderId_List delete list uid {0} status {1} orderId {2} removeCount {3}", uid, status, orderId, removeCount); } private void Insert_UidStatus2OrderId_List(long uid, int status, string orderId) { if (status != 1) { return; } m_redisDB.ListLeftPush(GetPay_uidStatus2OrderId_ListKey(uid, status), orderId); TraceLog.Debug("RedisDBOperator.Insert_UidStatus2OrderId_List insert list uid {0} status {1} orderId {2}", uid, status, orderId); } private void UpdatePay_UidStatus2OrderId_List(tbpay record, int oldStatus) { if (oldStatus == record.Status) { return; } Delete_UidStatus2OrderId_List(record.Uid, oldStatus, record.OrderID); Insert_UidStatus2OrderId_List(record.Uid, record.Status, record.OrderID); } private bool InsertPay(tbpay record) { Insert_UidStatus2OrderId_List(record.Uid, record.Status, record.OrderID); bool ret = m_redisDB.StringSet(GetPay_OrderId_StringKey(record.OrderID), record); if (!ret) { return false; } return true; } public override bool InsertPayReq(ref SSPayGoogleReq payReq) { tbpay record = new tbpay() { OrderID = payReq.OrderId.GetString(), PayType = payReq.PayType, ProductID = payReq.ItemID, PayTime3rd = DBServerUtils.GetTimeSecond(), Uid = payReq.Uid, Money = payReq.Money }; if (!InsertPay(record)) { TraceLog.Error("RedisDBOperator.InsertPayReq uid {0} orderid {1} insert fail", payReq.Uid, payReq.OrderId); return false; } return true; } public override tbpay SelectPayRecord(long uid, string orderId) { tbpay tbRecord = m_redisDB.StringGet(GetPay_OrderId_StringKey(orderId)); if (tbRecord == null) { TraceLog.Error("RedisDBOperator.SelectPayRecord no record orderid {0}", orderId); return null; } TraceLog.Trace("RedisDBOperator.SelectPayRecord query success uid {0} status {1} money {2} payType {3} orderId3rd {4} isTestPay {5}" , tbRecord.Uid, tbRecord.Status, tbRecord.Money, tbRecord.PayType , tbRecord.OrderId3rd, tbRecord.IsTestPay); return tbRecord; } public override List SelectPaySuccRecord(long uid) { // 以防万一, 只返回前10条记录, 应该不会出现连充10笔订单没有到账还继续充的人吧 var payList = m_redisDB.ListRange(GetPay_uidStatus2OrderId_ListKey(uid, 1), 0, 10); if (payList.Count() <= 0) { return null; } var resultList = new List(); foreach (var orderId in payList) { var record = m_redisDB.StringGet(GetPay_OrderId_StringKey(orderId)); if (record == null) { TraceLog.Error("RedisDBOperator.SelectPaySuccRecord get orderId {0} fail!", orderId); continue; } resultList.Add(record); } return resultList; } public override tbpay SelectPayRecordByOrderId3rd(long uid, string orderId3rd) { throw new NotImplementedException(); } public override bool UpdatePayProductId(long uid, string orderId, int productId) { return false; } public override bool UpdatePayStatus(long uid, string orderId, int newStatus, uint amountExchange, uint diamondExchange, int newItemId, uint money) { tbpay pay = m_redisDB.StringGet(GetPay_OrderId_StringKey(orderId)); if (pay == null) { return false; } int oldStatus = pay.Status; pay.Status = newStatus; pay.AmountExchange = amountExchange; pay.DiamondExchange = diamondExchange; pay.Money = money; if (newItemId != 0) { pay.ProductID = newItemId; } UpdatePay_UidStatus2OrderId_List(pay, oldStatus); bool ret = m_redisDB.StringSet(GetPay_OrderId_StringKey(orderId), pay); if (!ret) { TraceLog.Error("RedisDBOperator.UpdatePayStatus uid {0} orderid {1} insert fail", uid, orderId); return false; } TraceLog.Debug("RedisDBOperator.UpdatePayStatus orderid {0} status {1} to table success", orderId, newStatus); return true; } public override bool UpdatePayStatus(long uid, string orderId, int newStatus, string orderId3rd, long lTime, uint amount, bool isTestPay, string currency, int subPayType) { tbpay record = m_redisDB.StringGet(GetPay_OrderId_StringKey(orderId)); if (record == null) { return false; } int oldStatus = record.Status; record.Status = newStatus; record.PayTime3rd = lTime; record.Amount = amount; record.IsTestPay = (isTestPay ? 1 : 0); record.OrderId3rd = orderId3rd; record.Currency = currency; record.SubPayType = subPayType; UpdatePay_UidStatus2OrderId_List(record, oldStatus); bool ret = m_redisDB.StringSet(GetPay_OrderId_StringKey(orderId), record); if (!ret) { TraceLog.Error("RedisDBOperator.UpdatePayStatus newStatus {0} orderid {1} insert fail", newStatus, orderId); return false; } TraceLog.Debug("RedisDBOperator.UpdatePayStatus orderid {0} status {1} to table success", orderId, newStatus); return true; } public override bool SetRefundTime(long uid, string orderId, string orderId3rd, long refundTime) { tbpay tbRecord = m_redisDB.StringGet(GetPay_OrderId_StringKey(orderId)); if (tbRecord == null) { TraceLog.Error("RedisDBOperator.SetRefundTime no record orderid {0}", orderId); return false; } if (tbRecord.OrderId3rd != orderId3rd) { TraceLog.Error("RedisDBOperator.SetRefundTime record orderId3rd not equal orderId {0} orderId3rd {1}", orderId, orderId3rd); return false; } tbRecord.RefundTime = refundTime; bool ret = m_redisDB.StringSet(GetPay_OrderId_StringKey(orderId), tbRecord); if (!ret) { TraceLog.Error("RedisDBOperator.SetRefundTime orderid {1} fail", orderId); return false; } TraceLog.Trace("RedisDBOperator.SetRefundTime orderid {0} success", orderId); return true; } public override Tuple> SelectAllPayRecords(SSGmQueryUserPayRecordReq req) { throw new NotImplementedException(); } //================================================================================ tbpay_http private string GetPayHttp_StringKey(string orderId) { return m_redisDB.CreateKey("string:tbpay_http:orderId", orderId); } private string GetPayHttp_ListKey() { return m_redisDB.CreateKey("list:tbpay_http"); } public override bool ReplacePayHttpContent(ref SSPayHeroSaveHttpContentReq req) { string orderId = req.Http.OrderId.GetString(); tbpay_http patHttp = new tbpay_http { OrderId = orderId, Uid = req.Http.Uid, IsTestPay = req.Http.IsTestPay, Method = req.Http.Method, Url = req.Http.Url.GetString(), Content = req.Http.Content.GetString(), }; bool setResult = m_redisDB.StringSet(GetPayHttp_StringKey(orderId), patHttp); if (!setResult) { TraceLog.Error("RedisDBOperator.ReplacePayHttpContent orderId {0} ret {1}", orderId, setResult); return false; } TraceLog.Trace("RedisDBOperator.ReplacePayHttpContent orderId {0} ret {1}", orderId, setResult); // 尝试移除list中的订单查找表 try { m_redisDB.ListRemove(GetPayHttp_ListKey(), orderId, 1); m_redisDB.ListLeftPush(GetPayHttp_ListKey(), orderId); } catch (Exception ex) { TraceLog.Exception(ex); TraceLog.Exception(ex.InnerException); } return true; } public override void SelectPayHttpContent(ref SSPayHeroSelectHttpContentRes res) { var orders = m_redisDB.ListRange(GetPayHttp_ListKey(), 0, 10); if (orders.Count() <= 0) { return; } foreach (var orderId in orders) { var payHttp = m_redisDB.StringGet(GetPayHttp_StringKey(orderId)); if (payHttp == null) { TraceLog.Error("RedisDBOperator.SelectPayHttpContent get orderId {0} fail!", orderId); continue; } var http = new SSHttpRequest(); http.Method = payHttp.Method; http.IsTestPay = payHttp.IsTestPay; http.Uid = payHttp.Uid; http.OrderId.SetString(orderId); http.Url.SetString(payHttp.Url); http.Content.SetString(payHttp.Content); res.Http.Add(ref http); TraceLog.Trace("RedisDBOperator.SelectPayHttpContent orderId {0}", orderId); } } public override void DeletePayHttpContent(ref SSPayHeroDeleteHttpContentNotify notify) { string orderId = notify.OrderId.GetString(); bool ret = m_redisDB.KeyDelete(GetPayHttp_StringKey(orderId)); var rm = m_redisDB.ListRemove(GetPayHttp_ListKey(), orderId); if (!ret) { TraceLog.Error("RedisDBOperator.DeletePayHttpContent orderId {0} ret {1} rm list {2}", orderId, ret, rm); } else { TraceLog.Debug("RedisDBOperator.DeletePayHttpContent orderId {0} ret {1} rm list {2}", orderId, ret, rm); } } } }