修改玩游戏逻辑

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>
[HttpPost]
[Authorize]
public async Task<GameListDto> GetMyScListAsync([FromBody] RequestBaseModel requestBaseModel)
public async Task<PlayGameInfoDto> GetMyScListAsync([FromBody] RequestBaseModel requestBaseModel)
{
PlayGameBLL playGameBLL = new PlayGameBLL(ServiceProvider, JYApi);
return await playGameBLL.GetMyScList(requestBaseModel.Sn);

View File

@ -2,6 +2,12 @@
# 此阶段用于在快速模式(默认为调试配置)下从 VS 运行时
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
WORKDIR /app
EXPOSE 80

View File

@ -2,6 +2,13 @@
# 此阶段用于在快速模式(默认为调试配置)下从 VS 运行时
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
WORKDIR /app
EXPOSE 80

View File

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

View File

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

View File

@ -61,7 +61,10 @@ public class PlayGameProcessor(IServiceProvider serviceProvider) : ThreadProcess
{
var userNotActionDisconnect = DateTime.Now.AddSeconds(-appConfig.GameConfig.UserNotActionDisconnect);
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();
var app = scope.ServiceProvider.GetRequiredService<AppConfig>();
appConfig.ToAppConfig(app);
@ -101,6 +104,27 @@ public class PlayGameProcessor(IServiceProvider serviceProvider) : ThreadProcess
user.PlayGameUserNotAction();
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>
@ -123,4 +147,24 @@ public class PlayGameProcessor(IServiceProvider serviceProvider) : ThreadProcess
user.PlayGameDiaoXian(jyResponse);
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.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>
public enum PlayGameStatus
{
/// <summary>
/// 正常
/// </summary>
= 0,
/// <summary>
/// 初始化成功
/// </summary>
= 1,
/// <summary>
/// 开始游戏
/// </summary>
= 2,
/// <summary>
/// 游戏中
/// </summary>
= 3,
/// <summary>
/// 游戏结束
/// </summary>
= 4,
/// <summary>
///
/// </summary>
= 5,
/// <summary>
///
/// </summary>
= 6,
/// <summary>
///
/// </summary>
= 7,
退 = 13,
/// <summary>
/// 游戏掉线
/// </summary>
线 = 8,
/// <summary>
/// 排队异常
/// </summary>
= 14,
/// <summary>
///
/// </summary>
= 15,
/// <summary>
///
/// </summary>
线 = 10,
// ----------------------------------------
// 游戏进行中的状态 (预留空间: 20-39)
// ----------------------------------------
/// <summary>
/// 游戏启动失败
/// </summary>
= 9,
/// <summary>
/// 游戏开始
/// </summary>
= 20,
/// <summary>
///
/// </summary>
= 11,
/// <summary>
/// 游戏正在进行
/// </summary>
= 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>
public DateTime? PlayQueueStartAt { get; set; }
/// <summary>
/// 最后一次排队时间
/// </summary>
public DateTime? LastPlayQueueAt { get; set; }
/// <summary>
/// 最后写入排队时间
/// </summary>
@ -157,6 +163,10 @@ public class PlayGameUserInfo
/// <returns></returns>
public T_Game_PlayGameLog ToGamePlayGameLog()
{
JsonSerializerSettings settings = new JsonSerializerSettings
{
DateFormatString = "yyyy-MM-dd HH:mm:ss"
};
var log = new T_Game_PlayGameLog
{
GameId = GameId,
@ -184,7 +194,7 @@ public class PlayGameUserInfo
CurrencyLogId = CurrencyLogId,
DiamondListId = DiamondListId,
GameStatus = (int)GameStatus,
GameUserOperationJson = GameUserOperation == null ? "" : JsonConvert.SerializeObject(GameUserOperation),
GameUserOperationJson = GameUserOperation == null ? "" : JsonConvert.SerializeObject(GameUserOperation, settings),
};
return log;
}

View File

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