修改问题

This commit is contained in:
zpc 2024-11-29 01:01:32 +08:00
parent d6740c92dd
commit b556c4c23b
14 changed files with 480 additions and 73 deletions

View File

@ -149,7 +149,7 @@ public class PlayGameController : CloudGamingControllerBase
/// <returns></returns>
[HttpPost]
[Authorize]
public async Task<BaseResponse<object>> ReconPlayGameAsync([FromBody] ReconPlayGameSettings reconPlayGameSettings)
public async Task<BaseResponse<object>> ReconPlayGameAsync([FromBody] ReconPlayGameRequest reconPlayGameSettings)
{
PlayGameBLL playGameBLL = new PlayGameBLL(ServiceProvider, JYApi);
return await playGameBLL.ReconPlayGame(reconPlayGameSettings);

View File

@ -149,6 +149,17 @@ namespace CloudGaming.Code.AppExtend
{
return RedisConnection.GetRedis(appConfig.RedisConnectionString);
}
/// <summary>
///
/// </summary>
/// <param name="redisConnection"></param>
/// <returns></returns>
public static IServer GetRedisServer(this AppConfig appConfig)
{
return RedisConnection.GetServer(appConfig.RedisConnectionString);
}
/// <summary>
/// 获取Dao
/// </summary>

View File

@ -62,7 +62,7 @@ namespace CloudGaming.Code.Contract
Task<JYApiResponse<Dictionary<string, object>>> DisplayGrade([Body(BodySerializationMethod.UrlEncoded)] DisplayGradeSettings playGameQueue);
/// <summary>
/// 切换视频等级
/// 重连会话
/// </summary>
/// <param name="playGameQueue"></param>
/// <returns></returns>
@ -84,7 +84,7 @@ namespace CloudGaming.Code.Contract
/// <param name="requestBase"></param>
/// <returns></returns>
[Post("/jyapi/myScList")]
Task<JYApiResponse<Dictionary<string, object>>> MyScList([Body(BodySerializationMethod.UrlEncoded)] RequestBaseModel requestBase);
Task<JYApiResponse<Dictionary<string, object>>> MyScList([Body(BodySerializationMethod.UrlEncoded)] JYRequestParameter parameter);
/// <summary>
/// 获取会话列表
/// </summary>

View File

@ -7,6 +7,8 @@ using CloudGaming.DtoModel.PlayGame;
using Newtonsoft.Json;
using Org.BouncyCastle.Asn1.Ocsp;
namespace CloudGaming.Code.Game;
@ -481,10 +483,7 @@ public class PlayGameBLL : CloudGamingBase
/// <returns></returns>
public async Task<BaseResponse<object>> GetMyScList(string sn)
{
var requestParmat = new RequestBaseModel()
{
Sn = sn,
};
var requestParmat = new JYRequestParameter(sn, _UserId);
var response = await JYApi.MyScList(requestParmat);
if (response.IsSuccess)
{
@ -497,27 +496,32 @@ public class PlayGameBLL : CloudGamingBase
/// <summary>
/// 重连会话
/// </summary>
/// <param name="sc_id"></param>
/// <param name="display_grade"></param>
/// <param name="model_name"></param>
/// <param name="sn"></param>
/// <param name="cpu"></param>
/// <param name="reconPlayGameRequest"></param>
/// <returns></returns>
public async Task<BaseResponse<object>> ReconPlayGame(ReconPlayGameSettings reconPlayGameSettings)
public async Task<BaseResponse<dynamic>> ReconPlayGame(ReconPlayGameRequest reconPlayGameRequest)
{
var setting = new ReconPlayGameSettings()
var setting = new ReconPlayGameSettings(reconPlayGameRequest.Sn, _UserId)
{
ScId = reconPlayGameSettings.ScId,
DisplayGrade = reconPlayGameSettings.DisplayGrade,
Cpu = reconPlayGameSettings.Cpu,
ModelName = reconPlayGameSettings.ModelName,
Sn = reconPlayGameSettings.Sn,
ScId = reconPlayGameRequest.ScId,
DisplayGrade = reconPlayGameRequest.DisplayGrade,
Cpu = reconPlayGameRequest.Cpu,
ModelName = reconPlayGameRequest.ModelName,
};
var response = await JYApi.ReconPlayGame(setting);
if (response.IsSuccess)
var jyResponseData = await JYApi.ReconPlayGame(setting);
if (jyResponseData.IsSuccess)
{
return new BaseResponse<object>(ResponseCode.Success, "", response.Data) { };
var gameInfo = await PlayGameExtend.PlayGameRecon(this, _UserId, reconPlayGameRequest.ScId);
var gameResponse1 = JsonConvert.DeserializeObject<Dictionary<string, object>>(jyResponseData.ResponseContent);
if (gameResponse1 != null && gameResponse1.TryGetValue("data", out var xxx))
{
if (gameInfo != null)
{
await gameInfo.SaveChangesAsync(this);
}
return new BaseResponse<dynamic>(ResponseCode.Success, "", new { GameId = gameInfo?.GameId, GameData = JsonConvert.SerializeObject(xxx) });
}
}
throw response.ToMessageBox();
throw jyResponseData.ToMessageBox();
}
}

View File

@ -1,4 +1,7 @@
using AgileConfig.Client;
using CloudGaming.Code.DataAccess;
using CloudGaming.Code.DataAccess.MultiTenantUtil;
using CloudGaming.DtoModel.Account.User;
using CloudGaming.DtoModel.Game;
using CloudGaming.DtoModel.JY;
@ -8,13 +11,35 @@ using HuanMeng.DotNetCore.Redis;
using Newtonsoft.Json;
using StackExchange.Redis;
using System.Runtime.CompilerServices;
namespace CloudGaming.Code.Game
{
public static class PlayGameExtend
{
private static string GetPlayGameKey(string gameId, int userId) => $"PlayGame:{gameId}:{userId}";
/// <summary>
/// 初始化app
/// </summary>
/// <param name="builder"></param>
/// <returns></returns>
public static IHostApplicationBuilder AddPlayGameServer(this WebApplicationBuilder builder)
{
builder.Services.AddHostedService<PlayGameService>();
return builder;
}
/// <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>
/// 获取用户游戏缓存
/// </summary>
@ -91,7 +116,7 @@ namespace CloudGaming.Code.Game
}
/// <summary>
/// 初始化
/// 结束游戏
/// </summary>
/// <param name="playGameUserInfo"></param>
/// <param name="sn"></param>
@ -104,10 +129,10 @@ namespace CloudGaming.Code.Game
if (playGameUserInfo.GameStatus != PlayGameStatus.)
{
playGameUserInfo.GameStatus = PlayGameStatus.;
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation()
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation(jYApiRespnse)
{
OperationDateTime = DateTime.Now,
Content = "游戏结束"
Content = "游戏结束",
});
playGameUserInfo.LastDateTime = DateTime.Now;
}
@ -176,6 +201,15 @@ namespace CloudGaming.Code.Game
{
if (playGameUserInfo.GameStatus != PlayGameStatus.)
{
if (playGameUserInfo.GameStatus == PlayGameStatus.线)
{
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation()
{
OperationDateTime = DateTime.Now,
Content = "用户游戏掉线重连成功",
});
}
playGameUserInfo.GameStatus = PlayGameStatus.;
}
playGameUserInfo.PlayGameHeartbeatAt = DateTime.Now;
@ -279,6 +313,80 @@ namespace CloudGaming.Code.Game
return true;
}
/// <summary>
/// 游戏掉线
/// </summary>
/// <param name="playGameUserInfo"></param>
/// <returns></returns>
public static bool PlayGameUserNotAction(this PlayGameUserInfo playGameUserInfo)
{
if (playGameUserInfo.GameStatus != PlayGameStatus.线)
{
playGameUserInfo.GameStatus = PlayGameStatus.线;
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation()
{
Content = $"用户游戏掉线,上一次心跳时间{playGameUserInfo.PlayGameHeartbeatAt?.ToString("yyyy-MM-dd HH:mm:ss")};",
OperationDateTime = DateTime.Now,
});
}
return true;
}
/// <summary>
///
/// </summary>
/// <param name="redis"></param>
/// <param name="redisServer"></param>
/// <param name="keyPattern"></param>
/// <returns></returns>
public static async Task<List<PlayGameUserInfo?>> GetPlayGameUserInfoList(IDatabase redis, IServer redisServer, string keyPattern)
{
var keys = await redisServer.ScanKeysAsync(keyPattern, 2000).ConfigureAwait(false);
var tasks = keys.Select(async gameKey =>
{
var gameInfo = await redis.StringGetAsync<PlayGameUserInfo>(gameKey).ConfigureAwait(false);
return gameInfo;
});
var gameInfoList = (await Task.WhenAll(tasks).ConfigureAwait(false)).Where(x => x != null).ToList();
return gameInfoList;
}
/// <summary>
/// 游戏掉线
/// </summary>
/// <param name="playGameUserInfo"></param>
/// <returns></returns>
public static async Task<PlayGameUserInfo> PlayGameRecon(CloudGamingBase cloudGamingBase, int userId, int scId)
{
var list = await GetPlayGameUserInfoList(cloudGamingBase.RedisCache, cloudGamingBase.RedisServerCache, $"{GetPlayGameKeyPrefix}:*:{userId}");
if (list != null && list.Count > 0)
{
var playGameUserInfo = list.Where(it => it.ScId == scId).FirstOrDefault();
if (playGameUserInfo == null)
{
playGameUserInfo = list[0];
}
if (playGameUserInfo != null)
{
if (playGameUserInfo.GameStatus != PlayGameStatus.线)
{
playGameUserInfo.GameStatus = PlayGameStatus.线;
playGameUserInfo.GameUserOperation.Add(new PlayGameUserOperation()
{
Content = $"用户游戏掉线,上一次心跳时间{playGameUserInfo.PlayGameHeartbeatAt?.ToString("yyyy-MM-dd HH:mm:ss")};",
OperationDateTime = DateTime.Now,
});
}
}
return playGameUserInfo;
}
return null;
}
/// <summary>
/// 保存缓存到redis中
/// </summary>
@ -286,6 +394,19 @@ namespace CloudGaming.Code.Game
/// <param name="cloudGamingBase"></param>
/// <returns></returns>
public static async Task<bool> SaveChangesAsync(this PlayGameUserInfo playGameUserInfo, CloudGamingBase cloudGamingBase)
{
return await SaveChangesAsync(playGameUserInfo, cloudGamingBase.Dao, cloudGamingBase.RedisCache);
}
/// <summary>
/// 保存缓存到redis中
/// </summary>
/// <param name="playGameUserInfo"></param>
/// <param name="dao"></param>
/// <param name="redisDatabase"></param>
/// <returns></returns>
public static async Task<bool> SaveChangesAsync(this PlayGameUserInfo playGameUserInfo, DAO dao, IDatabase redisDatabase)
{
playGameUserInfo.LastDateTime = DateTime.Now;
var redisGameKey = GetPlayGameKey(playGameUserInfo.GameId, playGameUserInfo.UserId);
@ -294,7 +415,7 @@ namespace CloudGaming.Code.Game
if (playGameUserInfo.DiamondListId > 0)
{
//设置游玩记录
var userGameListLog = await cloudGamingBase.Dao.DaoPhone.Context.T_User_GameList.FirstOrDefaultAsync(it => it.Id == playGameUserInfo.DiamondListId);
var userGameListLog = await dao.DaoPhone.Context.T_User_GameList.FirstOrDefaultAsync(it => it.Id == playGameUserInfo.DiamondListId);
if (userGameListLog != null)
{
userGameListLog.Status = (int)PlayGameStatus.;
@ -304,12 +425,12 @@ namespace CloudGaming.Code.Game
userGameListLog.PlaySeconds = (int)t.TotalSeconds;
userGameListLog.PlayTime = playTime;
userGameListLog.UpdateTime = DateTime.Now;
await cloudGamingBase.Dao.DaoPhone.Context.SaveChangesAsync();
await dao.DaoPhone.Context.SaveChangesAsync();
//设置游玩历史
var userId = playGameUserInfo.UserId;
var gameId = playGameUserInfo.GameId;
//设置用户游玩历史
var playGameTime = await cloudGamingBase.Dao.DaoPhone.Context.T_User_PlayGameTime.Where(it => it.UserId == userId && it.GameId == gameId).FirstOrDefaultAsync();
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()
@ -323,26 +444,25 @@ namespace CloudGaming.Code.Game
UpdateTime = DateTime.Now,
UserId = userId,
};
await cloudGamingBase.Dao.DaoPhone.Context.T_User_PlayGameTime.AddAsync(playGameTime);
await dao.DaoPhone.Context.T_User_PlayGameTime.AddAsync(playGameTime);
}
playGameTime.PlayTime += playTime;
playGameTime.UpdateTime = DateTime.Now;
playGameTime.DiamondPlayTime += playTime;
await cloudGamingBase.Dao.DaoPhone.Context.SaveChangesAsync();
await dao.DaoPhone.Context.SaveChangesAsync();
}
}
var playGameLog = playGameUserInfo.ToGamePlayGameLog();
if (playGameLog != null)
{
await cloudGamingBase.Dao.DaoPhone.Context.T_Game_PlayGameLog.AddAsync(playGameLog);
await cloudGamingBase.Dao.DaoPhone.Context.SaveChangesAsync();
await dao.DaoPhone.Context.T_Game_PlayGameLog.AddAsync(playGameLog);
await dao.DaoPhone.Context.SaveChangesAsync();
}
return await cloudGamingBase.RedisCache.KeyDeleteAsync(redisGameKey);
return await redisDatabase.KeyDeleteAsync(redisGameKey);
}
return await cloudGamingBase.RedisCache.StringSetAsync(redisGameKey, playGameUserInfo, TimeSpan.FromMinutes(10));
return await redisDatabase.StringSetAsync(redisGameKey, playGameUserInfo, TimeSpan.FromMinutes(10));
}
}
}

