修改玩游戏逻辑

This commit is contained in:
zpc 2024-12-01 05:33:07 +08:00
parent 84b0beda2b
commit 5381ffe387
11 changed files with 452 additions and 151 deletions

View File

@ -135,7 +135,7 @@ public class PlayGameController : CloudGamingControllerBase
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
[Authorize] [Authorize]
public async Task<GameListDto> GetMyScListAsync([FromBody] RequestBaseModel requestBaseModel) public async Task<PlayGameInfoDto> GetMyScListAsync([FromBody] RequestBaseModel requestBaseModel)
{ {
PlayGameBLL playGameBLL = new PlayGameBLL(ServiceProvider, JYApi); PlayGameBLL playGameBLL = new PlayGameBLL(ServiceProvider, JYApi);
return await playGameBLL.GetMyScList(requestBaseModel.Sn); return await playGameBLL.GetMyScList(requestBaseModel.Sn);

View File

@ -2,6 +2,12 @@
# 此阶段用于在快速模式(默认为调试配置)下从 VS 运行时 # 此阶段用于在快速模式(默认为调试配置)下从 VS 运行时
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
# 设置时区为北京时间
RUN apt-get update && apt-get install -y tzdata && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone && \
dpkg-reconfigure -f noninteractive tzdata && \
apt-get clean && rm -rf /var/lib/apt/lists/*
USER $APP_UID USER $APP_UID
WORKDIR /app WORKDIR /app
EXPOSE 80 EXPOSE 80

View File

@ -2,6 +2,13 @@
# 此阶段用于在快速模式(默认为调试配置)下从 VS 运行时 # 此阶段用于在快速模式(默认为调试配置)下从 VS 运行时
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
# 设置时区为北京时间
RUN apt-get update && apt-get install -y tzdata && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone && \
dpkg-reconfigure -f noninteractive tzdata && \
apt-get clean && rm -rf /var/lib/apt/lists/*
USER $APP_UID USER $APP_UID
WORKDIR /app WORKDIR /app
EXPOSE 80 EXPOSE 80

View File

@ -338,7 +338,7 @@ namespace CloudGaming.Code.Game
{ {
//计算用户排名看看是否进入前50名 //计算用户排名看看是否进入前50名
var userIndex = list.FindIndex(it => it.UserId == _UserId); var userIndex = list.FindIndex(it => it.UserId == _UserId);
userGamePlayTimeDto.PlayTime = $"{(userGame.PlayTime / 60).ToString("0.##")}小时"; userGamePlayTimeDto.PlayTime = $"{(userGame.PlayTime / 60.0).ToString("0.##")}小时";
if (userIndex > -1) if (userIndex > -1)
{ {
userGamePlayTimeDto.Ranking = userIndex + 1; userGamePlayTimeDto.Ranking = userIndex + 1;

View File

@ -253,10 +253,15 @@ public class PlayGameBLL : CloudGamingBase
var (issuccess, currlogId, diamId) = await this.UserPlayGameDiamondConsumeMoney(-gameDiamondNumHour, gameInfoCache.GameName, gameInfoCache.CurrencyLogId, gameInfoCache.DiamondListId, $"{diamondNumHour}/分钟"); var (issuccess, currlogId, diamId) = await this.UserPlayGameDiamondConsumeMoney(-gameDiamondNumHour, gameInfoCache.GameName, gameInfoCache.CurrencyLogId, gameInfoCache.DiamondListId, $"{diamondNumHour}/分钟");
if (!issuccess) if (!issuccess)
{ {
gameInfoCache.GameUserOperation.Add(new PlayGameUserOperation()
{
ActionId = (int)PlayGameStatus.,
Content = $"扣除费用{gameDiamondNumHour},用户剩余金额{userInfo.Diamond}"
});
await gameInfoCache.SaveChangesAsync(this);
throw MessageBox.ErrorShow("扣款出现错误"); throw MessageBox.ErrorShow("扣款出现错误");
} }
//userInfo gameInfoCache.SpendingDiamonds += gameDiamondNumHour;
//var userPlayGameTime = await Dao.DaoPhone.Context.T_User_PlayGameTime.Where(it => it.UserId == userId).SumAsync(it => (int?)it.PlayTime);
userInfo.UserPlayGameTime += minutes; userInfo.UserPlayGameTime += minutes;
await this.SaveUserInfoCacheChangesAsync(); await this.SaveUserInfoCacheChangesAsync();
gameInfoCache.CurrencyLogId = currlogId; gameInfoCache.CurrencyLogId = currlogId;
@ -280,7 +285,8 @@ public class PlayGameBLL : CloudGamingBase
//重置一下用户钻石 //重置一下用户钻石
playGameHeartbeatResponse.Diamond = userInfo.Diamond; playGameHeartbeatResponse.Diamond = userInfo.Diamond;
gameInfoCache.PlayGameHeartbeat();
gameInfoCache.PlayGameHeartbeat($";累计扣除钻石*{gameInfoCache.SpendingDiamonds};当前游戏每分钟消耗钻石*{playGameHeartbeatResponse.GameConsumeDiamond}");
await gameInfoCache.SaveChangesAsync(this); await gameInfoCache.SaveChangesAsync(this);
} }
else else
@ -296,7 +302,7 @@ public class PlayGameBLL : CloudGamingBase
/// <summary> /// <summary>
/// 游戏结束 /// 用户主动结束游戏
/// </summary> /// </summary>
/// <param name="gameId"></param> /// <param name="gameId"></param>
/// <returns></returns> /// <returns></returns>
@ -319,9 +325,9 @@ public class PlayGameBLL : CloudGamingBase
PlayGameUserInfo gameInfoCache = await PlayGameExtend.GetPlayGameUserInfoOrNull(this, userInfo, gameInfo); PlayGameUserInfo gameInfoCache = await PlayGameExtend.GetPlayGameUserInfoOrNull(this, userInfo, gameInfo);
if (gameInfoCache == null) if (gameInfoCache == null)
{ {
throw MessageBox.ErrorShow("未找到游戏信息"); return new BaseResponse<bool>(ResponseCode.Success, "游戏已结束", true);
} }
if (gameInfoCache.GameStatus != PlayGameStatus.) if (gameInfoCache.GameStatus != PlayGameStatus.)
{ {
PlayGameCommonSetting playGameQueue = new PlayGameCommonSetting() PlayGameCommonSetting playGameQueue = new PlayGameCommonSetting()
{ {
@ -389,7 +395,7 @@ public class PlayGameBLL : CloudGamingBase
} }
else else
{ {
gameInfoCache.PlayGameError(paidui); gameInfoCache.PlayGameQueueError(paidui);
back = new BaseResponse<PlayQueueInfoModel>(ResponseCode.Error, "排队出现错误", paidui.Data); back = new BaseResponse<PlayQueueInfoModel>(ResponseCode.Error, "排队出现错误", paidui.Data);
} }
@ -483,11 +489,13 @@ public class PlayGameBLL : CloudGamingBase
if (response.IsSuccess) if (response.IsSuccess)
{ {
gameInfoCache.DisplayGrade = displayGrade; gameInfoCache.DisplayGrade = displayGrade;
gameInfoCache.UserSwitchDisplayGrade(displayGrade, response);
await gameInfoCache.SaveChangesAsync(this); await gameInfoCache.SaveChangesAsync(this);
} }
else else
{ {
gameInfoCache.UserSwitchDisplayGradeError(displayGrade, response);
await gameInfoCache.SaveChangesAsync(this);
throw MessageBox.ErrorShow("切换失败"); throw MessageBox.ErrorShow("切换失败");
} }
return new BaseResponse<object>(ResponseCode.Success, "", response.Data); return new BaseResponse<object>(ResponseCode.Success, "", response.Data);
@ -499,7 +507,7 @@ public class PlayGameBLL : CloudGamingBase
/// </summary> /// </summary>
/// <param name="sn"></param> /// <param name="sn"></param>
/// <returns></returns> /// <returns></returns>
public async Task<GameListDto> GetMyScList(string sn) public async Task<PlayGameInfoDto> GetMyScList(string sn)
{ {
var requestParmat = new JYRequestParameter(sn, _UserId); var requestParmat = new JYRequestParameter(sn, _UserId);
var response = await JYApi.MyScList(requestParmat); var response = await JYApi.MyScList(requestParmat);
@ -510,14 +518,15 @@ public class PlayGameBLL : CloudGamingBase
var sess = response.Data?.List[0]; var sess = response.Data?.List[0];
if (sess != null) if (sess != null)
{ {
var gameInfo = await PlayGameExtend.PlayGameRecon(this, _UserId, sess.ScId); //sess.RestTime
var gameInfo = await PlayGameExtend.PlayGameRecon(this, _UserId, sess.ScId, response);
if (gameInfo != null) if (gameInfo != null)
{ {
await gameInfo.SaveChangesAsync(this);
var game = Cache.GameEntityCache[gameInfo.GameId]; var game = Cache.GameEntityCache[gameInfo.GameId];
if (game != null) if (game != null)
{ {
await gameInfo.SaveChangesAsync(this); return new PlayGameInfoDto(game, DtoModel.Epg.EpgEnum.ImageResStyle.LOGO, sess.RestTime);
return new GameListDto(game, DtoModel.Epg.EpgEnum.ImageResStyle.LOGO);
} }
} }

View File

@ -32,13 +32,14 @@ namespace CloudGaming.Code.Game
return builder; return builder;
} }
public static string GetPlayGameKeyPrefix { get; set; } = $"PlayGame";
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="gameId"></param> /// <param name="gameId"></param>
/// <param name="userId"></param> /// <param name="userId"></param>
/// <returns></returns> /// <returns></returns>
public static string GetPlayGameKeyPrefix { get; set; } = $"PlayGame";
public static string GetPlayGameKey(string gameId, int userId) => $"PlayGame:{gameId}:{userId}"; public static string GetPlayGameKey(string gameId, int userId) => $"PlayGame:{gameId}:{userId}";
/// <summary> /// <summary>
/// 获取用户游戏缓存 /// 获取用户游戏缓存
@ -110,7 +111,7 @@ namespace CloudGaming.Code.Game
playGameUserInfo.DisplayGrade = playGameSettings.DisplayGrade; playGameUserInfo.DisplayGrade = playGameSettings.DisplayGrade;
if (playGameUserInfo.GameStatus == PlayGameStatus.) if (playGameUserInfo.GameStatus == PlayGameStatus.)
{ {
playGameUserInfo.GameStatus = PlayGameStatus.; playGameUserInfo.GameStatus = PlayGameStatus.;
} }
return true; return true;
} }
@ -126,13 +127,14 @@ namespace CloudGaming.Code.Game
public static bool ExitPlayGame(this PlayGameUserInfo playGameUserInfo, IJYApiRespnse jYApiRespnse) public static bool ExitPlayGame(this PlayGameUserInfo playGameUserInfo, IJYApiRespnse jYApiRespnse)
{ {
if (playGameUserInfo.GameStatus != PlayGameStatus.) if (playGameUserInfo.GameStatus != PlayGameStatus.)
{ {
playGameUserInfo.GameStatus = PlayGameStatus.; playGameUserInfo.GameStatus = PlayGameStatus.;
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse) playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse)
{ {
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
Content = "游戏结束", Content = "游戏结束",
ActionId = (int)PlayGameStatus.
}); });
playGameUserInfo.LastDateTime = DateTime.Now; playGameUserInfo.LastDateTime = DateTime.Now;
} }
@ -156,8 +158,9 @@ namespace CloudGaming.Code.Game
playGameUserInfo.DisplayGrade = display_grade; playGameUserInfo.DisplayGrade = display_grade;
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse) playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse)
{ {
Content = "开始游戏", Content = $"游戏启动成功,开始游戏scId{scId}",
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
ActionId = (int)PlayGameStatus.
}); });
playGameUserInfo.PlayGameStartAt = DateTime.Now; playGameUserInfo.PlayGameStartAt = DateTime.Now;
playGameUserInfo.PlayGameHeartbeatAt = DateTime.Now; playGameUserInfo.PlayGameHeartbeatAt = DateTime.Now;
@ -176,21 +179,12 @@ namespace CloudGaming.Code.Game
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse) playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse)
{ {
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
Content = "启动游戏失败", Content = "启动游戏失败;",
ActionId = (int)PlayGameStatus.
}); });
return true; return true;
} }
/// <summary>
/// 游戏启动失败
/// </summary>
/// <param name="playGameUserInfo"></param>
/// <returns></returns>
public static bool PlayGameClose(this PlayGameUserInfo playGameUserInfo)
{
playGameUserInfo.GameStatus = PlayGameStatus.;
return true;
}
/// <summary> /// <summary>
/// 游戏心跳 /// 游戏心跳
@ -208,6 +202,7 @@ namespace CloudGaming.Code.Game
{ {
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
Content = "用户游戏掉线重连成功", Content = "用户游戏掉线重连成功",
ActionId = (int)PlayGameStatus.线
}); });
} }
playGameUserInfo.GameStatus = PlayGameStatus.; playGameUserInfo.GameStatus = PlayGameStatus.;
@ -218,6 +213,7 @@ namespace CloudGaming.Code.Game
{ {
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
Content = $"用户持续游戏中,累计游玩时间{(playGameUserInfo.PlayGameTotalSeconds / 60).ToString("0.##")}分钟{desc}", Content = $"用户持续游戏中,累计游玩时间{(playGameUserInfo.PlayGameTotalSeconds / 60).ToString("0.##")}分钟{desc}",
ActionId = (int)PlayGameStatus.
}); });
return true; return true;
} }
@ -236,12 +232,13 @@ namespace CloudGaming.Code.Game
PlayGameUserOperation? playGameUserOperation = null; PlayGameUserOperation? playGameUserOperation = null;
if (playGameUserInfo.GameStatus == PlayGameStatus.) if (playGameUserInfo.GameStatus == PlayGameStatus.)
{ {
if (playGameUserInfo.LastWriteQueueAt == null || (playGameUserInfo.LastWriteQueueAt != null && DateTime.Now.Subtract(playGameUserInfo.LastWriteQueueAt ?? DateTime.Now).TotalMinutes > 1)) if (playGameUserInfo.LastWriteQueueAt == null || (playGameUserInfo.LastWriteQueueAt != null && DateTime.Now.Subtract(playGameUserInfo.LastWriteQueueAt ?? DateTime.Now).TotalSeconds > 30))
{ {
playGameUserOperation = new PlayGameUserOperation(jYApiRespnse) playGameUserOperation = new PlayGameUserOperation(jYApiRespnse)
{ {
Content = $"排队中,排队Id{play_queue_id},前面还有{queue_pos}人", Content = $"继续排队中,排队Id{play_queue_id},前面还有{queue_pos}人",
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
ActionId = (int)PlayGameStatus.
}; };
playGameUserInfo.LastWriteQueueAt = DateTime.Now; playGameUserInfo.LastWriteQueueAt = DateTime.Now;
} }
@ -249,24 +246,25 @@ namespace CloudGaming.Code.Game
{ {
playGameUserOperation = new PlayGameUserOperation() playGameUserOperation = new PlayGameUserOperation()
{ {
Content = $"排队中,排队Id{play_queue_id},前面还有{queue_pos}人", Content = $"继续排队中,排队Id{play_queue_id},前面还有{queue_pos}人",
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
ActionId = (int)PlayGameStatus.
}; };
} }
playGameUserInfo.GameUserOperation.Add(playGameUserOperation); playGameUserInfo.GameUserOperation.Add(playGameUserOperation);
} }
else else
{ {
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse) playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse)
{ {
Content = $"开始排队,排队Id{play_queue_id},前面还有{queue_pos}人", Content = $"开始排队,排队Id{play_queue_id},前面还有{queue_pos}人",
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
ActionId = (int)PlayGameStatus.
}); });
} }
playGameUserInfo.GameStatus = PlayGameStatus.; playGameUserInfo.GameStatus = PlayGameStatus.;
playGameUserInfo.LastPlayQueueAt = DateTime.Now;
playGameUserInfo.PlayQueueId = play_queue_id; playGameUserInfo.PlayQueueId = play_queue_id;
if (playGameUserInfo.PlayQueueStartAt == null) if (playGameUserInfo.PlayQueueStartAt == null)
{ {
@ -290,7 +288,7 @@ namespace CloudGaming.Code.Game
playGameUserInfo.GameStatus = PlayGameStatus.; playGameUserInfo.GameStatus = PlayGameStatus.;
playGameUserInfo.PlayQueueSuccessAt = DateTime.Now; playGameUserInfo.PlayQueueSuccessAt = DateTime.Now;
var totalSeconds = 0; var totalSeconds = 0;
if (playGameUserInfo.PlayQueueStart != null) if (playGameUserInfo.PlayQueueStartAt != null)
{ {
totalSeconds = (int)DateTime.Now.Subtract(playGameUserInfo.PlayQueueStartAt ?? DateTime.Now).TotalSeconds; totalSeconds = (int)DateTime.Now.Subtract(playGameUserInfo.PlayQueueStartAt ?? DateTime.Now).TotalSeconds;
} }
@ -298,7 +296,9 @@ namespace CloudGaming.Code.Game
{ {
Content = $"排队成功,本次排队耗时{totalSeconds}秒", Content = $"排队成功,本次排队耗时{totalSeconds}秒",
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
ActionId = (int)playGameUserInfo.GameStatus
}); });
playGameUserInfo.LastPlayQueueAt = DateTime.Now;
} }
return true; return true;
} }
@ -314,6 +314,62 @@ namespace CloudGaming.Code.Game
{ {
Content = $"用户取消排队", Content = $"用户取消排队",
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
ActionId = (int)playGameUserInfo.GameStatus
});
return true;
}
/// <summary>
/// 用户切换视频等级
/// </summary>
/// <param name="playGameUserInfo"></param>
/// <param name="displayGrade"></param>
/// <param name="jYApiRespnse"></param>
/// <returns></returns>
public static bool UserSwitchDisplayGrade(this PlayGameUserInfo playGameUserInfo, int displayGrade, IJYApiRespnse jYApiRespnse)
{
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse)
{
Content = $"用户切换视频等级:{displayGrade};",
OperationDateTime = DateTime.Now,
ActionId = (int)PlayGameStatus.
});
return true;
}
/// <summary>
/// 用户切换视频等级
/// </summary>
/// <param name="playGameUserInfo"></param>
/// <param name="displayGrade"></param>
/// <param name="jYApiRespnse"></param>
/// <returns></returns>
public static bool UserSwitchDisplayGradeError(this PlayGameUserInfo playGameUserInfo, int displayGrade, IJYApiRespnse jYApiRespnse)
{
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse)
{
Content = $"用户切换视频等级失败:{displayGrade};",
OperationDateTime = DateTime.Now,
ActionId = (int)PlayGameStatus.
});
return true;
}
/// <summary>
/// 排队异常
/// </summary>
/// <param name="playGameUserInfo"></param>
/// <returns></returns>
public static bool PlayGameQueueError(this PlayGameUserInfo playGameUserInfo, IJYApiRespnse jYApiRespnse)
{
playGameUserInfo.GameStatus = PlayGameStatus.;
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse)
{
OperationDateTime = DateTime.Now,
Content = "排队异常!",
ActionId = (int)PlayGameStatus.
}); });
return true; return true;
} }
@ -337,11 +393,50 @@ namespace CloudGaming.Code.Game
{ {
Content = $"用户游戏掉线,上一次心跳时间{playGameUserInfo.PlayGameHeartbeatAt?.ToString("yyyy-MM-dd HH:mm:ss")};", Content = $"用户游戏掉线,上一次心跳时间{playGameUserInfo.PlayGameHeartbeatAt?.ToString("yyyy-MM-dd HH:mm:ss")};",
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
ActionId = (int)playGameUserInfo.GameStatus
}); });
} }
return true; return true;
} }
/// <summary>
/// 游戏掉线
/// </summary>
/// <param name="playGameUserInfo"></param>
/// <returns></returns>
public static bool PlayGameUserNotQueue(this PlayGameUserInfo playGameUserInfo)
{
if (playGameUserInfo.GameStatus != PlayGameStatus.线)
{
playGameUserInfo.GameStatus = PlayGameStatus.线;
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation()
{
Content = $"用户排队掉线,上一次排队时间{playGameUserInfo.LastPlayQueueAt?.ToString("yyyy-MM-dd HH:mm:ss")}",
OperationDateTime = DateTime.Now,
ActionId = (int)playGameUserInfo.GameStatus
});
}
return true;
}
/// <summary>
/// 游戏掉线
/// </summary>
/// <param name="playGameUserInfo"></param>
/// <returns></returns>
public static bool PlayGameUserNotQueueEnd(this PlayGameUserInfo playGameUserInfo, IJYApiRespnse jYApiRespnse)
{
playGameUserInfo.GameStatus = PlayGameStatus.线;
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse)
{
Content = $"用户排队掉线,上一次排队时间{playGameUserInfo.LastPlayQueueAt?.ToString("yyyy-MM-dd HH:mm:ss")};准备结束游戏;",
OperationDateTime = DateTime.Now,
ActionId = (int)playGameUserInfo.GameStatus
});
return true;
}
/// <summary> /// <summary>
/// 游戏掉线 /// 游戏掉线
/// </summary> /// </summary>
@ -352,24 +447,26 @@ namespace CloudGaming.Code.Game
playGameUserInfo.GameStatus = PlayGameStatus.线; playGameUserInfo.GameStatus = PlayGameStatus.线;
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse) playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse)
{ {
Content = $"用户游戏掉线,结束游戏", Content = $"用户游戏掉线,准备结束游戏",
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
ActionId = (int)PlayGameStatus.线
}); });
return true; return true;
} }
/// <summary> /// <summary>
/// 游戏掉线 /// 用户钻石不足,准备退出游戏
/// </summary> /// </summary>
/// <param name="playGameUserInfo"></param> /// <param name="playGameUserInfo"></param>
/// <returns></returns> /// <returns></returns>
public static bool PlayGameUserNotDiamond(this PlayGameUserInfo playGameUserInfo, IJYApiRespnse jYApiRespnse) public static bool PlayGameUserNotDiamond(this PlayGameUserInfo playGameUserInfo, IJYApiRespnse jYApiRespnse)
{ {
playGameUserInfo.GameStatus = PlayGameStatus.; playGameUserInfo.GameStatus = PlayGameStatus.;
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse) playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse)
{ {
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
Content = $"用户余额不足,准备退出游戏" Content = $"用户余额不足,准备退出游戏",
ActionId = (int)PlayGameStatus.
}); });
return true; return true;
} }
@ -403,7 +500,7 @@ namespace CloudGaming.Code.Game
/// <param name="userId"></param> /// <param name="userId"></param>
/// <param name="scId"></param> /// <param name="scId"></param>
/// <returns></returns> /// <returns></returns>
public static async Task<PlayGameUserInfo> PlayGameRecon(CloudGamingBase cloudGamingBase, int userId, int scId) public static async Task<PlayGameUserInfo> PlayGameRecon(CloudGamingBase cloudGamingBase, int userId, int scId, IJYApiRespnse jYApiRespnse)
{ {
var list = await GetPlayGameUserInfoList(cloudGamingBase.RedisCache, cloudGamingBase.RedisServerCache, $"{GetPlayGameKeyPrefix}:*:{userId}"); var list = await GetPlayGameUserInfoList(cloudGamingBase.RedisCache, cloudGamingBase.RedisServerCache, $"{GetPlayGameKeyPrefix}:*:{userId}");
if (list != null && list.Count > 0) if (list != null && list.Count > 0)
@ -415,10 +512,11 @@ namespace CloudGaming.Code.Game
} }
if (playGameUserInfo != null) if (playGameUserInfo != null)
{ {
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation() playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse)
{ {
Content = $"用户获取可连接的游戏列表scId:${scId};", Content = $"用户获取可连接的游戏列表scId:${scId};",
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
ActionId = (int)PlayGameStatus.线
}); });
} }
return playGameUserInfo; return playGameUserInfo;
@ -448,6 +546,7 @@ namespace CloudGaming.Code.Game
{ {
Content = $"用户重连游戏成功,上一次心跳时间{playGameUserInfo.PlayGameHeartbeatAt?.ToString("yyyy-MM-dd HH:mm:ss")};", Content = $"用户重连游戏成功,上一次心跳时间{playGameUserInfo.PlayGameHeartbeatAt?.ToString("yyyy-MM-dd HH:mm:ss")};",
OperationDateTime = DateTime.Now, OperationDateTime = DateTime.Now,
ActionId = (int)PlayGameStatus.
}); });
} }
return playGameUserInfo; return playGameUserInfo;
@ -475,64 +574,85 @@ namespace CloudGaming.Code.Game
{ {
playGameUserInfo.LastDateTime = DateTime.Now; playGameUserInfo.LastDateTime = DateTime.Now;
var redisGameKey = GetPlayGameKey(playGameUserInfo.GameId, playGameUserInfo.UserId); var redisGameKey = GetPlayGameKey(playGameUserInfo.GameId, playGameUserInfo.UserId);
if (playGameUserInfo.GameStatus == PlayGameStatus. || playGameUserInfo.GameStatus == PlayGameStatus. || playGameUserInfo.GameStatus == PlayGameStatus. || playGameUserInfo.GameStatus == PlayGameStatus. || playGameUserInfo.GameStatus == PlayGameStatus.线) if (playGameUserInfo.GameStatus == PlayGameStatus. ||
playGameUserInfo.GameStatus == PlayGameStatus. ||
playGameUserInfo.GameStatus == PlayGameStatus.
|| playGameUserInfo.GameStatus == PlayGameStatus.
|| playGameUserInfo.GameStatus == PlayGameStatus.
|| playGameUserInfo.GameStatus == PlayGameStatus.线 ||
playGameUserInfo.GameStatus == PlayGameStatus. ||
playGameUserInfo.GameStatus == PlayGameStatus.线
)
{ {
T_User_GameList userGameListLog = null; //只有不等于下面这几种状态才记录游玩记录
if (playGameUserInfo.DiamondListId > 0) if (playGameUserInfo.GameStatus != PlayGameStatus.线 && playGameUserInfo.GameStatus != PlayGameStatus. && playGameUserInfo.GameStatus != PlayGameStatus.线 && playGameUserInfo.GameStatus != PlayGameStatus.线 && playGameUserInfo.GameStatus != PlayGameStatus. && playGameUserInfo.GameStatus != PlayGameStatus.)
{ {
//设置游玩记录 T_User_GameList userGameListLog = null;
userGameListLog = await dao.DaoPhone.Context.T_User_GameList.FirstOrDefaultAsync(it => it.Id == playGameUserInfo.DiamondListId); if (playGameUserInfo.DiamondListId > 0)
}
if (userGameListLog == null)
{
userGameListLog = new T_User_GameList
{ {
Channel = playGameUserInfo.Channel, //设置游玩记录
CreateTime = playGameUserInfo.PlayGameStartAt ?? playGameUserInfo.CreateDateTime, userGameListLog = await dao.DaoPhone.Context.T_User_GameList.FirstOrDefaultAsync(it => it.Id == playGameUserInfo.DiamondListId);
GameId = playGameUserInfo.GameId,
Status = (int)PlayGameStatus.,
UpdateTime = DateTime.Now,
UserId = playGameUserInfo.UserId,
SessionId = playGameUserInfo?.SessionId
};
await dao.DaoPhone.Context.T_User_GameList.AddAsync(userGameListLog);
}
userGameListLog.Status = (int)PlayGameStatus.;
var t = DateTime.Now.Subtract(playGameUserInfo.PlayGameStartAt ?? playGameUserInfo.CreateDateTime);
var playTime = (int)t.TotalSeconds / 60;
userGameListLog.PlaySeconds = (int)t.TotalSeconds;
userGameListLog.PlayTime = playTime;
userGameListLog.UpdateTime = DateTime.Now;
await dao.DaoPhone.Context.SaveChangesAsync();
//设置游玩历史
var userId = playGameUserInfo.UserId;
var gameId = playGameUserInfo.GameId;
if (playGameUserInfo.GameStatus != PlayGameStatus. && playGameUserInfo.GameStatus != PlayGameStatus.)
{
//设置用户游玩历史
var playGameTime = await dao.DaoPhone.Context.T_User_PlayGameTime.Where(it => it.UserId == userId && it.GameId == gameId).FirstOrDefaultAsync();
if (playGameTime == null)
{
playGameTime = new T_User_PlayGameTime()
{
Createtime = DateTime.Now,
NightCardPlayTime = 0,
DiamondPlayTime = 0,
FreePlayTime = 0,
GameId = gameId,
PlayTime = 0,
UpdateTime = DateTime.Now,
UserId = userId,
};
await dao.DaoPhone.Context.T_User_PlayGameTime.AddAsync(playGameTime);
} }
playGameTime.PlayTime += playTime; if (userGameListLog == null)
playGameTime.UpdateTime = DateTime.Now; {
playGameTime.DiamondPlayTime += playTime; userGameListLog = new T_User_GameList
{
Channel = playGameUserInfo.Channel,
CreateTime = playGameUserInfo.PlayGameStartAt ?? playGameUserInfo.CreateDateTime,
GameId = playGameUserInfo.GameId,
Status = (int)PlayGameStatus.,
UpdateTime = DateTime.Now,
UserId = playGameUserInfo.UserId,
SessionId = playGameUserInfo?.SessionId
};
await dao.DaoPhone.Context.T_User_GameList.AddAsync(userGameListLog);
}
userGameListLog.Status = (int)PlayGameStatus.;
var t = DateTime.Now.Subtract(playGameUserInfo.PlayGameStartAt ?? playGameUserInfo.CreateDateTime);
var playTime = (int)t.TotalSeconds / 60;
userGameListLog.PlaySeconds = (int)t.TotalSeconds;
userGameListLog.PlayTime = playTime;
userGameListLog.UpdateTime = DateTime.Now;
await dao.DaoPhone.Context.SaveChangesAsync(); await dao.DaoPhone.Context.SaveChangesAsync();
//设置游玩历史
var userId = playGameUserInfo.UserId;
var gameId = playGameUserInfo.GameId;
if (playGameUserInfo.GameStatus != PlayGameStatus. && playGameUserInfo.GameStatus != PlayGameStatus. && playGameUserInfo.GameStatus != PlayGameStatus.线)
{
//设置用户游玩历史
var playGameTime = await dao.DaoPhone.Context.T_User_PlayGameTime.Where(it => it.UserId == userId && it.GameId == gameId).FirstOrDefaultAsync();
if (playGameTime == null)
{
playGameTime = new T_User_PlayGameTime()
{
Createtime = DateTime.Now,
NightCardPlayTime = 0,
DiamondPlayTime = 0,
FreePlayTime = 0,
GameId = gameId,
PlayTime = 0,
UpdateTime = DateTime.Now,
UserId = userId,
};
await dao.DaoPhone.Context.T_User_PlayGameTime.AddAsync(playGameTime);
}
playGameTime.PlayTime += playTime;
playGameTime.UpdateTime = DateTime.Now;
playGameTime.DiamondPlayTime += playTime;
await dao.DaoPhone.Context.SaveChangesAsync();
}
} }
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation()
{
Content = "游戏结束",
OperationDateTime = DateTime.Now,
ActionId = (int)PlayGameStatus.
});
var playGameLog = playGameUserInfo.ToGamePlayGameLog(); var playGameLog = playGameUserInfo.ToGamePlayGameLog();
if (playGameLog != null) if (playGameLog != null)
{ {

View File

@ -61,7 +61,10 @@ public class PlayGameProcessor(IServiceProvider serviceProvider) : ThreadProcess
{ {
var userNotActionDisconnect = DateTime.Now.AddSeconds(-appConfig.GameConfig.UserNotActionDisconnect); var userNotActionDisconnect = DateTime.Now.AddSeconds(-appConfig.GameConfig.UserNotActionDisconnect);
var userNotActionEndGame = DateTime.Now.AddSeconds(-appConfig.GameConfig.UserNotActionEndGame); var userNotActionEndGame = DateTime.Now.AddSeconds(-appConfig.GameConfig.UserNotActionEndGame);
//30 秒检测不到排队信息,则判断排队掉线
var userNotQueue = DateTime.Now.AddSeconds(-30);
//60 秒检查不到排队,则判断排队结束
var userNotQueueEnd = DateTime.Now.AddSeconds(-60);
using var scope = serviceProvider.CreateScope(); using var scope = serviceProvider.CreateScope();
var app = scope.ServiceProvider.GetRequiredService<AppConfig>(); var app = scope.ServiceProvider.GetRequiredService<AppConfig>();
appConfig.ToAppConfig(app); appConfig.ToAppConfig(app);
@ -101,6 +104,27 @@ public class PlayGameProcessor(IServiceProvider serviceProvider) : ThreadProcess
user.PlayGameUserNotAction(); user.PlayGameUserNotAction();
await user.SaveChangesAsync(dao, redis).ConfigureAwait(false); await user.SaveChangesAsync(dao, redis).ConfigureAwait(false);
} }
//用户排队掉线人
var userPlayGameNotQueueEndGame = gameInfoList
.Where(it => it.GameStatus == PlayGameStatus.线 && it.PlayGameHeartbeatAt < userNotQueueEnd)
.ToList();
if (userPlayGameNotQueueEndGame.Count > 0)
foreach (var user in userPlayGameNotQueueEndGame)
{
await EndGameQueueAsync(user, appConfig, dao, redis).ConfigureAwait(false);
gameInfoList.Remove(user);
}
var userPlayGameNotQueue = gameInfoList
.Where(it => it.GameStatus == PlayGameStatus. && it.LastDateTime < userNotQueue)
.ToList();
if (userPlayGameNotQueue.Count > 0)
foreach (var user in userPlayGameNotQueue)
{
user.PlayGameUserNotQueue();
await user.SaveChangesAsync(dao, redis).ConfigureAwait(false);
}
} }
/// <summary> /// <summary>
@ -123,4 +147,24 @@ public class PlayGameProcessor(IServiceProvider serviceProvider) : ThreadProcess
user.PlayGameDiaoXian(jyResponse); user.PlayGameDiaoXian(jyResponse);
await user.SaveChangesAsync(dao, redis).ConfigureAwait(false); await user.SaveChangesAsync(dao, redis).ConfigureAwait(false);
} }
/// <summary>
/// 排队掉线结束游戏逻辑
/// </summary>
private async Task EndGameQueueAsync(PlayGameUserInfo user, AppConfig appConfig, DAO dao, IDatabase redis)
{
HttpClient httpClient = new HttpClient(new JYApiAppConfigHandler(appConfig, user.Ip));
httpClient.BaseAddress = new Uri(appConfig.GameConfig.BsUrl);
var jyApi = RestService.For<IJYApi>(httpClient);
var playGameCommonSetting = new PlayGameQueue(user.Sn, user.UserId)
{
PlayQueueId = user.ScId,
Sn = user.Sn
};
var jyResponse = await jyApi.CancelQueue(playGameCommonSetting).ConfigureAwait(false);
user.PlayGameUserNotQueueEnd(jyResponse);
await user.SaveChangesAsync(dao, redis).ConfigureAwait(false);
}
} }

View File

@ -0,0 +1,27 @@
using CloudGaming.DtoModel.Epg;
using CloudGaming.DtoModel.Game;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.DtoModel.PlayGame
{
/// <summary>
///
/// </summary>
public class PlayGameInfoDto : GameListDto
{
public PlayGameInfoDto(GameInfo gameInfo, EpgEnum.ImageResStyle imageResStyle, int restTime) : base(gameInfo, imageResStyle)
{
this.RestTime = restTime;
}
/// <summary>
/// 剩余时间,秒
/// </summary>
public int RestTime { get; set; }
}
}

View File

@ -4,66 +4,141 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace CloudGaming.DtoModel.PlayGame namespace CloudGaming.DtoModel.PlayGame;
/// <summary>
/// 游戏状态枚举
/// 初始化相关状态放在前面,按顺序排列(如初始化、初始化成功等)。
/// 排队相关状态接着排列,确保排队的流程是连贯的(如排队中、排队成功等)。
/// 游戏进行中状态按开始、进行、结束的顺序排列。
/// 错误或异常状态(如游戏启动失败、钻石不足等)在适当位置按流程排序。
/// </summary>
public enum PlayGameStatus
{ {
/// <summary>
/// 游戏初始化状态
/// </summary>
= 0,
/// <summary>
/// 游戏初始化成功
/// </summary>
= 1,
// ----------------------------------------
// 初始化和排队相关状态0 到 6占用了较低的范围留有空间例如 7-9供未来扩展。
// ----------------------------------------
/// <summary>
/// 排队中
/// </summary>
= 2,
/// <summary>
/// 排队成功
/// </summary>
= 3,
/// <summary>
/// 取消排队
/// </summary>
= 4,
/// <summary>
/// 排队过程中掉线
/// </summary>
线 = 5,
/// <summary>
/// 排队掉线已结束
/// </summary>
线 = 6,
// ----------------------------------------
// 异常状态占用了10到19
// ----------------------------------------
/// <summary>
/// 游戏启动失败
/// </summary>
= 10,
/// <summary>
/// 用户钻石不足
/// </summary>
= 11,
/// <summary>
/// 用户游玩时钻石不足
/// </summary>
= 12,
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public enum PlayGameStatus 退 = 13,
{
/// <summary>
/// 正常
/// </summary>
= 0,
/// <summary>
/// 初始化成功
/// </summary>
= 1,
/// <summary>
/// 开始游戏
/// </summary>
= 2,
/// <summary>
/// 游戏中
/// </summary>
= 3,
/// <summary>
/// 游戏结束
/// </summary>
= 4,
/// <summary>
///
/// </summary>
= 5,
/// <summary>
///
/// </summary>
= 6,
/// <summary>
///
/// </summary>
= 7,
/// <summary> /// <summary>
/// 游戏掉线 /// 排队异常
/// </summary> /// </summary>
线 = 8, = 14,
/// <summary>
///
/// </summary>
= 15,
/// <summary> // ----------------------------------------
/// // 游戏进行中的状态 (预留空间: 20-39)
/// </summary> // ----------------------------------------
线 = 10,
/// <summary> /// <summary>
/// 游戏启动失败 /// 游戏开始
/// </summary> /// </summary>
= 9, = 20,
/// <summary> /// <summary>
/// /// 游戏正在进行
/// </summary> /// </summary>
= 11, = 21,
/// <summary>
/// 用户主动结束游戏
/// </summary>
= 22,
/// <summary>
/// 游戏掉线
/// </summary>
线 = 23,
/// <summary>
/// 游戏掉线已结束
/// </summary>
线 = 24,
// ----------------------------------------
// 游戏结束状态 (预留空间: 40-49)
// ----------------------------------------
/// <summary>
/// 游戏结束
/// </summary>
= 40,
// ----------------------------------------
// 未来扩展的状态 (预留空间: 50-99)
// ----------------------------------------
} /// <summary>
/// 游戏暂停 (示例)
/// </summary>
= 50,
/// <summary>
/// 切换视频等级
/// </summary>
= 51
} }

View File

@ -115,6 +115,12 @@ public class PlayGameUserInfo
/// </summary> /// </summary>
public DateTime? PlayQueueStartAt { get; set; } public DateTime? PlayQueueStartAt { get; set; }
/// <summary>
/// 最后一次排队时间
/// </summary>
public DateTime? LastPlayQueueAt { get; set; }
/// <summary> /// <summary>
/// 最后写入排队时间 /// 最后写入排队时间
/// </summary> /// </summary>
@ -157,6 +163,10 @@ public class PlayGameUserInfo
/// <returns></returns> /// <returns></returns>
public T_Game_PlayGameLog ToGamePlayGameLog() public T_Game_PlayGameLog ToGamePlayGameLog()
{ {
JsonSerializerSettings settings = new JsonSerializerSettings
{
DateFormatString = "yyyy-MM-dd HH:mm:ss"
};
var log = new T_Game_PlayGameLog var log = new T_Game_PlayGameLog
{ {
GameId = GameId, GameId = GameId,
@ -184,7 +194,7 @@ public class PlayGameUserInfo
CurrencyLogId = CurrencyLogId, CurrencyLogId = CurrencyLogId,
DiamondListId = DiamondListId, DiamondListId = DiamondListId,
GameStatus = (int)GameStatus, GameStatus = (int)GameStatus,
GameUserOperationJson = GameUserOperation == null ? "" : JsonConvert.SerializeObject(GameUserOperation), GameUserOperationJson = GameUserOperation == null ? "" : JsonConvert.SerializeObject(GameUserOperation, settings),
}; };
return log; return log;
} }

View File

@ -23,7 +23,10 @@ namespace CloudGaming.DtoModel.PlayGame
TotalMilliseconds = jYApiRespnse?.TotalMilliseconds; TotalMilliseconds = jYApiRespnse?.TotalMilliseconds;
} }
/// <summary>
/// 动作id
/// </summary>
public int ActionId { get; set; }
/// <summary> /// <summary>
/// 操作时间 /// 操作时间