Compare commits
4 Commits
2a8ab3265d
...
a36516db60
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a36516db60 | ||
|
|
aca8e46eaa | ||
|
|
b7bd2c612b | ||
|
|
424c9490e7 |
File diff suppressed because it is too large
Load Diff
@@ -20,5 +20,88 @@
|
|||||||
"role_hp": "生命",
|
"role_hp": "生命",
|
||||||
"role_power": "力量",
|
"role_power": "力量",
|
||||||
"role_physical": "体质",
|
"role_physical": "体质",
|
||||||
"role_agile": "敏捷"
|
"role_agile": "敏捷",
|
||||||
|
"heros": "英雄",
|
||||||
|
|
||||||
|
"htype_melee": "近战",
|
||||||
|
"htype_mid": "中程",
|
||||||
|
"htype_long": "远程",
|
||||||
|
|
||||||
|
"hero_name_5001": "盾战士",
|
||||||
|
"hero_name_5002": "圣骑士",
|
||||||
|
"hero_name_5003": "风行剑士",
|
||||||
|
"hero_name_5004": "刺客",
|
||||||
|
"hero_name_5005": "自然骑士",
|
||||||
|
"hero_name_5101": "奥术法师",
|
||||||
|
"hero_name_5102": "火焰法师",
|
||||||
|
"hero_name_5103": "冰法法师",
|
||||||
|
"hero_name_5104": "寒霜术士",
|
||||||
|
"hero_name_5105": "炎爆法师",
|
||||||
|
"hero_name_5201": "射手",
|
||||||
|
"hero_name_5202": "游侠",
|
||||||
|
"hero_name_5203": "游侠",
|
||||||
|
"hero_name_5301": "牧师",
|
||||||
|
"hero_name_5302": "战地医师",
|
||||||
|
"hero_name_5303": "守护祭司",
|
||||||
|
"hero_name_5304": "秘法精灵",
|
||||||
|
|
||||||
|
"hero_info_5001": "近战,魔法盾 坦克",
|
||||||
|
"hero_info_5002": "近战,群体护盾 坦克",
|
||||||
|
"hero_info_5003": "近战,闪击 近战dps",
|
||||||
|
"hero_info_5004": "近战,火焰击 近战dps",
|
||||||
|
"hero_info_5005": "治疗近战,火焰击 近战dps",
|
||||||
|
"hero_info_5101": "冰球,冰锥 远法dps",
|
||||||
|
"hero_info_5102": "火击,火球 远法dps",
|
||||||
|
"hero_info_5103": "冰击,冰锥 远法dps",
|
||||||
|
"hero_info_5104": "冰锥,冰刺 远法dps",
|
||||||
|
"hero_info_5105": "火球,陨石术 远法dps",
|
||||||
|
"hero_info_5201": "普通射击,暴射 远dps",
|
||||||
|
"hero_info_5202": "暴射,光箭 远dps",
|
||||||
|
"hero_info_5203": "暴射,光箭 远dps",
|
||||||
|
"hero_info_5301": "冰锥1,治疗 远辅助",
|
||||||
|
"hero_info_5302": "冰锥1,群体治疗 远辅助",
|
||||||
|
"hero_info_5303": "普通射击,单体攻击buff 射手辅助",
|
||||||
|
"hero_info_5304": "普通射击,群体攻击buff 射手辅助",
|
||||||
|
|
||||||
|
"mon_name_6001": "兽人战士",
|
||||||
|
"mon_name_6002": "兽人斥候",
|
||||||
|
"mon_name_6003": "兽人卫士",
|
||||||
|
"mon_name_6004": "兽人射手",
|
||||||
|
"mon_name_6005": "兽人法师",
|
||||||
|
"mon_name_6006": "兽人首领(BOSS)",
|
||||||
|
"mon_name_6101": "亡灵战士",
|
||||||
|
"mon_name_6102": "兽人射手",
|
||||||
|
"mon_name_6103": "兽人斥候",
|
||||||
|
"mon_name_6104": "亡灵法师(boss)",
|
||||||
|
"mon_name_6105": "兽人首领(BOSS)",
|
||||||
|
|
||||||
|
"skill_name_6401": "单体攻击",
|
||||||
|
"skill_name_6402": "单体生命",
|
||||||
|
"skill_name_6403": "单体全能",
|
||||||
|
"skill_name_6404": "群体攻击",
|
||||||
|
"skill_name_6405": "群体生命",
|
||||||
|
"skill_name_6406": "群体全能",
|
||||||
|
"skill_name_6304": "神圣治疗",
|
||||||
|
"skill_name_6305": "群体护盾",
|
||||||
|
|
||||||
|
"skill_info_6401": "随机1个友方+5攻击",
|
||||||
|
"skill_info_6402": "随机1个友方+20最大生命值",
|
||||||
|
"skill_info_6403": "随机1个友方+2攻击,+10最大生命值",
|
||||||
|
"skill_info_6404": "随机3个友方+2攻击",
|
||||||
|
"skill_info_6405": "随机3个友方+10最大生命值",
|
||||||
|
"skill_info_6406": "为随机3个友方单位增加攻击力和生命上限",
|
||||||
|
"skill_info_6304": "恢复场上随机3个友方单位的生命值",
|
||||||
|
"skill_info_6305": "随机3个友方获得2次伤害免疫",
|
||||||
|
|
||||||
|
"scard_name_7001": "战术晋升",
|
||||||
|
"scard_name_7002": "进阶战术",
|
||||||
|
"scard_name_7101": "近战征召",
|
||||||
|
"scard_name_7102": "远程征召",
|
||||||
|
"scard_name_7103": "精英筛选",
|
||||||
|
|
||||||
|
"scard_info_7001": "升级场上随机1个1级英雄到2级",
|
||||||
|
"scard_info_7002": "升级场上随机1个2级英雄到3级",
|
||||||
|
"scard_info_7101": "刷新卡池,都是近战英雄",
|
||||||
|
"scard_info_7102": "刷新卡池,都是远程英雄",
|
||||||
|
"scard_info_7103": "刷新卡池,都是3级卡池等级英雄"
|
||||||
}
|
}
|
||||||
@@ -93,49 +93,60 @@ export class GameDataSync {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将获取到的云端数据与本地对比并合并
|
||||||
|
*/
|
||||||
|
public syncWithCloudData(cloudData: CloudData | null) {
|
||||||
|
const localData = this.loadFromLocal();
|
||||||
|
|
||||||
|
let cloudTs = cloudData?.data?.timestamp || 0;
|
||||||
|
let localTs = localData?.timestamp || 0;
|
||||||
|
|
||||||
|
if (!localData || cloudTs > localTs) {
|
||||||
|
mLogger.log(this.debugMode, 'GameDataSync', `[GameDataSync]: 云端数据较新 (Cloud: ${cloudTs} > Local: ${localTs}), 执行覆盖。`);
|
||||||
|
if (cloudData) {
|
||||||
|
smc.overrideLocalDataWithRemote(cloudData);
|
||||||
|
this.saveToLocal(); // 同步到本地
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mLogger.log(this.debugMode, 'GameDataSync', `[GameDataSync]: 本地数据较新 (Local: ${localTs} >= Cloud: ${cloudTs}), 使用本地数据,触发强制云同步。`);
|
||||||
|
smc.overrideLocalDataWithRemote({ data: localData });
|
||||||
|
// 本地数据较新,需要强制推送到云端以保证多端一致
|
||||||
|
this._localDataDirty = true;
|
||||||
|
this.executeCloudSync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public getCloudData() {
|
public getCloudData() {
|
||||||
const localData = this.loadFromLocal();
|
const localData = this.loadFromLocal();
|
||||||
|
|
||||||
// 未登录微信云端前,先用本地数据顶上(让玩家秒进游戏)
|
// 未登录微信云端前,先用本地数据顶上(让玩家秒进游戏)
|
||||||
if (localData && !this.isWxClient()) {
|
if (localData && !this.isWxClient()) {
|
||||||
smc.overrideLocalDataWithRemote({ data: localData });
|
smc.overrideLocalDataWithRemote({ data: localData });
|
||||||
return;
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
WxCloudApi.get().then(async (result) => {
|
return WxCloudApi.get().then(async (result) => {
|
||||||
if(result.result.code === 200) {
|
if(result.result.code === 200) {
|
||||||
let cloudData = result.result.data as CloudData;
|
let cloudData = result.result.data as CloudData;
|
||||||
mLogger.log(this.debugMode, 'GameDataSync', `[GameDataSync]: 获取游戏云端数据成功:`, cloudData);
|
mLogger.log(this.debugMode, 'GameDataSync', `[GameDataSync]: 获取游戏云端数据成功:`, cloudData);
|
||||||
|
|
||||||
// 冲突解决:基于时间戳比较(云端时间戳 > 本地时间戳 则覆盖)
|
this.syncWithCloudData(cloudData);
|
||||||
let cloudTs = cloudData?.data?.timestamp || 0;
|
|
||||||
let localTs = localData?.timestamp || 0;
|
|
||||||
|
|
||||||
if (!localData || cloudTs > localTs) {
|
return true;
|
||||||
mLogger.log(this.debugMode, 'GameDataSync', `[GameDataSync]: 云端数据更新 (Cloud: ${cloudTs} > Local: ${localTs}), 执行覆盖。`);
|
|
||||||
smc.overrideLocalDataWithRemote(cloudData);
|
|
||||||
this.saveToLocal(); // 同步到本地
|
|
||||||
} else {
|
|
||||||
mLogger.log(this.debugMode, 'GameDataSync', `[GameDataSync]: 本地数据更新 (Local: ${localTs} >= Cloud: ${cloudTs}), 使用本地数据,触发强制云同步。`);
|
|
||||||
smc.overrideLocalDataWithRemote({ data: localData });
|
|
||||||
// 本地数据较新,需要强制推送到云端以保证多端一致
|
|
||||||
this._localDataDirty = true;
|
|
||||||
this.executeCloudSync();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
} else {
|
} else {
|
||||||
mLogger.warn(this.debugMode, 'GameDataSync', `[GameDataSync]: 获取游戏云端数据失败,使用本地缓存兜底。`);
|
mLogger.warn(this.debugMode, 'GameDataSync', `[GameDataSync]: 获取游戏云端数据失败,使用本地缓存兜底。`);
|
||||||
if (localData) {
|
if (localData) {
|
||||||
smc.overrideLocalDataWithRemote({ data: localData });
|
smc.overrideLocalDataWithRemote({ data: localData });
|
||||||
}
|
}
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
mLogger.error(this.debugMode, 'GameDataSync', `[GameDataSync]: 获取游戏云端数据异常:`, error);
|
mLogger.error(this.debugMode, 'GameDataSync', `[GameDataSync]: 获取游戏云端数据异常:`, error);
|
||||||
if (localData) {
|
if (localData) {
|
||||||
smc.overrideLocalDataWithRemote({ data: localData });
|
smc.overrideLocalDataWithRemote({ data: localData });
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,12 @@ import { gameDataSync } from "./GameDataSync";
|
|||||||
*/
|
*/
|
||||||
export interface GameDate{
|
export interface GameDate{
|
||||||
gold:number,
|
gold:number,
|
||||||
heros:any,
|
|
||||||
fight_hero:number,
|
|
||||||
timestamp?: number, // 用于比对本地与云端数据的最新状态
|
timestamp?: number, // 用于比对本地与云端数据的最新状态
|
||||||
collection?: {
|
collection?: {
|
||||||
talents: Partial<Record<TalentType, number>>,
|
talents: Partial<Record<TalentType, number>>,
|
||||||
player_level: number,
|
player_level: number,
|
||||||
player_exp: number,
|
player_exp: number,
|
||||||
talent_points: number,
|
talent_points: number,
|
||||||
skills?: {uuid:0,count:0},
|
|
||||||
friend?: {uuid:0,count:0},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export interface CloudData {
|
export interface CloudData {
|
||||||
@@ -64,8 +60,6 @@ export class SingletonModuleComp extends ecs.Comp {
|
|||||||
|
|
||||||
guides:any=[0,0,0,0,0]
|
guides:any=[0,0,0,0,0]
|
||||||
current_guide:number=0
|
current_guide:number=0
|
||||||
fight_hero: number = 5001; // 单个出战英雄
|
|
||||||
heros:any= [5001]
|
|
||||||
|
|
||||||
collection: {
|
collection: {
|
||||||
talents: Partial<Record<TalentType, number>>;
|
talents: Partial<Record<TalentType, number>>;
|
||||||
@@ -239,14 +233,6 @@ export class SingletonModuleComp extends ecs.Comp {
|
|||||||
if (data.gold !== undefined) {
|
if (data.gold !== undefined) {
|
||||||
this.vmdata.gold = data.gold;
|
this.vmdata.gold = data.gold;
|
||||||
}
|
}
|
||||||
// 同步英雄
|
|
||||||
if (data.heros && Array.isArray(data.heros)) {
|
|
||||||
this.heros = data.heros;
|
|
||||||
}
|
|
||||||
// 同步出战英雄
|
|
||||||
if (data.fight_hero !== undefined) {
|
|
||||||
this.fight_hero = data.fight_hero;
|
|
||||||
}
|
|
||||||
// 恢复收集记录
|
// 恢复收集记录
|
||||||
if (data.collection) {
|
if (data.collection) {
|
||||||
const remoteCol = data.collection;
|
const remoteCol = data.collection;
|
||||||
@@ -267,8 +253,6 @@ export class SingletonModuleComp extends ecs.Comp {
|
|||||||
getGameDate(){
|
getGameDate(){
|
||||||
let data: GameDate = {
|
let data: GameDate = {
|
||||||
gold: this.vmdata.gold,
|
gold: this.vmdata.gold,
|
||||||
heros: this.heros,
|
|
||||||
fight_hero: this.fight_hero,
|
|
||||||
collection: this.collection,
|
collection: this.collection,
|
||||||
timestamp: Date.now() // 每次获取当前数据结构时都附带最新的时间戳
|
timestamp: Date.now() // 每次获取当前数据结构时都附带最新的时间戳
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { LoadingViewComp } from "./view/LoadingViewComp";
|
|||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
import { WxCloudApi } from "../wx_clound_client_api/WxCloudApi";
|
import { WxCloudApi } from "../wx_clound_client_api/WxCloudApi";
|
||||||
import { mLogger } from "../common/Logger";
|
import { mLogger } from "../common/Logger";
|
||||||
|
import { gameDataSync } from "../common/GameDataSync";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 游戏进入初始化模块
|
* 游戏进入初始化模块
|
||||||
@@ -29,7 +30,7 @@ export class Initialize extends ecs.Entity {
|
|||||||
// 加载自定义资
|
// 加载自定义资
|
||||||
this.loadCustom(queue);
|
this.loadCustom(queue);
|
||||||
// 加载多语言包
|
// 加载多语言包
|
||||||
// this.loadLanguage(queue);
|
this.loadLanguage(queue);
|
||||||
// 加载公共资源
|
// 加载公共资源
|
||||||
this.loadCommon(queue);
|
this.loadCommon(queue);
|
||||||
// 加载游戏内容加载进度提示界面
|
// 加载游戏内容加载进度提示界面
|
||||||
@@ -85,13 +86,6 @@ export class Initialize extends ecs.Entity {
|
|||||||
oops.res.loadDir("common", next);
|
oops.res.loadDir("common", next);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 判断是否为微信客户端
|
|
||||||
*/
|
|
||||||
private isWxClient(): boolean {
|
|
||||||
// 检查是否存在微信API
|
|
||||||
return typeof wx !== 'undefined' && typeof (wx as any).getSystemInfoSync === 'function';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统一的游戏数据加载流程
|
* 统一的游戏数据加载流程
|
||||||
@@ -102,7 +96,7 @@ export class Initialize extends ecs.Entity {
|
|||||||
try {
|
try {
|
||||||
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 开始统一数据加载流程...");
|
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 开始统一数据加载流程...");
|
||||||
|
|
||||||
if (this.isWxClient()) {
|
if (gameDataSync.isWxClient()) {
|
||||||
// 微信客户端:加载云端数据
|
// 微信客户端:加载云端数据
|
||||||
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 检测到微信客户端,使用云端数据");
|
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 检测到微信客户端,使用云端数据");
|
||||||
await this.loadFromCloud();
|
await this.loadFromCloud();
|
||||||
@@ -130,36 +124,33 @@ export class Initialize extends ecs.Entity {
|
|||||||
const loginResult = await WxCloudApi.login();
|
const loginResult = await WxCloudApi.login();
|
||||||
const response = loginResult.result;
|
const response = loginResult.result;
|
||||||
|
|
||||||
if (loginResult.result.code === 200) {
|
if (response && response.code === 200) {
|
||||||
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 云端登录成功");
|
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 云端登录成功");
|
||||||
smc.updateCloudData()
|
|
||||||
const cloudData = loginResult.result.data;
|
const cloudData = response.data;
|
||||||
try {
|
|
||||||
// 直接覆盖基础游戏数据
|
if (cloudData && cloudData.openid) {
|
||||||
if (cloudData.openid) {
|
smc.openid = cloudData.openid;
|
||||||
smc.openid=cloudData.openid
|
|
||||||
}
|
|
||||||
// 直接覆盖出战英雄配置
|
|
||||||
if (cloudData.game_data) {
|
|
||||||
let gameDate=cloudData.game_data
|
|
||||||
if( gameDate.gold ) smc.vmdata.gold=gameDate.gold
|
|
||||||
if( gameDate.heros ) smc.heros=gameDate.heros
|
|
||||||
if( gameDate.fight_hero ) smc.fight_hero=gameDate.fight_hero
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
mLogger.log(this.debugMode, 'Initialize', `[SMC]: 数据覆盖失败:`, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将 login 获取的 game_data 封装为统一下发格式,交给 gameDataSync 对比与合并
|
||||||
|
const formattedCloudData = {
|
||||||
|
openid: cloudData?.openid || '',
|
||||||
|
data: cloudData?.game_data || {}
|
||||||
|
};
|
||||||
|
|
||||||
|
gameDataSync.syncWithCloudData(formattedCloudData);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 云端登录失败:", response.msg);
|
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 云端登录失败:", response?.msg);
|
||||||
// 登录失败时使用本地数据 游戏需要退出
|
// 登录失败时使用本地数据
|
||||||
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 云端登录失败:", response.msg);
|
gameDataSync.syncWithCloudData(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 云端数据加载异常:", error);
|
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 云端数据加载异常:", error);
|
||||||
// 异常时使用本地数据 游戏需要退出
|
// 异常时使用本地数据兜底
|
||||||
|
gameDataSync.syncWithCloudData(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,10 +159,8 @@ export class Initialize extends ecs.Entity {
|
|||||||
*/
|
*/
|
||||||
private async loadFromLocalDebug() {
|
private async loadFromLocalDebug() {
|
||||||
try {
|
try {
|
||||||
// 使用本地调试API,模拟云端接口
|
|
||||||
|
|
||||||
// 用本地调试数据覆盖客户端数据
|
// 用本地调试数据覆盖客户端数据
|
||||||
|
gameDataSync.syncWithCloudData(null);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 本地调试数据加载异常:", error);
|
mLogger.log(this.debugMode, 'Initialize', "[Initialize]: 本地调试数据加载异常:", error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ if (loginResult.result.code === 200) {
|
|||||||
const userData = loginResult.result.data;
|
const userData = loginResult.result.data;
|
||||||
console.log("用户ID:", userData.user_id);
|
console.log("用户ID:", userData.user_id);
|
||||||
console.log("金币:", userData.data.gold);
|
console.log("金币:", userData.data.gold);
|
||||||
console.log("出战英雄:", userData.fight_heros);
|
console.log("用户金币:", userData.gold);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user