View File

@ -0,0 +1,119 @@
using CloudGaming.Code.AppExtend;
using CloudGaming.Code.Contract;
using CloudGaming.Code.DataAccess;
using CloudGaming.Code.JY;
using CloudGaming.DtoModel.PlayGame;
using Flurl.Util;
using HuanMeng.DotNetCore.Processors;
using Microsoft.Extensions.DependencyInjection;
using Refit;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static SKIT.FlurlHttpClient.Wechat.TenpayV3.Models.CreatePayDevicePrinterPrintOrderRequest.Types.Table.Types;
namespace CloudGaming.Code.Game;
/// <summary>
/// 游戏服务
/// </summary>
public class PlayGameProcessor(IServiceProvider serviceProvider) : ThreadProcessor
{
protected override async void Proc_Do()
{
while (_isRunning)
{
// 多项目配置
var appConfigs = AppConfigurationExtend.AppConfigs
.Select(it => it.Value)
.Where(it => it.DomainName != "default")
.ToList();
var tasks = appConfigs.Select(ProcessAppConfig).ToList();
// 等待所有任务完成
await Task.WhenAll(tasks);
// 使用异步延迟代替阻塞线程
await Task.Delay(5);
}
}
private async Task ProcessAppConfig(AppConfig appConfig)
{
var userNotActionDisconnect = DateTime.Now.AddSeconds(-appConfig.GameConfig.UserNotActionDisconnect);
var userNotActionEndGame = DateTime.Now.AddSeconds(-appConfig.GameConfig.UserNotActionEndGame);
using var scope = serviceProvider.CreateScope();
var dao = scope.ServiceProvider.GetDAO(appConfig);
var redis = appConfig.GetRedisDataBase();
var redisServer = appConfig.GetRedisServer();
var keyPattern = $"{PlayGameExtend.GetPlayGameKeyPrefix}:*";
List<PlayGameUserInfo?> gameInfoList = await GetPlayGameUserInfoList(redis, redisServer, keyPattern).ConfigureAwait(false);
// 处理未操作断线的玩家
var userPlayGameNotActionEndGame = gameInfoList
.Where(it => it.GameStatus == PlayGameStatus.线 && it.PlayGameHeartbeatAt < userNotActionEndGame)
.ToList();
foreach (var user in userPlayGameNotActionEndGame)
{
await EndGameAsync(user, appConfig, dao, redis).ConfigureAwait(false);
gameInfoList.Remove(user);
}
// 处理未操作标记为掉线的玩家
var userPlayGameNotAction = gameInfoList
.Where(it => it.GameStatus == PlayGameStatus. && it.PlayGameHeartbeatAt < userNotActionDisconnect)
.ToList();
foreach (var user in userPlayGameNotAction)
{
//将用户标记为短线状态
user.PlayGameUserNotAction();
await user.SaveChangesAsync(dao, redis).ConfigureAwait(false);
}
}
public static async Task<List<PlayGameUserInfo?>> GetPlayGameUserInfoList(IDatabase redis, IServer redisServer, string keyPattern)
{
var keys = await redisServer.ScanKeysAsync(keyPattern, 2000).ConfigureAwait(false);
var tasks = keys.Select(async gameKey =>
{
var gameInfo = await redis.StringGetAsync<PlayGameUserInfo>(gameKey).ConfigureAwait(false);
return gameInfo;
});
var gameInfoList = (await Task.WhenAll(tasks).ConfigureAwait(false)).Where(x => x != null).ToList();
return gameInfoList;
}
private async Task EndGameAsync(PlayGameUserInfo user, AppConfig appConfig, DAO dao, IDatabase redis)
{
using HttpClient httpClient = new HttpClient(new JYApiAppConfigHandler(appConfig, user.Ip));
var jyApi = RestService.For<IJYApi>(httpClient);
var playGameCommonSetting = new PlayGameCommonSetting
{
ScId = user.ScId,
Sn = user.Sn
};
var jyResponse = await jyApi.StopGame(playGameCommonSetting).ConfigureAwait(false);
user.ExitPlayGame(jyResponse);
await user.SaveChangesAsync(dao, redis).ConfigureAwait(false);
}
}

