using System; using System.Collections.Generic; using UnityEngine; using LitJson; using System.Linq; //查看其他玩家的简短信息, 该模块处理数据,其他由各自功能模块处理 通过OnRevPackage public class OtherPlayerDetailManager : GameSystemManager { public int viewPlayer { get; private set; } // 查询类型:根据类型做不同处理 // 按功能自定义枚举值 EnumHelper的 ViewPlayerType public int viewPlayerType { get; private set; } public int viewPreSetType { get; private set; } public RolePlusData.EquipData otherPlayerViewEquip;//查看他人界面正在查看中的装备 private Dictionary viewPlayerDataDic = new Dictionary(); // 查看类型,玩家ID public event Action OnRevPackage; //尽量不要用第一个参数viewtype做判断,容易出错 public override void Init() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin; } public override void Release() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin; } public void OnBeforePlayerDataInitializeEventOnRelogin() { viewPlayer = -1; viewPlayerType = -1; viewPreSetType = -1; otherPlayerViewEquip = null; viewHeroDetailData = null; } // 获取其他玩家本地缓存数据 public ViewPlayerData GetViewPlayerData(int playerId) { ViewPlayerData viewPlayerData = null; viewPlayerDataDic.TryGetValue(playerId, out viewPlayerData); return viewPlayerData; } // 向服务端请求其他玩家数据 serverID发0默认本服玩家 public void ViewPlayerDetail(int playerId, int serverID, int viewType = (int)ViewPlayerType.viewPlayerData, int viewBattlePreSetType = (int)BattlePreSetType.Story) { // 自己不能查看自己的信息 if (playerId == PlayerDatas.Instance.baseData.PlayerID) return; viewPlayerType = viewType; viewPreSetType = viewBattlePreSetType; ViewRoleParticulars(playerId, serverID); } // 向服务端请求玩家数据 void ViewRoleParticulars(int playerID, int serverID) { if (playerID <= 0) return; viewPlayer = playerID; if (viewPlayerDataDic.ContainsKey(playerID)) { ViewPlayerData viewPlayerData = viewPlayerDataDic[playerID]; if ((DateTime.Now - viewPlayerData.getTime).TotalSeconds < 30) { ShowRoleParticulars(playerID); return; } } CA212_tagCMViewPlayerInfo pak = new CA212_tagCMViewPlayerInfo(); pak.PlayerID = (uint)playerID; pak.ServerID = (uint)serverID; GameNetSystem.Instance.SendInfo(pak); } public void OnRevRoleEquip(HA705_tagSCQueryPlayerCacheResult package) { ViewPlayerData viewPlayerData = null; if (!viewPlayerDataDic.TryGetValue((int)package.PlayerID, out viewPlayerData)) { viewPlayerData = new ViewPlayerData(); viewPlayerData.getTime = DateTime.Now; viewPlayerDataDic.Add((int)package.PlayerID, viewPlayerData); } viewPlayerData.getTime = DateTime.Now; viewPlayerData.PlayerID = (int)package.PlayerID; viewPlayerData.PlayerName = UIHelper.ServerStringTrim(package.PlayerName); viewPlayerData.LV = package.LV; viewPlayerData.Job = package.Job; viewPlayerData.RealmLV = package.RealmLV; viewPlayerData.Face = (int)package.Face; viewPlayerData.FacePic = (int)package.FacePic; viewPlayerData.ModelMark = (int)package.ModelMark; viewPlayerData.EquipShowSwitch = (int)package.EquipShowSwitch; viewPlayerData.TitleID = (int)package.TitleID; viewPlayerData.ServerID = (int)package.ServerID; viewPlayerData.FightPower = package.FightPower + package.FightPowerEx * (long)Constants.ExpPointValue; viewPlayerData.FamilyID = (int)package.FamilyID; viewPlayerData.FamilyName = UIHelper.ServerStringTrim(package.FamilyName); viewPlayerData.FamilyEmblemID = (int)package.FamilyEmblemID; viewPlayerData.FamilyDataServerID = (int)package.FamilyDataServerID; viewPlayerData.FamilyEmblemWord = UIHelper.ServerStringTrim(package.FamilyEmblemWord); if (viewPlayerData.rolePlusData == null) { //第一次初始化 viewPlayerData.rolePlusData = new RolePlusData(); } if (package.PlusDataSize != 0) { viewPlayerData.rolePlusData.AnalysisRolePlusData(package.PlusData); } ShowRoleParticulars((int)package.PlayerID); } //尽量不要用第一个参数viewtype做判断,容易出错,比如同时发送两个不同的viewPlayerType请求的时候 private void ShowRoleParticulars(int playerID) { if (viewPlayerType == (int)ViewPlayerType.viewPlayerData) { if (UIManager.Instance.IsOpened()) { UIManager.Instance.CloseWindow(); } UIManager.Instance.OpenWindow(viewPreSetType); } OnRevPackage?.Invoke(viewPlayerType, playerID); viewPlayerType = -1; viewPreSetType = -1; } public ViewHeroDetailData viewHeroDetailData; public void OpenOtherHeroDetailWin(ViewHeroDetailData viewHeroDetailData) { this.viewHeroDetailData = viewHeroDetailData; if (!UIManager.Instance.IsOpened()) { UIManager.Instance.OpenWindow(); } } #region 获取PlusData中的数据 /// /// 获取特定战斗环境下的命格方案详情 /// public RolePlusData.MinggePresetData GetMinggePresetByBattleType(int playerID, int battleType) { int presetID = GetFuncPresetID(playerID, battleType, (int)FuncPresetType.Mingge); var minggeData = GetMinggeTotalData(playerID); if (minggeData == null || minggeData.PresetDic == null) return null; // 取出对应的方案数据 if (minggeData.PresetDic.TryGetValue(presetID, out var data)) { return data; } // 如果找不到该方案ID(兼容性),尝试取默认方案 ID=1 if (presetID != 1 && minggeData.PresetDic.TryGetValue(1, out var defaultData)) { return defaultData; } return null; } public RolePlusData.MinggeData GetMinggeTotalData(int playerID) { ViewPlayerData viewPlayerData = GetViewPlayerData(playerID); return viewPlayerData?.rolePlusData?.minggeData; } public int GetFuncPresetID(int playerID, int battleType, int funcType) { ViewPlayerData viewPlayerData = GetViewPlayerData(playerID); if (viewPlayerData?.rolePlusData?.BatPresetDic?.TryGetValue(battleType, out var data) != true) { return 1; } return data.ContainsKey(funcType) ? data[funcType] : 1; } public Dictionary GetHeroDataDict(int playerID, int presetID) { ViewPlayerData viewPlayerData = GetViewPlayerData(playerID); if (viewPlayerData?.rolePlusData?.LineupDic?.TryGetValue(presetID, out var lineupData) != true) { return null; } return lineupData?.HeroDic; } public List GetHeroDataSortList(int playerID, int presetID) { var heroDataDict = GetHeroDataDict(playerID, presetID); if (heroDataDict == null) { return null; } var res = new List(); List keyList = heroDataDict.Keys.ToList(); keyList.Sort(); foreach (var num in keyList) { if (!heroDataDict.ContainsKey(num)) { continue; } res.Add(heroDataDict[num]); } return res; } public bool TryGetFightPointByTeamType(int playerID, int presetID, out long fightPower) { fightPower = 0; var lineupDic = GetViewPlayerData(playerID)?.rolePlusData?.LineupDic; if (lineupDic != null && lineupDic.TryGetValue(presetID, out var lineupData)) { fightPower = lineupData.FightPower; return true; } return false; } public Dictionary GetEquipDataDict(int playerID) { ViewPlayerData viewPlayerData = GetViewPlayerData(playerID); return viewPlayerData?.rolePlusData?.EquipDic; } public int GetUseDataFirstValue(RolePlusData.EquipData equip, int key) { if (equip.UserData != null && equip.UserData.ContainsKey(key) && equip.UserData[key].Count > 0) { return equip.UserData[key][0]; } return 0; } public int GetUseDataFirstValue(RolePlusData.HeroData hero, int key) { if (hero.Data != null && hero.Data.ContainsKey(key) && hero.Data[key].Count > 0) { return hero.Data[key][0]; } return 0; } public int GetEquipLV(RolePlusData.EquipData equip) { if (equip == null) { return 0; } return GetUseDataFirstValue(equip, 22); } public List GetUseData(RolePlusData.EquipData equip, int key) { List list = null; if (equip.UserData != null) { equip.UserData.TryGetValue(key, out list); } return list == null ? new List() : list; } public List GetUseData(RolePlusData.HeroData hero, int key) { List list = null; if (hero.Data != null) { hero.Data.TryGetValue(key, out list); } return list == null ? new List() : list; } //基础属性ID列表 public List GetEquipBaseAttrs(RolePlusData.EquipData equip) { if (equip == null) { return new List(); } return GetUseData(equip, 21); } //基础属性值列表 public List GetEquipBaseValues(RolePlusData.EquipData equip) { if (equip == null) { return new List(); } return GetUseData(equip, 23); } //战斗属性ID列表 public List GetEquipFightAttrs(RolePlusData.EquipData equip) { if (equip == null) { return new List(); } return GetUseData(equip, 17); } //战斗属性值列表 public List GetEquipFightValues(RolePlusData.EquipData equip) { if (equip == null) { return new List(); } return GetUseData(equip, 19); } // 武将突破等级 public int GetBreakLevel(RolePlusData.HeroData hero) { if (hero == null) return 0; return GetUseDataFirstValue(hero, 74); } // 武将觉醒等级 public int GetAwakeLevel(RolePlusData.HeroData hero) { if (hero == null) return 0; return GetUseDataFirstValue(hero, 76); } // 71 # 英雄天赋ID列表 public List GetTalentIDList(RolePlusData.HeroData hero) { if (hero == null) return new List(); return GetUseData(hero, 71); } // 73 # 英雄天赋ID等级列表,对应71天赋ID的等级 public List GetTalentLvList(RolePlusData.HeroData hero) { if (hero == null) return new List(); return GetUseData(hero, 73); } // 获取红颜属性值 public RolePlusData.BeautyData GetBeautyData(int playerID) { ViewPlayerData viewPlayerData = GetViewPlayerData(playerID); return viewPlayerData?.rolePlusData?.beautyData; } // 获取坐骑数据对象 public RolePlusData.HorseData GetHorseData(int playerID) { ViewPlayerData viewPlayerData = GetViewPlayerData(playerID); return viewPlayerData?.rolePlusData?.horseData; } // 获取古宝数据对象 public RolePlusData.GubaoData GetGubaoData(int playerID) { ViewPlayerData viewPlayerData = GetViewPlayerData(playerID); return viewPlayerData?.rolePlusData?.gubaoData; } #endregion #region 解析PlusData public class ViewPlayerData { public int PlayerID; public string PlayerName; public int LV; public int Job; public int RealmLV; public int Face; public int FacePic; public int ModelMark; // 变形模型mark public int EquipShowSwitch; // 其他外观信息 public int TitleID; public int ServerID; public long FightPower; public int FamilyID; public int FamilyDataServerID; //公会数据所在服务器ID,A619查看公会用 public string FamilyName; public int FamilyEmblemID; public string FamilyEmblemWord; public RolePlusData rolePlusData; public DateTime getTime; } public class RolePlusData { // --- 定义存储数据的结构 --- // 装备字典 <位置索引, 装备数据> public Dictionary EquipDic = new Dictionary(); // 阵容字典 <阵容ID, 阵容数据> public Dictionary LineupDic = new Dictionary(); //<战斗预设类型,<预设类型,使用的方案ID>> public Dictionary> BatPresetDic = new Dictionary>(); // 红颜数据 public BeautyData beautyData; // 坐骑数据 public HorseData horseData; // 古宝数据 public GubaoData gubaoData; // 命格数据 public MinggeData minggeData; // 红颜数据类 public class BeautyData { public int Cnt; // 已解锁数 public Dictionary AttrDict = new Dictionary(); // 属性 } // 坐骑数据类 public class HorseData { public int LV; // 等级 public int ClassLV; // 阶级 public Dictionary AttrDict = new Dictionary(); // 属性 } // 装备数据类 public class EquipData { public int ItemID; public Dictionary> UserData = new Dictionary>(); } // 古宝数据类 public class GubaoData { public int Cnt; // 已解锁数 public Dictionary AttrDict = new Dictionary(); // 属性 } public class MinggeData { public int GWLV; // 感悟等级 public Dictionary PresetDic = new Dictionary(); // <预设ID, 预设详情> } public class MinggePresetData { // 命格技能 <意象技能ID, 等级> public Dictionary SkillDic = new Dictionary(); // 命格属性 <属性ID, 值> public Dictionary AttrDict = new Dictionary(); } // 阵容数据类 public class LineupData { public int PlayerID; public long FightPower; public int ShapeType; // 英雄字典 <站位, 英雄数据> public Dictionary HeroDic = new Dictionary(); } // 英雄数据类 public class HeroData { public int HeroID; public int SkinID; public int LV; public int Star; public long FightPower; public List SkillIDList = new List(); // 属性字典 <属性ID, 属性值> public Dictionary AttrDict = new Dictionary(); // 英雄专属UserData (格式与物品UserData相同) // 使用 Dictionary> 结构,key为ItemUseDataKey枚举值 public Dictionary> Data = new Dictionary>(); } // 通用的属性解析方法 private Dictionary ParseAttrDict(JsonData jd, string key) { Dictionary result = new Dictionary(); if (jd.Keys.Contains(key)) { JsonData attrs = jd[key]; foreach (string attrKey in attrs.Keys) { if (int.TryParse(attrKey, out int attrId)) { JsonData v = attrs[attrKey]; long val = 0; // 健壮性数值转换 if (v.IsLong) val = (long)v; else if (v.IsInt) val = (long)(int)v; else if (v.IsDouble) val = (long)(double)v; else if (v.IsString) long.TryParse(v.ToString(), out val); result[attrId] = val; } } } return result; } // --- 解析逻辑 --- public void AnalysisRolePlusData(string jsonStr) { try { if (string.IsNullOrEmpty(jsonStr)) return; EquipDic.Clear(); LineupDic.Clear(); BatPresetDic.Clear(); beautyData = null; // 必须置空,防止显示上一个玩家的数据 horseData = null; // 必须置空 gubaoData = null; // 必须置空 minggeData = null; // 1. 转为 JsonData 对象 JsonData jd = JsonMapper.ToObject(jsonStr); // 2. 解析装备 (Equip) if (jd.Keys.Contains("Equip")) { JsonData equipJd = jd["Equip"]; foreach (string key in equipJd.Keys) { if (int.TryParse(key, out int posIndex)) { JsonData itemJd = equipJd[key]; EquipData equipData = new EquipData(); if (itemJd.Keys.Contains("ItemID")) equipData.ItemID = (int)itemJd["ItemID"]; if (itemJd.Keys.Contains("UserData") && !string.IsNullOrEmpty((string)itemJd["UserData"])) equipData.UserData = ConfigParse.Analysis((string)itemJd["UserData"]); EquipDic[posIndex] = equipData; } } } // 【新增】解析古宝 (Gubao) if (jd.Keys.Contains("Gubao")) { JsonData gubaoJd = jd["Gubao"]; gubaoData = new GubaoData(); if (gubaoJd.Keys.Contains("Cnt")) gubaoData.Cnt = (int)gubaoJd["Cnt"]; // 解析属性 gubaoData.AttrDict = ParseAttrDict(gubaoJd, "Attr"); } // 【新增】解析红颜 (Beauty) if (jd.Keys.Contains("Beauty")) { JsonData beautyJd = jd["Beauty"]; beautyData = new BeautyData(); if (beautyJd.Keys.Contains("Cnt")) beautyData.Cnt = (int)beautyJd["Cnt"]; // 解析属性 beautyData.AttrDict = ParseAttrDict(beautyJd, "Attr"); } // 【新增】解析坐骑 (Horse) if (jd.Keys.Contains("Horse")) { JsonData horseJd = jd["Horse"]; horseData = new HorseData(); if (horseJd.Keys.Contains("LV")) horseData.LV = (int)horseJd["LV"]; if (horseJd.Keys.Contains("ClassLV")) horseData.ClassLV = (int)horseJd["ClassLV"]; // 解析属性 horseData.AttrDict = ParseAttrDict(horseJd, "Attr"); } // 3. 解析阵容 (Lineup) if (jd.Keys.Contains("Lineup")) { JsonData lineupJd = jd["Lineup"]; foreach (string key in lineupJd.Keys) { if (int.TryParse(key, out int lineupId)) { JsonData oneLineupJd = lineupJd[key]; LineupData lineupData = new LineupData(); if (oneLineupJd.Keys.Contains("PlayerID")) lineupData.PlayerID = (int)oneLineupJd["PlayerID"]; if (oneLineupJd.Keys.Contains("FightPower")) lineupData.FightPower = long.Parse(oneLineupJd["FightPower"].ToString()); if (oneLineupJd.Keys.Contains("ShapeType")) lineupData.ShapeType = (int)oneLineupJd["ShapeType"]; // 解析阵容下的英雄 (Hero) if (oneLineupJd.Keys.Contains("Hero")) { JsonData heroRootJd = oneLineupJd["Hero"]; foreach (string heroKey in heroRootJd.Keys) { if (int.TryParse(heroKey, out int heroPos)) { JsonData heroJd = heroRootJd[heroKey]; HeroData heroData = new HeroData(); if (heroJd.Keys.Contains("HeroID")) heroData.HeroID = (int)heroJd["HeroID"]; if (heroJd.Keys.Contains("SkinID")) heroData.SkinID = (int)heroJd["SkinID"]; if (heroJd.Keys.Contains("LV")) heroData.LV = (int)heroJd["LV"]; if (heroJd.Keys.Contains("Star")) heroData.Star = (int)heroJd["Star"]; if (heroJd.Keys.Contains("FightPower")) heroData.FightPower = long.Parse(heroJd["FightPower"].ToString()); // 解析Data字段(武将物品UserData) if (heroJd.Keys.Contains("Data") && !string.IsNullOrEmpty((string)heroJd["Data"])) { heroData.Data = ConfigParse.Analysis((string)heroJd["Data"]); } // 解析技能列表 List if (heroJd.Keys.Contains("SkillIDList")) { JsonData skills = heroJd["SkillIDList"]; for (int i = 0; i < skills.Count; i++) { heroData.SkillIDList.Add((int)skills[i]); } } heroData.AttrDict = ParseAttrDict(heroJd, "AttrDict"); lineupData.HeroDic[heroPos] = heroData; } } } LineupDic[lineupId] = lineupData; } } } //BatPreset - {"战斗预设类型":{"预设类型":使用的方案ID, ...}, ...} if (jd.Keys.Contains("BatPreset")) { JsonData batPresetJson = jd["BatPreset"]; BatPresetDic = new Dictionary>(); foreach (string outerKey in batPresetJson.Keys) { if (int.TryParse(outerKey, out int outerKeyInt)) { JsonData innerJson = batPresetJson[outerKey]; var innerDict = new Dictionary(); foreach (string innerKey in innerJson.Keys) { if (int.TryParse(innerKey, out int innerKeyInt)) { innerDict[innerKeyInt] = int.Parse(innerJson[innerKey].ToString()); } } BatPresetDic[outerKeyInt] = innerDict; } } } // 【新增】解析命格 (Mingge) if (jd.Keys.Contains("Mingge")) { JsonData minggeJd = jd["Mingge"]; minggeData = new MinggeData(); // 1. 解析感悟等级 if (minggeJd.Keys.Contains("GWLV")) minggeData.GWLV = (int)minggeJd["GWLV"]; // 2. 解析预设 (Preset) if (minggeJd.Keys.Contains("Preset")) { JsonData presetRootJd = minggeJd["Preset"]; foreach (string key in presetRootJd.Keys) { // key 为命格预设ID if (int.TryParse(key, out int presetId)) { JsonData singlePresetJd = presetRootJd[key]; MinggePresetData presetData = new MinggePresetData(); // 解析属性 (Attr) presetData.AttrDict = ParseAttrDict(singlePresetJd, "Attr"); // 解析技能 (Skill) - {"SkillID": level, ...} if (singlePresetJd.Keys.Contains("Skill")) { JsonData skillJd = singlePresetJd["Skill"]; foreach (string skillKey in skillJd.Keys) { if (int.TryParse(skillKey, out int skillId)) { if (int.TryParse(skillJd[skillKey].ToString(), out int level)) { presetData.SkillDic[skillId] = level; } } } } minggeData.PresetDic[presetId] = presetData; } } } } } catch (Exception e) { Debug.LogError("AnalysisRolePlusData Error: " + e.Message + "\nJSON: " + jsonStr); } } } #endregion } public class ViewHeroDetailData { public int viewHeroType;//0:战场点击我方的英雄模型 1:查看他人英雄详情界面点击英雄卡牌 public BattleClickHeroData clickHeroData; public ViewNPCAttr viewNPCAttr; public OtherPlayerDetailManager.RolePlusData.HeroData heroData; public List heroDatas; public OtherPlayerDetailManager.RolePlusData.EquipData equip; }