oss测试

This commit is contained in:
wuwenbo 2026-03-11 14:55:01 +08:00
parent 2ee0d995df
commit 1a19aa9dd7
9 changed files with 126 additions and 32 deletions

View File

@ -9,7 +9,7 @@ const TableStore = require('tablestore');
const MAX_BODY_SIZE = 1024;
const PORT = 9000;
const TOKEN_CACHE_DURATION_MS = 5 * 60 * 1000; // 5分钟
const MAX_UPLOAD_SIZE = 2 * 1024 * 1024; // 2MB
const MAX_UPLOAD_SIZE = 3 * 1024 * 1024; // 3MB
const STS_DURATION_SECONDS = 900; // 15分钟
/**
@ -26,8 +26,10 @@ function getOtsClient() {
/**
* Tablestore 获取缓存的令牌
* @param {string} steamId
* @param {string|null} version 客户端版本号null 表示老版本未传
*/
async function getCachedToken(steamId) {
async function getCachedToken(steamId, version) {
const otsClient = getOtsClient();
const params = {
@ -54,6 +56,14 @@ async function getCachedToken(steamId) {
: value;
}
// 版本号比对:缓存中存储的版本号(无版本号时为空字符串或不存在)
const cachedVersion = attrs.version || null;
const requestVersion = version || null;
if (cachedVersion !== requestVersion) {
console.log(`[缓存查询] SteamID: ${steamId} 版本号不匹配,缓存版本: ${cachedVersion ?? '(无)'}, 请求版本: ${requestVersion ?? '(无)'},忽略缓存`);
return null;
}
const issuedAt = attrs.issuedAt;
if (!issuedAt || Date.now() - issuedAt > TOKEN_CACHE_DURATION_MS) {
console.log(`[缓存查询] SteamID: ${steamId} 缓存已过期(签发时间: ${new Date(issuedAt).toISOString()}`);
@ -68,7 +78,7 @@ async function getCachedToken(steamId) {
}
const expiresIn = Math.floor((stsExpireAt - Date.now()) / 1000);
console.log(`[缓存命中] SteamID: ${steamId} 命中缓存,剩余有效期 ${expiresIn}`);
console.log(`[缓存命中] SteamID: ${steamId} 命中缓存,版本: ${cachedVersion ?? '(无)'}剩余有效期 ${expiresIn}`);
return {
accessKeyId: attrs.accessKeyId,
@ -89,34 +99,41 @@ async function getCachedToken(steamId) {
/**
* 将令牌存入 Tablestore
* @param {string} steamId
* @param {object} tokenData
* @param {string|null} version 客户端版本号null 表示老版本未传
*/
async function saveTokenToCache(steamId, tokenData) {
async function saveTokenToCache(steamId, tokenData, version) {
const otsClient = getOtsClient();
const now = Date.now();
const stsExpireAt = now + tokenData.expiresIn * 1000;
const attributeColumns = [
{ accessKeyId: tokenData.accessKeyId },
{ accessKeySecret: tokenData.accessKeySecret },
{ securityToken: tokenData.securityToken },
{ endpoint: tokenData.endpoint },
{ bucket: tokenData.bucket },
{ objectKey: tokenData.objectKey },
{ policy: tokenData.policy },
{ signature: tokenData.signature },
{ issuedAt: TableStore.Long.fromNumber(now) },
{ stsExpireAt: TableStore.Long.fromNumber(stsExpireAt) },
// version 为 null 时存空字符串,与查询时保持一致
{ version: version !== null && version !== undefined ? version : '' }
];
const params = {
tableName: 'Players',
condition: new TableStore.Condition(TableStore.RowExistenceExpectation.IGNORE, null),
primaryKey: [{ PlayerId: steamId }],
attributeColumns: [
{ accessKeyId: tokenData.accessKeyId },
{ accessKeySecret: tokenData.accessKeySecret },
{ securityToken: tokenData.securityToken },
{ endpoint: tokenData.endpoint },
{ bucket: tokenData.bucket },
{ objectKey: tokenData.objectKey },
{ policy: tokenData.policy },
{ signature: tokenData.signature },
{ issuedAt: TableStore.Long.fromNumber(now) },
{ stsExpireAt: TableStore.Long.fromNumber(stsExpireAt) }
],
attributeColumns,
returnContent: { returnType: TableStore.ReturnType.NONE }
};
try {
console.log(`[缓存写入] 正在写入 SteamID: ${steamId} 的令牌缓存...`);
console.log(`[缓存写入] 正在写入 SteamID: ${steamId} 的令牌缓存,版本: ${version ?? '(无)'}...`);
await otsClient.putRow(params);
console.log(`[缓存写入] SteamID: ${steamId} 缓存写入成功,过期时间: ${new Date(stsExpireAt).toISOString()}`);
} catch (e) {
@ -270,6 +287,10 @@ async function handleRequest(req, res) {
try {
const requestData = JSON.parse(body || '{}');
const { steamId, authTicket } = requestData;
// version 为可选字段,老版本不传则为 null
const version = (typeof requestData.version === 'string' && requestData.version.trim() !== '')
? requestData.version.trim()
: null;
if (!steamId) {
console.warn('[参数校验] 缺少 steamId 参数');
@ -286,10 +307,10 @@ async function handleRequest(req, res) {
}
const requestId = req.headers['x-fc-request-id'] || '-';
console.log(`[请求开始] RequestId: ${requestId}SteamID: ${steamId}AuthTicket长度: ${authTicket.length}`);
console.log(`[请求开始] RequestId: ${requestId}SteamID: ${steamId}AuthTicket长度: ${authTicket.length},版本: ${version ?? '(无)'}`);
// 1. 先检查 Tablestore 缓存
const cachedToken = await getCachedToken(steamId);
// 1. 先检查 Tablestore 缓存(版本号必须一致才命中)
const cachedToken = await getCachedToken(steamId, version);
if (cachedToken) {
console.log(`[请求完成] RequestId: ${requestId}SteamID: ${steamId} — 返回缓存令牌,剩余有效期 ${cachedToken.expiresIn}`);
res.writeHead(200, { 'Content-Type': 'application/json' });
@ -316,7 +337,10 @@ async function handleRequest(req, res) {
apiVersion: '2015-04-01'
});
const objectKey = `${steamId}/${Date.now()}.dat`;
// 根据版本号构建文件路径:有版本号时为 {version}/{steamId}/...,无版本号时为 common/{steamId}/...
const pathPrefix = version !== null ? version : 'common';
const objectKey = `${pathPrefix}/${steamId}/${Date.now()}.dat`;
console.log(`[路径构建] SteamID: ${steamId},版本: ${version ?? '(无)'}ObjectKey: ${objectKey}`);
const stsParams = {
RoleArn: process.env.ROLE_ARN,
@ -356,8 +380,8 @@ async function handleRequest(req, res) {
expiresIn: STS_DURATION_SECONDS
};
// 5. 存入 Tablestore 缓存
await saveTokenToCache(steamId, tokenData);
// 5. 存入 Tablestore 缓存(携带版本号)
await saveTokenToCache(steamId, tokenData, version);
console.log(`[请求完成] RequestId: ${requestId}SteamID: ${steamId} 全流程完成 ✅(验证 → 签发 → Policy → 缓存)`);
@ -376,4 +400,4 @@ async function handleRequest(req, res) {
const server = http.createServer(handleRequest);
server.listen(PORT, '0.0.0.0', () => {
console.log(`[服务启动] 服务器已启动,监听端口: ${PORT},最大上传文件: ${MAX_UPLOAD_SIZE} 字节`);
})
})

View File

@ -1326,13 +1326,13 @@ namespace RuntimeData
}
// 当场上有小兵死亡时
public void OnAnyUnitDie(MapData map)
public void OnAnyUnitDie(MapData map, UnitData dieUnit)
{
foreach (var unit in UnitMap.UnitList)
{
//避免在遍历的时候直接改到了skillsList
var copy = new List<SkillBase>(unit.Skills);
foreach (var skill in copy) skill.OnAnyUnitDie(map, unit);
foreach (var skill in copy) skill.OnAnyUnitDie(map, unit, dieUnit);
}
}

View File

@ -40,7 +40,7 @@ namespace Logic.Config
{
if (version.VersionId == versionId) return version;
}
return null;
return Versions[0];
}

View File

@ -7,7 +7,9 @@
using System;
using System.IO;
using System.Text;
using MemoryPack;
using Steamworks;
using TH1_Logic.Net;
using TH1_Logic.Oss;
@ -86,6 +88,11 @@ namespace Logic.Editor
if (InspectorUtils.InspectorButtonWithTextWidth("测试5: 上传文件到OSS(大文件)"))
{
TestUploadBigFile();
}
if (InspectorUtils.InspectorButtonWithTextWidth("测试存档反序列化"))
{
TestDeserializeArchive();
}
EditorGUILayout.EndScrollView();
@ -209,5 +216,60 @@ namespace Logic.Editor
? "<color=green>完整流程测试成功!</color>"
: "<color=red>完整流程测试失败</color>");
}
// 测试存档反序列化
public void TestDeserializeArchive()
{
string path = "F:/gamerecord/";
if (!Directory.Exists(path))
{
Debug.LogError($"路径不存在: {path}");
return;
}
var datFiles = Directory.GetFiles(path, "*.dat");
if (datFiles.Length == 0)
{
Debug.LogWarning($"路径下没有找到 .dat 文件: {path}");
return;
}
Debug.Log($"=== 开始测试存档反序列化,共找到 {datFiles.Length} 个文件 ===");
int successCount = 0;
int failCount = 0;
foreach (var filePath in datFiles)
{
string fileName = Path.GetFileName(filePath);
try
{
byte[] data = File.ReadAllBytes(filePath);
Debug.Log($"读取文件: {fileName}, 大小: {data.Length} bytes");
var ossData = MemoryPackSerializer.Deserialize<OssData>(data);
if (ossData != null)
{
Debug.Log($"<color=green>[成功] {fileName} 反序列化成功</color>");
successCount++;
}
else
{
Debug.LogError($"<color=red>[失败] {fileName} 反序列化结果为 null</color>");
failCount++;
}
}
catch (Exception ex)
{
Debug.LogError($"<color=red>[异常] {fileName} 反序列化失败: {ex.Message}</color>");
failCount++;
}
}
Debug.Log($"=== 反序列化完成: 成功 {successCount} / 失败 {failCount} / 共 {datFiles.Length} 个文件 ===");
}
}
}

View File

@ -2,6 +2,7 @@
using System.Text;
using System.Threading.Tasks;
using Logic.CrashSight;
using TH1_Logic.Config;
using UnityEngine;
using UnityEngine.Networking;
@ -35,7 +36,8 @@ namespace TH1_Logic.Oss
var requestBody = JsonUtility.ToJson(new StsRequest
{
steamId = steamId,
authTicket = authTicket
authTicket = authTicket,
version = ConfigManager.Instance.VersionCfg.CurVersionInfo.Version,
});
var bodyBytes = Encoding.UTF8.GetBytes(requestBody);
@ -65,6 +67,7 @@ namespace TH1_Logic.Oss
{
public string steamId;
public string authTicket;
public string version;
}
}
}

View File

@ -50,7 +50,7 @@ namespace Logic.Skill
RefreshAroundGiant(map, self);
}
public override void OnAnyUnitDie(MapData map, UnitData self)
public override void OnAnyUnitDie(MapData map, UnitData self, UnitData dieUnit)
{
RefreshAroundGiant(map, self);
}

View File

@ -23,6 +23,11 @@ namespace Logic.Skill
{
return SkillType.RinCorpseCollet;
}
public override void OnAnyUnitDie(MapData map, UnitData self, UnitData dieUnit)
{
}
}
}

View File

@ -366,7 +366,7 @@ namespace Logic.Skill
public void OnAnyUnitMove(MapData map, UnitData self, UnitData moveUnit, GridData target, MoveType moveType);
// 当有单位死亡时
public void OnAnyUnitDie(MapData map, UnitData self);
public void OnAnyUnitDie(MapData map, UnitData self, UnitData dieUnit);
// 当有单位创建时
public void OnAnyUnitCreate(MapData map, UnitData self, UnitData newUnit);
@ -797,7 +797,7 @@ namespace Logic.Skill
}
public virtual void OnAnyUnitDie(MapData map, UnitData self)
public virtual void OnAnyUnitDie(MapData map, UnitData self, UnitData dieUnit)
{
}

View File

@ -594,8 +594,8 @@ namespace Logic
});
}
map.OnAnyUnitDie(map, unit);
map.SetUnitDataDie(unit);
map.OnAnyUnitDie(map);
}
//unit非自然死亡如背盟、国家灭亡、解散、被挤死等