View File

@ -6,16 +6,29 @@ using System.Threading.Tasks;
namespace CloudGaming.Code.Game;
/// <summary>
/// 玩游戏服务
/// </summary>
/// <param name="serviceProvider"></param>
public class PlayGameService(IServiceProvider serviceProvider) : IHostedService
{
PlayGameProcessor? playGameProcessor = null;
public Task StartAsync(CancellationToken cancellationToken)
{
//AppConfigurationExtend.AppConfigs.Select(it => it.Value).Where(it => it.DomainName != "default").ToList();
throw new NotImplementedException();
AppConfigurationExtend.AppConfigs.Select(it => it.Value).Where(it => it.DomainName != "default").ToList();
//throw new NotImplementedException();
playGameProcessor = new PlayGameProcessor(serviceProvider) { };
playGameProcessor.Run();
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
throw new NotImplementedException();
if (playGameProcessor != null)
{
playGameProcessor.Stop();
playGameProcessor.Dispose();
}
return Task.CompletedTask;
}
}

View File

@ -0,0 +1,56 @@
using CloudGaming.AppConfigModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.Code.JY
{
public class JYApiAppConfigHandler : JYApiHandler
{
protected AppConfig AppConfig { get; set; }
protected string Ip { get; set; }
public JYApiAppConfigHandler(AppConfig appConfig, string ip) : base(null)
{
AppConfig = appConfig;
Ip = ip;
}
//protected new async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
//{
// try
// {
// await SetRequest(request);
// var sw = Stopwatch.StartNew();
// var response = await base.SendAsync(request, cancellationToken);
// sw.Stop();
// if (response.IsSuccessStatusCode)
// {
// await AttachDebugInfoAsync(request, response, sw.Elapsed.TotalMilliseconds.ToString());
// }
// return response;
// }
// catch (Exception ex)
// {
// // 可根据实际需要扩展异常处理逻辑
// throw new HttpRequestException("发送请求时发生错误。", ex);
// }
//}
protected override async Task SetRequest(HttpRequestMessage request)
{
UpdateRequestUri(request, AppConfig.GameConfig.BsUrl);
if (request.Content is FormUrlEncodedContent)
{
await UpdateRequestContentAsync(request, AppConfig, Ip);
}
}
}
}

