6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) + game logic (GameFix/GameDAL/ServerData) + network layer (NetWorkMessage) + data layer (ObjectModel) + utilities (MrWu/Core/Config/CloudAPI/dll) + adapters (zyxAdapter/base) .NET 8.0 C# solution, 16 projects, 958 source files
880 lines
31 KiB
C#
880 lines
31 KiB
C#
/********************************
|
||
*
|
||
* 作者:吴隆健
|
||
* 创建时间: 2019/7/3 13:06:48
|
||
*
|
||
********************************/
|
||
|
||
using GameData;
|
||
using GameDAL.Game;
|
||
using MrWu.Debug;
|
||
using Server.DB.Redis;
|
||
using StackExchange.Redis;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Data;
|
||
using MrWu.Time;
|
||
using System.Threading;
|
||
using Server.Data;
|
||
using System.IO;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using Server.Core;
|
||
using Server.DB.Sql;
|
||
|
||
///// <summary>
|
||
///// 玩家数据管理
|
||
///// </summary>
|
||
namespace Server
|
||
{
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public class PlayerDataManager
|
||
{
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public static PlayerDataManager instance { get; private set; }
|
||
|
||
private PlayerDataManager()
|
||
{
|
||
}
|
||
|
||
static PlayerDataManager()
|
||
{
|
||
instance = new PlayerDataManager();
|
||
}
|
||
|
||
|
||
#region player redis 字段
|
||
|
||
/// <summary>
|
||
/// 玩家的userid 字段
|
||
/// </summary>
|
||
public const string useridField = "userid";
|
||
|
||
/// <summary>
|
||
/// 用户名
|
||
/// </summary>
|
||
public const string UserNameField = "UserName";
|
||
|
||
/// <summary>
|
||
/// 玩家昵称
|
||
/// </summary>
|
||
public const string nickNameField = "NickName";
|
||
|
||
/// <summary>
|
||
/// 数据版本
|
||
/// </summary>
|
||
public const string verField = "ver";
|
||
|
||
/// <summary>
|
||
/// 玩家金额字段
|
||
/// </summary>
|
||
public const string moneyField = "money";
|
||
|
||
/// <summary>
|
||
/// 游戏币变化字段
|
||
/// </summary>
|
||
public const string moneyChangeField = "moneyChange";
|
||
|
||
/// <summary>
|
||
/// 金币字段名
|
||
/// </summary>
|
||
public const string goldFiled = "Glod";
|
||
|
||
/// <summary>
|
||
/// 金币变化字段名
|
||
/// </summary>
|
||
public const string goldChangeField = "GlodChange";
|
||
|
||
/// <summary>
|
||
/// 性别字段名
|
||
/// </summary>
|
||
public const string sexField = "Sex";
|
||
|
||
/// <summary>
|
||
/// 地区字段
|
||
/// </summary>
|
||
public const string areaField = "Area";
|
||
|
||
/// <summary>
|
||
/// 经验字段
|
||
/// </summary>
|
||
public const string expField = "hjha_Exp";
|
||
|
||
/// <summary>
|
||
/// 经验变化字段
|
||
/// </summary>
|
||
public const string expChangeField = "expChange";
|
||
|
||
/// <summary>
|
||
/// 玩家的奖券字段
|
||
/// </summary>
|
||
public const string couponField = "coupon";
|
||
|
||
/// <summary>
|
||
/// 奖券变化字段名
|
||
/// </summary>
|
||
public const string couponChangeField = "couponChange";
|
||
|
||
/// <summary>
|
||
/// 房卡字段名
|
||
/// </summary>
|
||
public const string fangkaField = "fangka";
|
||
|
||
/// <summary>
|
||
/// 房卡变化字段名
|
||
/// </summary>
|
||
public const string FangKaChangeField = "fangkaChange";
|
||
|
||
/// <summary>
|
||
/// 用户类型
|
||
/// </summary>
|
||
public const string UserTypeField = "UserType";
|
||
|
||
/// <summary>
|
||
/// 代理字段
|
||
/// </summary>
|
||
public const string DailiField = "daili";
|
||
|
||
/// <summary>
|
||
/// 防沉迷字段
|
||
/// </summary>
|
||
public const string PiField = "pi";
|
||
|
||
/// <summary>
|
||
/// 比赛卷字段
|
||
/// </summary>
|
||
public const string MatchRollField = "mmnn";
|
||
|
||
/// <summary>
|
||
/// 比赛卷变化字段
|
||
/// </summary>
|
||
public const string MatchRollChangeField = "mmnnChange";
|
||
|
||
/// <summary>
|
||
/// 推广的标识
|
||
/// </summary>
|
||
public const string platTagField = "platTag";
|
||
|
||
/// <summary>
|
||
/// 用户头像对应的字段
|
||
/// </summary>
|
||
public const string HeadField = "hjha_LeagueId";
|
||
|
||
/// <summary>
|
||
/// 平台类型
|
||
/// </summary>
|
||
public const string PlatEnumField = "hjha_fy_Value";
|
||
|
||
/// <summary>
|
||
/// 在redis中的玩家列表
|
||
/// </summary>
|
||
public const string PlayerListKey = "Game:PlayerLRU:Players";
|
||
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// 获取玩家的数据的key
|
||
/// </summary>
|
||
/// <param name="userid"></param>
|
||
/// <returns></returns>
|
||
public static string GetKey(int userid)
|
||
{
|
||
return RedisPlayerDataKeyPrefix + userid;
|
||
}
|
||
|
||
/// <summary>
|
||
/// redis中玩家数据的key
|
||
/// </summary>
|
||
public const string RedisPlayerDataKeyPrefix = "Game:PlayerData:";
|
||
|
||
/// <summary>
|
||
/// 头像
|
||
/// </summary>
|
||
public const string AvatarFidle = "avatar";
|
||
|
||
/// <summary>
|
||
/// 从redis中加载玩家数据
|
||
/// </summary>
|
||
/// <param name="pl"></param>
|
||
/// <param name="cgdata">变化量</param>
|
||
/// <returns></returns>
|
||
public static int LoadRedisPlayerData(playerData pl, out PlayerDataChange cgdata)
|
||
{
|
||
var changeData = PlayerDataChange.Create(pl.userid);
|
||
cgdata = changeData;
|
||
//-1表示为加载到玩家
|
||
int result = -1;
|
||
|
||
string key = GetKey(pl.userid);
|
||
|
||
//临时变量
|
||
long tmplong;
|
||
int tmpint;
|
||
|
||
var fields = redisManager.db.HashGetAll(key);
|
||
|
||
if (fields == null) //redis 中没有玩家数据
|
||
return result;
|
||
|
||
foreach (var he in fields)
|
||
{
|
||
switch (he.Name)
|
||
{
|
||
case nickNameField:
|
||
pl.nickname = he.Value;
|
||
break;
|
||
case UserNameField:
|
||
pl.UserName = he.Value;
|
||
break;
|
||
case moneyField:
|
||
if (he.Value.TryParse(out tmplong))
|
||
{
|
||
pl.money = tmplong;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家游戏币数据竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case moneyChangeField:
|
||
if (he.Value.TryParse(out tmplong))
|
||
{
|
||
changeData.moneyChange = tmplong;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的游戏币变化值竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case goldFiled:
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
pl.gold = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的金币数据竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case goldChangeField:
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
changeData.goldChange = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的游戏币数据竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case sexField:
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
pl.sex = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的性别字段竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case areaField:
|
||
pl.area = he.Value;
|
||
break;
|
||
case expField:
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
pl.exp = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的经验字段竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case expChangeField:
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
changeData.expChange = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的经验字段竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case couponField:
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
pl.coupon = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的奖券字段竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case couponChangeField:
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
changeData.couponChange = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的奖券变化字段竟然不是数值 userid:{0} vlaue:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case fangkaField:
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
pl.fangka = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的房卡字段竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case FangKaChangeField:
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
changeData.fangkaChange = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的房卡变化值字段竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case UserTypeField:
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
pl.userType = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("asckjagbshdbashbsmbaxas :" + he.Value);
|
||
}
|
||
|
||
break;
|
||
case AvatarFidle:
|
||
pl.avatar = he.Value;
|
||
break;
|
||
case DailiField:
|
||
tmpint = 0;
|
||
if (he.Value.TryParse(out tmpint))
|
||
pl.daili = tmpint;
|
||
else
|
||
Debug.Error("错误错误,玩家代理字段竟然不是数值 userid{0} value{1}", pl.userid, he.Value);
|
||
break;
|
||
case PlatEnumField:
|
||
tmpint = 0;
|
||
if (he.Value.TryParse(out tmpint))
|
||
pl.PlatEnum = tmpint;
|
||
else
|
||
Debug.Error("错误错误,玩家代理字段竟然不是数值 userid{0} value{1}", pl.userid, he.Value);
|
||
break;
|
||
case PiField:
|
||
pl.pi = he.Value;
|
||
break;
|
||
case platTagField:
|
||
pl.platTag = he.Value;
|
||
break;
|
||
case HeadField:
|
||
tmpint = 0;
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
pl.HeadType = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的头像字段竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case MatchRollField:
|
||
tmpint = 0;
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
pl.MatchRoll = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的比赛卷字段竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case MatchRollChangeField:
|
||
if (he.Value.TryParse(out tmpint))
|
||
{
|
||
changeData.MatchRollChange = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("错误错误,玩家的比赛卷变化值字段竟然不是数值 userid:{0} value:{1}", pl.userid, he.Value);
|
||
}
|
||
|
||
break;
|
||
case "RegTime":
|
||
string temp = he.Value;
|
||
try
|
||
{
|
||
pl.RegTime = string.IsNullOrWhiteSpace(temp) ? default(DateTime) : Convert.ToDateTime(temp);
|
||
}
|
||
catch
|
||
{
|
||
pl.RegTime = default(DateTime);
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
PlayerFun.PlayerAddChangeData(pl, changeData);
|
||
result = 1;
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载玩家数据如果 sql中的ver 与 参数 ver 不一致 更新redis 以及 pl 原始数据 并添加版本ver信息
|
||
/// </summary>
|
||
//加载sql 数据 并更新 redis 数据
|
||
public static bool LoadSqlPlayerData(playerData pl, int ver, PlayerDataChange pdc)
|
||
{
|
||
int userid = pl.userid;
|
||
|
||
string key = GetKey(pl.userid);
|
||
|
||
DataSet ds = PlayerDB.ReadPlayerData(pl.userid, !string.IsNullOrEmpty(pl.pi));
|
||
|
||
if (ds.Tables == null || ds.Tables.Count < 1 || ds.Tables[0].Rows.Count <= 0)
|
||
{
|
||
//版本一致,数据取redis 原来的数据
|
||
|
||
return false; //redis 中的版本 与数据库中的版本一致 则有玩家, 版本不一致却没数据,表示没有这个用户
|
||
}
|
||
|
||
//读取玩家数据
|
||
DataTable gameTable = ds.Tables[0];
|
||
|
||
//昵称
|
||
string db_nickname;
|
||
//地区
|
||
string db_area;
|
||
//头像
|
||
string db_avatar; //头像
|
||
|
||
string db_userName;
|
||
//用户类型
|
||
int db_UserType;
|
||
//经验值
|
||
int db_exp;
|
||
//性别
|
||
int db_sex;
|
||
//游戏币
|
||
long db_money;
|
||
//奖券
|
||
int db_coupon = 0;
|
||
//房卡
|
||
int db_fangka;
|
||
//金币
|
||
int db_glod;
|
||
|
||
int db_daili = 0;
|
||
db_nickname = gameTable.Rows[0]["nickNameEm"] as string;
|
||
if (string.IsNullOrEmpty(db_nickname))
|
||
{
|
||
db_nickname = gameTable.Rows[0][nickNameField] as string;
|
||
}
|
||
|
||
db_userName = gameTable.Rows[0]["userName"] as string;
|
||
|
||
if (db_nickname == null)
|
||
db_nickname = string.Empty;
|
||
|
||
db_area = gameTable.Rows[0][areaField] as string;
|
||
if (db_area == null)
|
||
db_area = string.Empty;
|
||
db_sex = (int)gameTable.Rows[0][sexField];
|
||
db_money = (long)gameTable.Rows[0][moneyField];
|
||
db_exp = (int)gameTable.Rows[0][expField];
|
||
db_fangka = (int)gameTable.Rows[0]["xu"];
|
||
db_UserType = (int)gameTable.Rows[0][UserTypeField];
|
||
db_coupon = (int)gameTable.Rows[0][couponField];
|
||
db_avatar = gameTable.Rows[0][AvatarFidle] as string;
|
||
db_daili = (int)gameTable.Rows[0][DailiField];
|
||
var platEnum = (int)gameTable.Rows[0][PlatEnumField];
|
||
string pi = pl.pi;
|
||
if (string.IsNullOrEmpty(pl.pi))
|
||
{
|
||
pi = (gameTable.Rows[0][PiField] as string) ?? string.Empty;
|
||
}
|
||
|
||
string platTag = (gameTable.Rows[0][platTagField] as string) ?? string.Empty;
|
||
int matchRoll = (int)gameTable.Rows[0][MatchRollField];
|
||
int head = (int)gameTable.Rows[0][HeadField];
|
||
DateTime regTime = default(DateTime);
|
||
try
|
||
{
|
||
regTime = (DateTime)gameTable.Rows[0]["RegTime"];
|
||
}
|
||
catch
|
||
{
|
||
}
|
||
|
||
if (db_avatar == null)
|
||
db_avatar = string.Empty;
|
||
db_glod = (int)gameTable.Rows[0]["hjha_Gold"];
|
||
|
||
List<HashEntry> hes = new List<HashEntry>();
|
||
hes.Add(new HashEntry(useridField, userid));
|
||
hes.Add(new HashEntry(UserNameField,db_userName));
|
||
hes.Add(new HashEntry(nickNameField, db_nickname));
|
||
hes.Add(new HashEntry(moneyField, db_money));
|
||
hes.Add(new HashEntry(sexField, db_sex));
|
||
hes.Add(new HashEntry(areaField, db_area));
|
||
hes.Add(new HashEntry(expField, db_exp));
|
||
hes.Add(new HashEntry(couponField, db_coupon));
|
||
hes.Add(new HashEntry(fangkaField, db_fangka));
|
||
hes.Add(new HashEntry(UserTypeField, db_UserType.ToString()));
|
||
hes.Add(new HashEntry(AvatarFidle, db_avatar));
|
||
hes.Add(new HashEntry(goldFiled, db_glod));
|
||
hes.Add(new HashEntry(verField, ver));
|
||
hes.Add(new HashEntry(DailiField, db_daili));
|
||
hes.Add(new HashEntry(PiField, pi));
|
||
hes.Add(new HashEntry(platTagField, platTag));
|
||
hes.Add(new HashEntry("RegTime", regTime.ToString("yyyy-MM-dd HH:mm:ss")));
|
||
hes.Add(new HashEntry(MatchRollField, matchRoll));
|
||
hes.Add(new HashEntry(HeadField, head));
|
||
hes.Add(new HashEntry(PlatEnumField, platEnum));
|
||
|
||
//Debug.Info("设置玩家原始数据:" + userid + "," + db_money);
|
||
redisManager.db.HashSetAsync(key, hes.ToArray());
|
||
|
||
pl.nickname = db_nickname;
|
||
pl.UserName = db_userName;
|
||
pl.money = db_money;
|
||
pl.sex = db_sex;
|
||
pl.area = db_area;
|
||
pl.exp = db_exp;
|
||
pl.coupon = db_coupon;
|
||
pl.fangka = db_fangka;
|
||
pl.userType = db_UserType;
|
||
pl.avatar = db_avatar;
|
||
pl.gold = db_glod;
|
||
pl.daili = db_daili;
|
||
pl.pi = pi;
|
||
pl.PlatEnum = platEnum;
|
||
pl.MatchRoll = matchRoll;
|
||
pl.platTag = platTag;
|
||
pl.RegTime = regTime;
|
||
pl.HeadType = head;
|
||
if (pdc != null)
|
||
PlayerFun.PlayerAddChangeData(pl, pdc);
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 把玩家的变化数据清楚掉-和写sql一起使用, 原始数据+ 变化数据-
|
||
/// </summary>
|
||
/// <param name="pdc"></param>
|
||
/// <returns>是否存在改玩家</returns>
|
||
public static bool ClearRedisDataChange(PlayerDataChange pdc)
|
||
{
|
||
string key = GetKey(pdc.userid);
|
||
|
||
var tran = redisManager.GetDataBase().CreateTransaction();
|
||
tran.AddCondition(Condition.KeyExists(key));
|
||
if (pdc.moneyChange != 0)
|
||
{
|
||
tran.HashDecrementAsync(key, moneyChangeField, pdc.moneyChange);
|
||
tran.HashIncrementAsync(key, moneyField, pdc.moneyChange);
|
||
}
|
||
|
||
if (pdc.expChange != 0)
|
||
{
|
||
tran.HashDecrementAsync(key, expChangeField, pdc.expChange);
|
||
tran.HashIncrementAsync(key, expField, pdc.expChange);
|
||
}
|
||
|
||
if (pdc.fangkaChange != 0)
|
||
{
|
||
tran.HashDecrementAsync(key, FangKaChangeField, pdc.fangkaChange);
|
||
tran.HashIncrementAsync(key, fangkaField, pdc.fangkaChange);
|
||
}
|
||
|
||
if (pdc.goldChange != 0)
|
||
{
|
||
tran.HashDecrementAsync(key, goldChangeField, pdc.goldChange);
|
||
tran.HashIncrementAsync(key, goldFiled, pdc.goldChange);
|
||
}
|
||
|
||
if (pdc.couponChange != 0)
|
||
{
|
||
tran.HashDecrementAsync(key, couponChangeField, pdc.couponChange);
|
||
tran.HashIncrementAsync(key, couponField, pdc.couponChange);
|
||
}
|
||
|
||
if (pdc.MatchRollChange != 0)
|
||
{
|
||
tran.HashDecrementAsync(key, MatchRollChangeField, pdc.MatchRollChange);
|
||
tran.HashIncrementAsync(key, MatchRollField, pdc.MatchRollChange);
|
||
}
|
||
|
||
return tran.Execute();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 变化数据写入redis中
|
||
/// </summary>
|
||
/// <param name="pdc">玩家数据变化值</param>
|
||
/// <returns>是否存在这个玩家</returns>
|
||
public static bool WriteToRedis(PlayerDataChange pdc)
|
||
{
|
||
string key = GetKey(pdc.userid);
|
||
|
||
var tran = redisManager.GetDataBase().CreateTransaction();
|
||
|
||
if (pdc.moneyChange != 0)
|
||
tran.HashIncrementAsync(key, moneyChangeField, pdc.moneyChange);
|
||
if (pdc.expChange != 0)
|
||
tran.HashIncrementAsync(key, expChangeField, pdc.expChange);
|
||
if (pdc.goldChange != 0)
|
||
tran.HashIncrementAsync(key, goldChangeField, pdc.goldChange);
|
||
if (pdc.fangkaChange != 0)
|
||
tran.HashIncrementAsync(key, FangKaChangeField, pdc.fangkaChange);
|
||
if (pdc.couponChange != 0)
|
||
tran.HashIncrementAsync(key, couponChangeField, pdc.couponChange);
|
||
if (pdc.MatchRollChange != 0)
|
||
tran.HashIncrementAsync(key, MatchRollChangeField, pdc.MatchRollChange);
|
||
tran.AddCondition(Condition.KeyExists(key));
|
||
return tran.Execute();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载redis 中的变化的数据
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private static PlayerDataChange LoadRedisPlayerDataChange(int userid, bool isLock)
|
||
{
|
||
string key = GetKey(userid);
|
||
|
||
//加载redis 中变化的数据
|
||
var hes = redisManager.db.HashGetAll(key);
|
||
|
||
if (hes == null)
|
||
return null;
|
||
|
||
int tmpint;
|
||
long tmplong;
|
||
|
||
PlayerDataChange pdc =PlayerDataChange.Create(userid);
|
||
foreach (var item in hes)
|
||
{
|
||
switch (item.Name)
|
||
{
|
||
case moneyChangeField:
|
||
if (long.TryParse(item.Value, out tmplong))
|
||
{
|
||
pdc.moneyChange = tmplong;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("redis 中玩家的游戏币变化值不是数值userid:{0},value:{1}", userid, item.Value);
|
||
}
|
||
|
||
break;
|
||
case expChangeField:
|
||
if (int.TryParse(item.Value, out tmpint))
|
||
{
|
||
pdc.expChange = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("redis 中玩家的经验变化值不是数值userid:{0},value:{1}", userid, item.Value);
|
||
}
|
||
|
||
break;
|
||
case goldChangeField:
|
||
if (int.TryParse(item.Value, out tmpint))
|
||
{
|
||
pdc.goldChange = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("redis 中金币变化值不是数值userid:{0},value:{1}", userid, item.Value);
|
||
}
|
||
|
||
break;
|
||
case couponChangeField:
|
||
if (int.TryParse(item.Value, out tmpint))
|
||
{
|
||
pdc.couponChange = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("redis 中奖券变化值不是数值userid:{0},value:{1}", userid, item.Value);
|
||
}
|
||
|
||
break;
|
||
case FangKaChangeField:
|
||
if (int.TryParse(item.Value, out tmpint))
|
||
{
|
||
pdc.fangkaChange = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("redis 中房卡变化值不是数值userid:{0},value:{1}", userid, item.Value);
|
||
}
|
||
|
||
break;
|
||
case MatchRollChangeField:
|
||
if (int.TryParse(item.Value, out tmpint))
|
||
{
|
||
pdc.MatchRollChange = tmpint;
|
||
}
|
||
else
|
||
{
|
||
Debug.Error("redis 中比赛卷变化值不是数值userid:{0},value:{1}", userid, item.Value);
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
return pdc;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除玩家redis key
|
||
/// </summary>
|
||
/// <param name="userid"></param>
|
||
public static void DeletePlayReids(int userid)
|
||
{
|
||
redisManager.db.KeyDelete(GetKey(userid));
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 保存至sql数据库
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static bool SaveToSql(int userid)
|
||
{
|
||
PlayerDataChange pdc = LoadRedisPlayerDataChange(userid, false);
|
||
try
|
||
{
|
||
if (pdc != null && pdc.IsChanged)
|
||
{
|
||
//读取变化的数据
|
||
Debug.Info("保存玩家数据:" + pdc.userid + "," + pdc.moneyChange);
|
||
//先清楚redis, sql未保存成功 再手动回滚
|
||
if (!ClearRedisDataChange(pdc))
|
||
{
|
||
Debug.Error("数据竟然没有了,,,......玩家数据被穿透!!");
|
||
return false;
|
||
}
|
||
|
||
bool isOK = true;
|
||
try
|
||
{
|
||
isOK = PlayerDB.SavePlayerData(pdc);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.Error("保存玩家数据时出现错误:" + e.ToString());
|
||
isOK = false;
|
||
}
|
||
|
||
//写入要志
|
||
|
||
if (!isOK)
|
||
{
|
||
try
|
||
{
|
||
//获取相反值,回滚
|
||
PlayerDataChange pdc2 = pdc.GetOppositeValue(true);
|
||
ClearRedisDataChange(pdc2);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.Error($"回滚失败!错误错误!:{e.Message}\r\n" + pdc.ToString());
|
||
}
|
||
}
|
||
|
||
return isOK;
|
||
}
|
||
}finally
|
||
{
|
||
if (pdc != null)
|
||
{
|
||
ReferencePool.Recycle(pdc);
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
public Task<UserAccountInfo> GetUserAccountInfoAsync(int userid)
|
||
{
|
||
return Task.Run(() => GetUserAccountInfo(userid));
|
||
}
|
||
|
||
public UserAccountInfo GetUserAccountInfo(int userid)
|
||
{
|
||
var dt =GameDB.Instance.selectDb(dbbase.gamedb,"tbUserBaseInfo",new string[]{"UserName","NickName","nickNameEm"},$"userid={userid}");
|
||
if (dt.Rows.Count == 1)
|
||
{
|
||
var row = dt.Rows[0];
|
||
UserAccountInfo info = new UserAccountInfo();
|
||
info.UserId = userid;
|
||
var userName = Convert.ToString(row["UserName"]);
|
||
var nickName = Convert.ToString(row["NickName"]);
|
||
var nickNameEm = Convert.ToString(row["nickNameEm"]);
|
||
info.UserName = userName;
|
||
info.NickName = string.IsNullOrEmpty(nickNameEm) ? nickName : nickNameEm;
|
||
return info;
|
||
}
|
||
else
|
||
{
|
||
if (dt.Rows.Count < 1)
|
||
{
|
||
Debug.Error($"GetUserAccountInfo 未找到用户 {userid}");
|
||
}
|
||
else
|
||
{
|
||
Debug.Error($"GetUserAccountInfo 多条数据 userid={userid}");
|
||
}
|
||
return null;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 用户信息
|
||
/// </summary>
|
||
public class UserAccountInfo
|
||
{
|
||
/// <summary>
|
||
/// UserId
|
||
/// </summary>
|
||
public int UserId;
|
||
/// <summary>
|
||
/// 用户名
|
||
/// </summary>
|
||
public string UserName;
|
||
/// <summary>
|
||
/// 昵称
|
||
/// </summary>
|
||
public string NickName;
|
||
}
|
||
} |