View File

@ -1,3 +1,5 @@
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@ -10,11 +12,14 @@ namespace CloudGaming.Code.JY;
/// </summary>
public class JYApiHandler : DelegatingHandler
{
private readonly IHttpContextAccessor _httpContextAccessor;
protected readonly IHttpContextAccessor _httpContextAccessor;
public JYApiHandler(IHttpContextAccessor httpContextAccessor)
public JYApiHandler(IHttpContextAccessor? httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
if (httpContextAccessor != null)
{
_httpContextAccessor = httpContextAccessor;
}
}
/// <summary>
@ -24,21 +29,7 @@ public class JYApiHandler : DelegatingHandler
{
try
{
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null)
throw new InvalidOperationException("无法获取HttpContext。");
var host = httpContext.Request.Host.Host;
var app = AppConfigurationExtend.GetAppConfig(host);
if (app != null)
{
UpdateRequestUri(request, app.GameConfig.BsUrl);
if (request.Content is FormUrlEncodedContent)
{
await UpdateRequestContentAsync(request, app, httpContext);
}
}
await SetRequest(request);
var sw = Stopwatch.StartNew();
var response = await base.SendAsync(request, cancellationToken);
sw.Stop();
@ -46,7 +37,6 @@ public class JYApiHandler : DelegatingHandler
{
await AttachDebugInfoAsync(request, response, sw.Elapsed.TotalMilliseconds.ToString());
}
return response;
}
catch (Exception ex)
@ -56,10 +46,36 @@ public class JYApiHandler : DelegatingHandler
}
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
protected virtual async Task SetRequest(HttpRequestMessage request)
{
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null)
throw new InvalidOperationException("无法获取HttpContext。");
var host = httpContext.Request.Host.Host;
var app = AppConfigurationExtend.GetAppConfig(host);
if (app != null)
{
UpdateRequestUri(request, app.GameConfig.BsUrl);
if (request.Content is FormUrlEncodedContent)
{
await UpdateRequestContentAsync(request, app, httpContext.GetClientIpAddress());
}
}
}
/// <summary>
/// 更新请求的URI
/// </summary>
private void UpdateRequestUri(HttpRequestMessage request, string baseUrl)
protected void UpdateRequestUri(HttpRequestMessage request, string baseUrl)
{
var newUri = new Uri(new Uri(baseUrl), request.RequestUri.PathAndQuery);
request.RequestUri = newUri;
@ -68,12 +84,12 @@ public class JYApiHandler : DelegatingHandler
/// <summary>
/// 更新请求内容
/// </summary>
private async Task UpdateRequestContentAsync(HttpRequestMessage request, dynamic app, HttpContext httpContext)
protected async Task UpdateRequestContentAsync(HttpRequestMessage request, AppConfig app, string ip)
{
var formData = await request.Content.ReadAsStringAsync();
var parameters = ParseFormData(formData);
AddDefaultParameters(parameters, app, httpContext);
AddDefaultParameters(parameters, app, ip);
var signKey = GenerateSignature(parameters, app.GameConfig.SignKey);
var encryptedParameters = $"{ConvertDictionaryToPostData(parameters)}&sign={signKey}";
@ -84,7 +100,7 @@ public class JYApiHandler : DelegatingHandler
/// <summary>
/// 添加默认参数
/// </summary>
private void AddDefaultParameters(SortedDictionary<string, object> parameters, dynamic app, HttpContext httpContext)
protected void AddDefaultParameters(SortedDictionary<string, object> parameters, AppConfig app, string ip)
{
if (!parameters.ContainsKey("channel_id"))
{
@ -93,7 +109,7 @@ public class JYApiHandler : DelegatingHandler
if (!parameters.ContainsKey("ip"))
{
parameters["ip"] = httpContext.GetClientIpAddress();
parameters["ip"] = ip;
}
if (!parameters.ContainsKey("time"))
@ -105,7 +121,7 @@ public class JYApiHandler : DelegatingHandler
/// <summary>
/// 生成签名
/// </summary>
private string GenerateSignature(SortedDictionary<string, object> parameters, string signKey)
protected string GenerateSignature(SortedDictionary<string, object> parameters, string signKey)
{
var dataString = string.Join("&", parameters.Select(kv => $"{kv.Key}={kv.Value}")) + $"&key={signKey}";
return MD5Encryption.ComputeMD5Hash(dataString).ToUpper();
@ -114,7 +130,7 @@ public class JYApiHandler : DelegatingHandler
/// <summary>
/// 附加调试信息到响应
/// </summary>
private async Task AttachDebugInfoAsync(HttpRequestMessage request, HttpResponseMessage response, string totalMilliseconds)
protected async Task AttachDebugInfoAsync(HttpRequestMessage request, HttpResponseMessage response, string totalMilliseconds)
{
var responseContent = await response.Content.ReadAsStringAsync();
var responseJson = JsonConvert.DeserializeObject<JObject>(responseContent);
@ -131,7 +147,7 @@ public class JYApiHandler : DelegatingHandler
/// <summary>
/// 序列化HTTP响应
/// </summary>
private string SerializeResponse(HttpResponseMessage response, string content)
protected string SerializeResponse(HttpResponseMessage response, string content)
{
return JsonConvert.SerializeObject(new
{
@ -144,7 +160,7 @@ public class JYApiHandler : DelegatingHandler
/// <summary>
/// 解析表单数据
/// </summary>
private SortedDictionary<string, object> ParseFormData(string formData)
protected SortedDictionary<string, object> ParseFormData(string formData)
{
var parameters = new SortedDictionary<string, object>();
var pairs = formData.Split('&');
@ -164,7 +180,7 @@ public class JYApiHandler : DelegatingHandler
/// <summary>
/// 将字典转换为POST数据格式
/// </summary>
private string ConvertDictionaryToPostData(SortedDictionary<string, object> dictionary)
protected string ConvertDictionaryToPostData(SortedDictionary<string, object> dictionary)
{
return string.Join("&", dictionary.Select(kv => $"{kv.Key}={kv.Value}"));
}

View File

@ -25,5 +25,21 @@ namespace CloudGaming.AppConfigModel
/// 客户渠道地址
/// </summary>
public string BsUrl { get; set; }
/// <summary>
/// 用户多少秒后可以重连会话,必须小于结束游戏前
/// </summary>
public int UserReconnectTime { get; set; }
/// <summary>
/// 用户没有心跳后多少秒判断掉线
/// </summary>
public int UserNotActionDisconnect { get; set; }
/// <summary>
/// 用户没有心跳后多少秒结束游戏
/// </summary>
public int UserNotActionEndGame { get; set; }
}
}

View File

@ -1,3 +1,5 @@
using CloudGaming.DtoModel.JY;
using System;
using System.Collections.Generic;
using System.Linq;
@ -10,11 +12,15 @@ namespace CloudGaming.DtoModel.PlayGame
/// <summary>
/// 切换视频
/// </summary>
public class DisplayGradeSettings : PlayGameCommonSetting
public class DisplayGradeSettings : JYRequestParameter// PlayGameCommonSetting
{
public DisplayGradeSettings() { }
/// <summary>
/// 本次游戏连接会话 id
/// </summary>
[JsonPropertyName("sc_id")]
public int ScId { get; set; }
/// <summary>
/// 显示等级,可在后台配置,默认为 1
/// </summary>

View File

@ -141,6 +141,11 @@ public class PlayGameUserInfo
/// </summary>
public int DiamondListId { get; set; }
/// <summary>
/// ip地址
/// </summary>
public string Ip { get; set; }
/// <summary>
/// 转化成数据库实体类
/// </summary>

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace CloudGaming.DtoModel.PlayGame;
/// <summary>
/// 重连会话
/// </summary>
public class ReconPlayGameRequest : PlayGameCommonSetting
{
public ReconPlayGameRequest() { }
/// <summary>
/// 显示等级,可在后台配置,默认为 1
/// </summary>
[JsonPropertyName("display_grade")]
public int? DisplayGrade { get; set; } = 1; // 默认值为 1
/// <summary>
/// 设备型号
/// </summary>
[JsonPropertyName("model_name")]
public string ModelName { get; set; }
/// <summary>
/// 芯片
/// </summary>
[JsonPropertyName("cpu")]
public string Cpu { get; set; }
}

View File

@ -1,3 +1,5 @@
using CloudGaming.DtoModel.JY;
using System;
using System.Collections.Generic;
using System.Linq;
@ -10,13 +12,17 @@ namespace CloudGaming.DtoModel.PlayGame
/// <summary>
/// 重连会话
/// </summary>
public class ReconPlayGameSettings : PlayGameCommonSetting
public class ReconPlayGameSettings : JYRequestParameter// PlayGameCommonSetting
{
public ReconPlayGameSettings() { }
public ReconPlayGameSettings(string sn, int userId) : base(sn, userId)
{
}
/// <summary>
/// 会话 id
/// 本次游戏连接会话 id
/// </summary>
[JsonPropertyName("sc_id")]
public int ScId { get; set; }