| using System;  | 
| using System.Collections;  | 
| using System.Collections.Generic;  | 
| using UnityEngine;  | 
| using LitJson;  | 
| using System.Linq;  | 
|   | 
|   | 
| //查看其他玩家的简短信息, 该模块处理数据,其他由各自功能模块处理 通过OnRevPackage  | 
| public class RoleParticularModel : GameSystemManager<RoleParticularModel>  | 
| {  | 
|   | 
|     public override void Init()  | 
|     {  | 
|         DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize;  | 
|     }  | 
|   | 
|     public override void Release()  | 
|     {  | 
|         DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitialize;  | 
|     }  | 
|   | 
|   | 
|     public void OnBeforePlayerDataInitialize()  | 
|     {  | 
|         viewPlayerType = -1;  | 
|     }  | 
|   | 
|     public int viewPlayer { get; private set; }  | 
|   | 
|     // 查询本服:0-查看其他玩家的简洁信息界面 1-查看战力界面 2(以上小于100)-返回数据不做处理,由调用者自行处理逻辑  | 
|     // 查询跨服:100-查看其他玩家的简洁信息界面 101-查看战力界面 102以上-返回数据不做处理,由调用者自行处理逻辑  | 
|     // 调用者需要的话自定义枚举值 EnumHelper的ViewPlayerType  | 
|     public int viewPlayerType { get; private set; }    | 
|   | 
|     private Dictionary<int, ViewPlayerData> viewPlayerDataDic = new Dictionary<int, ViewPlayerData>();  | 
|     private Dictionary<int, long> funcFightPowerDict = new Dictionary<int, long>();  | 
|     public event Action PowerUpdate;  | 
|     public static Action<int, int, ViewPlayerData> OnRevPackage; //尽量不要用第一个参数viewtype做判断,容易出错  | 
|   | 
|     public ViewPlayerData GetViewPlayerData(int player)  | 
|     {  | 
|         ViewPlayerData viewPlayerData = null;  | 
|         viewPlayerDataDic.TryGetValue(player, out viewPlayerData);  | 
|         return viewPlayerData;  | 
|     }  | 
|   | 
|     // 查看玩家模型展示,查玩家装备详情需另外处理  | 
|     // 本服查询:返回时打开查看其他玩家的简洁信息界面(可查看装备,宠物,坐骑等具体信息)RoleParticularsWin  | 
|     public void ViewRoleEquip(int playerID)  | 
|     {  | 
|         if (playerID == PlayerDatas.Instance.baseData.PlayerID)  | 
|         {  | 
|             return;  | 
|         }  | 
|         viewPlayerType = (int)ViewPlayerType.viewPlayerEquip;  | 
|         ViewRoleParticulars(playerID);  | 
|     }  | 
|   | 
|     // 本服查询:返回时打开查看其他玩家战力界面(战力分布)ViewFuncPowerWin  | 
|     public void ViewRoleFightPower(int playerID)  | 
|     {  | 
|         if (playerID == PlayerDatas.Instance.baseData.PlayerID)  | 
|         {  | 
|             return;  | 
|         }  | 
|         viewPlayerType = (int)ViewPlayerType.viewPlayerFightPower;  | 
|         ViewRoleParticulars(playerID);  | 
|     }  | 
|   | 
|     // 返回时不做任何操作,由调用者自行处理逻辑  | 
|     public void ViewPlayerCacheData(int _playerId, int viewType = (int)ViewPlayerType.viewPlayerData)  | 
|     {  | 
|         viewPlayerType = viewType;  | 
|         ViewRoleParticulars(_playerId);  | 
|     }  | 
|   | 
|     // 查看玩家模型展示,查玩家装备详情需另外处理  | 
|     // 跨服查询:返回时打开查看其他玩家的简洁信息界面(可查看装备,宠物,坐骑等具体信息)RoleParticularsWin  | 
|     public void ViewCrossServerPlayerEquip(int _playerId)  | 
|     {  | 
|         if (_playerId == PlayerDatas.Instance.baseData.PlayerID)  | 
|         {  | 
|             return;  | 
|         }  | 
|         viewPlayerType = (int)ViewPlayerType.viewCrossPlayerEquip;  | 
|         ViewRoleParticulars(_playerId);  | 
|     }  | 
|   | 
|     public void ViewCrossPlayerFightPower(int _playerId)  | 
|     {  | 
|         if (_playerId == PlayerDatas.Instance.baseData.PlayerID)  | 
|         {  | 
|             return;  | 
|         }  | 
|         viewPlayerType = (int)ViewPlayerType.viewCrossPlayerFightPower;  | 
|         ViewRoleParticulars(_playerId);  | 
|     }  | 
|   | 
|     // 返回时不做任何操作,由调用者自行处理逻辑  | 
|     public void ViewCrossPlayerCacheData(int _playerId, int viewType = (int)ViewPlayerType.viewCrossPlayerData)  | 
|     {  | 
|         viewPlayerType = viewType;  | 
|         ViewRoleParticulars(_playerId);  | 
|     }  | 
|   | 
|     public void ViewRoleParticulars(int playerID)  | 
|     {  | 
|         if (playerID == 0)  | 
|         {  | 
|             return;  | 
|         }  | 
|         viewPlayer = playerID;  | 
|         if (viewPlayerDataDic.ContainsKey(playerID))  | 
|         {  | 
|             ViewPlayerData viewPlayerData = viewPlayerDataDic[playerID];  | 
|             if ((DateTime.Now - viewPlayerData.getTime).TotalSeconds < 30)  | 
|             {  | 
|                 ShowRoleParticulars(viewPlayerData, playerID);  | 
|                 return;  | 
|             }  | 
|         }  | 
|         if (viewPlayerType >= (int)ViewPlayerType.viewCrossPlayerEquip)  | 
|         {  | 
|             //由子服服务器向跨服服务器查询; 会优先查本服数据(gameserver)  | 
|             CC002_tagCGViewCrossPlayerInfo c002 = new CC002_tagCGViewCrossPlayerInfo();  | 
|             c002.PlayerID = (uint)playerID;  | 
|             GameNetSystem.Instance.SendInfo(c002);  | 
|         }  | 
|         else  | 
|         {  | 
|             //只查本服数据,有可能本地图有数据,就不查gameserver  | 
|             CA212_tagCMViewPlayerInfo pak = new CA212_tagCMViewPlayerInfo();  | 
|             pak.PlayerID = (uint)playerID;  | 
|             GameNetSystem.Instance.SendInfo(pak);  | 
|         }  | 
|     }  | 
|   | 
|   | 
|     //本服竞技场假查询模拟封包,返回查看机器人数据 打开RoleParticularsWin界面,专用接口其他地方不要调用  | 
|     public void ViewFairyArenaRobot(int playerID, ViewPlayerData _viewPlayerData)  | 
|     {  | 
|         ViewPlayerData viewPlayerData = null;  | 
|         viewPlayer = playerID;  | 
|         if (!viewPlayerDataDic.TryGetValue(playerID, out viewPlayerData))  | 
|         {  | 
|             viewPlayerDataDic.Add(playerID, _viewPlayerData);  | 
|         }  | 
|         else  | 
|         {  | 
|             viewPlayerDataDic[playerID] = _viewPlayerData;  | 
|         }  | 
|   | 
|         viewPlayerType = (int)ViewPlayerType.viewCrossPlayerEquip;  | 
|         ShowRoleParticulars(_viewPlayerData, playerID);  | 
|     }  | 
|   | 
|   | 
|   | 
|     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.rolePropData.PlayerID = (int)package.PlayerID;  | 
|         viewPlayerData.rolePropData.Name = package.PlayerName;  | 
|         viewPlayerData.rolePropData.LV = package.LV;  | 
|         viewPlayerData.rolePropData.Job = package.Job;  | 
|         viewPlayerData.rolePropData.RealmLV = package.RealmLV;  | 
|         viewPlayerData.rolePropData.Face = (int)package.Face;  | 
|         viewPlayerData.rolePropData.FacePic = (int)package.FacePic;  | 
|         viewPlayerData.rolePropData.TitleID = (int)package.TitleID;  | 
|         viewPlayerData.rolePropData.ServerID = (int)package.ServerID;  | 
|         viewPlayerData.rolePropData.FightPower = package.FightPower + package.FightPowerEx * (long)Constants.ExpPointValue;  | 
|         viewPlayerData.rolePropData.FamilyID = (int)package.FamilyID;  | 
|         viewPlayerData.rolePropData.FamilyName = package.FamilyName;  | 
|         viewPlayerData.rolePropData.FamilyEmblemID = (int)package.FamilyEmblemID;  | 
|   | 
|   | 
|         if (viewPlayerData.rolePlusData == null)  | 
|         {  | 
|             //第一次初始化  | 
|             viewPlayerData.rolePlusData = new RolePlusData();  | 
|         }  | 
|         if (package.PlusDataSize != 0)  | 
|         {  | 
|             viewPlayerData.rolePlusData.AnalysisRolePlusData(package.PlusData);  | 
|         }  | 
|   | 
|   | 
|         ShowRoleParticulars(viewPlayerData, (int)package.PlayerID);  | 
|     }  | 
|   | 
|     public void OnRevRoleFuncPower(HA3A1_tagMCModuleFightPowerInfo package)  | 
|     {  | 
|         if (package.MFPCnt == 0)  | 
|             return;  | 
|         for (int i = 0; i < package.MFPList.Length; i++)  | 
|         {  | 
|             funcFightPowerDict[package.MFPList[i].MfpType] = package.MFPList[i].FightPowerEx * Constants.ExpPointValue + package.MFPList[i].FightPower;  | 
|         }  | 
|         if (PowerUpdate != null)  | 
|         {  | 
|             PowerUpdate();  | 
|         }  | 
|     }  | 
|   | 
|     public long GetFuncFightPower(int type)  | 
|     {  | 
|         if (funcFightPowerDict.ContainsKey(type))  | 
|         {  | 
|             return funcFightPowerDict[type];  | 
|         }  | 
|         return 0;  | 
|     }  | 
|   | 
|     #region 查看玩家坐骑灵宠属性  | 
|       | 
|   | 
|     // int[] qualitys;  | 
|     // string[] qualityTitles;  | 
|     // public string GetQualityDisplay(int quality)  | 
|     // {  | 
|     //     if (qualitys == null)  | 
|     //     {  | 
|     //         var config = FuncConfigConfig.Get("PetQuality");  | 
|     //         qualitys = ConfigParse.GetMultipleStr<int>(config.Numerical1);  | 
|     //         qualityTitles = ConfigParse.GetMultipleStr(config.Numerical2);  | 
|     //     }  | 
|     //     for (int i = 0; i < qualitys.Length; i++)  | 
|     //     {  | 
|     //         if (quality == qualitys[i])  | 
|     //         {  | 
|     //             return qualityTitles[i];  | 
|     //         }  | 
|     //     }  | 
|     //     return string.Empty;  | 
|     // }  | 
|   | 
|   | 
|     // public int GetPetFightPower(List<PetInfo> pets)  | 
|     // {  | 
|     //     var fightPower = 0;  | 
|     //     for (int i = 0; i < pets.Count; i++)  | 
|     //     {  | 
|     //         fightPower += GetPetFightPower(pets[i].id, pets[i].lv);  | 
|     //     }  | 
|     //     return fightPower;  | 
|     // }  | 
|   | 
|     // public int GetPetFightPower(int id, int lv)  | 
|     // {  | 
|     //     var fightPower = 0;  | 
|     //     var config = PetInfoConfig.Get(id);  | 
|     //     var _init_fightpower = 0;  | 
|     //     int.TryParse(config.InitFightPower, out _init_fightpower);  | 
|     //     fightPower += _init_fightpower;  | 
|     //     PetInfoConfig.GetPetSkills(id, lv, true, ref skills);  | 
|     //     var petUpConfig = PetClassCostConfig.GetPetIdAndRank(id, lv);  | 
|     //     if (petUpConfig != null)  | 
|     //     {  | 
|     //         Dictionary<int, int> propertyDict = new Dictionary<int, int>();  | 
|     //         propertyDict.Add(77, petUpConfig.AtkAdd);  | 
|     //         propertyDict.Add(78, petUpConfig.AtkAdd);  | 
|     //         fightPower += UIHelper.GetFightPower(propertyDict);// Mathf.FloorToInt(petUpConfig.AtkAdd * 2.5f);  | 
|     //     }  | 
|     //     for (int i = 0; i < skills.Count; i++)  | 
|     //     {  | 
|     //         var skillConfig = SkillConfig.Get(skills[i]);  | 
|     //         if (skillConfig != null)  | 
|     //         {  | 
|     //             fightPower += skillConfig.FightPower;  | 
|     //         }  | 
|     //     }  | 
|     //     return fightPower;  | 
|     // }  | 
|   | 
|     // public int GetPetAtkProperty(List<PetInfo> pets)  | 
|     // {  | 
|     //     var atk = 0;  | 
|     //     for (int i = 0; i < pets.Count; i++)  | 
|     //     {  | 
|     //         atk += GetPetAtkProperty(pets[i].id, pets[i].lv, pets);  | 
|     //     }  | 
|     //     return atk;  | 
|     // }  | 
|   | 
|     // public int GetPetAtkProperty(int id, int lv, List<PetInfo> pets)  | 
|     // {  | 
|     //     var atk = 0;  | 
|     //     var petUpConfig = PetClassCostConfig.GetPetIdAndRank(id, lv);  | 
|     //     if (petUpConfig != null)  | 
|     //     {  | 
|     //         atk += petUpConfig.AtkAdd;  | 
|     //     }  | 
|     //     PetInfoConfig.GetPetSkills(id, lv, true, ref skills);  | 
|     //     for (int i = 0; i < skills.Count; i++)  | 
|     //     {  | 
|     //         atk += GetPetAtkSkillProperty(skills[i], pets);  | 
|     //     }  | 
|     //     return atk;  | 
|     // }  | 
|   | 
|     // public int GetPetAtkSkillProperty(int skillId, List<PetInfo> pets)  | 
|     // {  | 
|     //     SkillConfig skillconfig = SkillConfig.Get(skillId);  | 
|     //     if (skillconfig == null)  | 
|     //     {  | 
|     //         return 0;  | 
|     //     }  | 
|     //     if (skillconfig.Effect1 == (int)RidingAndPetActivationModel.RidingAndPetProperty.PetAttack)  | 
|     //     {  | 
|     //         return GetPetAttack(skillconfig.EffectValue11, skillconfig.EffectValue12, pets);  | 
|     //     }  | 
|     //     else if (skillconfig.Effect2 == (int)RidingAndPetActivationModel.RidingAndPetProperty.PetAttack)  | 
|     //     {  | 
|     //         return GetPetAttack(skillconfig.EffectValue21, skillconfig.EffectValue22, pets);  | 
|     //     }  | 
|     //     else if (skillconfig.Effect3 == (int)RidingAndPetActivationModel.RidingAndPetProperty.PetAttack)  | 
|     //     {  | 
|     //         return GetPetAttack(skillconfig.EffectValue31, skillconfig.EffectValue32, pets);  | 
|     //     }  | 
|     //     else if (skillconfig.Effect4 == (int)RidingAndPetActivationModel.RidingAndPetProperty.PetAttack)  | 
|     //     {  | 
|     //         return GetPetAttack(skillconfig.EffectValue41, skillconfig.EffectValue42, pets);  | 
|     //     }  | 
|     //     else if (skillconfig.Effect5 == (int)RidingAndPetActivationModel.RidingAndPetProperty.PetAttack)  | 
|     //     {  | 
|     //         return GetPetAttack(skillconfig.EffectValue51, skillconfig.EffectValue52, pets);  | 
|     //     }  | 
|     //     else if (skillconfig.Effect6 == (int)RidingAndPetActivationModel.RidingAndPetProperty.PetAttack)  | 
|     //     {  | 
|     //         return GetPetAttack(skillconfig.EffectValue61, skillconfig.EffectValue62, pets);  | 
|     //     }  | 
|     //     return 0;  | 
|     // }  | 
|   | 
|     // int GetPetAttack(int quality, int value, List<PetInfo> pets)  | 
|     // {  | 
|     //     var atk = 0;  | 
|     //     for (int i = 0; i < pets.Count; i++)  | 
|     //     {  | 
|     //         var config = PetInfoConfig.Get(pets[i].id);  | 
|     //         if (config != null && config.Quality == quality)  | 
|     //         {  | 
|     //             var petUpConfig = PetClassCostConfig.GetPetIdAndRank(pets[i].id, pets[i].lv);  | 
|     //             atk += petUpConfig == null ? 0 : petUpConfig.AtkAdd;  | 
|     //         }  | 
|     //     }  | 
|     //     return (int)(atk * ((float)value / 10000));  | 
|     // }  | 
|   | 
|     public bool viewPetStone { get; set; }  | 
|     #endregion  | 
|   | 
|     //尽量不要用第一个参数viewtype做判断,容易出错,比如同时发送两个不同的viewPlayerType请求的时候  | 
|     private void ShowRoleParticulars(ViewPlayerData _viewPlayerData, int playerID)  | 
|     {  | 
|         // if (viewPlayerType == (int)ViewPlayerType.viewPlayerEquip || viewPlayerType == (int)ViewPlayerType.viewCrossPlayerEquip)  | 
|         // {  | 
|         //     if (!WindowCenter.Instance.IsOpen<RoleParticularsWin>())  | 
|         //     {  | 
|         //         RoleParticularsWin.viewType = viewPlayerType;  | 
|         //         WindowCenter.Instance.Open<RoleParticularsWin>();  | 
|         //     }  | 
|         // }  | 
|         // else if (viewPlayerType == (int)ViewPlayerType.viewPlayerFightPower || viewPlayerType == (int)ViewPlayerType.viewCrossPlayerFightPower)  | 
|         // {  | 
|         //     if (!WindowCenter.Instance.IsOpen<ViewFuncPowerWin>())  | 
|         //     {  | 
|         //         WindowCenter.Instance.Open<ViewFuncPowerWin>();  | 
|         //     }  | 
|         // }  | 
|   | 
|           | 
|         OnRevPackage?.Invoke(viewPlayerType, playerID, _viewPlayerData);  | 
|         viewPlayerType = -1;  | 
|     }  | 
|   | 
|     public class ViewPlayerData  | 
|     {  | 
|         public RolePropData rolePropData;  | 
|         public RolePlusData rolePlusData;  | 
|   | 
|         public DateTime getTime;  | 
|   | 
|         public int GetEquipSuitLevel()  | 
|         {  | 
|             return 0;  | 
|         }  | 
|   | 
|   | 
|     }  | 
|   | 
|   | 
|     [Serializable]  | 
|     public struct RolePropData  | 
|     {  | 
|         public int PlayerID;  | 
|         public int LV;  | 
|         public int RealmLV;  | 
|         public string Name;  | 
|         public string FamilyName;  | 
|         public int Job;  | 
|         public int FamilyID;  | 
|         public long FightPower;  | 
|         public int TitleID;  | 
|         public int ServerID;  | 
|         public int FamilyEmblemID;  | 
|         public int Face;    //脸型  | 
|         public int FacePic;    //脸型外框  | 
|     }  | 
|   | 
|   | 
|     public class RolePlusData  | 
|     {  | 
|         Dictionary<int, ulong> fightPowerDict = new Dictionary<int, ulong>();  | 
|         Dictionary<int, int> godWeaponDict = new Dictionary<int, int>();  | 
|         Dictionary<int, int> treasureDict = new Dictionary<int, int>();  | 
|         public List<HorseInfo> horses = new List<HorseInfo>();  | 
|         public List<PetInfo> pets = new List<PetInfo>();  | 
|         public List<AlchemyDrug> alchemyDrugs = new List<AlchemyDrug>();  | 
|         public int Horse { get; private set; } //改为等级  | 
|         public int Pet { get; private set; }  | 
|   | 
|         public int AtkSpeed { get; private set; }  | 
|         public int Rune { get; private set; }  | 
|         public int orangeEquipsCount { get; private set; }  | 
|         public int totalGemsLevel { get; private set; }  | 
|         public int totalEquipWashLevel { get; private set; }  | 
|         public int totalEquipStarLevel { get; private set; }  | 
|         public int totalEquipStrengthLevel { get; private set; }  | 
|         public int totalEquipEvolveLevel { get; private set; }  | 
|         public int totalSkillLevel { get; private set; }  | 
|   | 
|         public ulong GetFightPower(int type)  | 
|         {  | 
|             if (fightPowerDict != null && fightPowerDict.ContainsKey(type))  | 
|             {  | 
|                 return fightPowerDict[type];  | 
|             }  | 
|             return 0;  | 
|         }  | 
|   | 
|   | 
|   | 
|         public void AnalysisRolePlusData(string jsonStr)  | 
|         {  | 
|             try  | 
|             {  | 
|                 var jsonData = JsonMapper.ToObject(jsonStr);  | 
|                 if (jsonData.Keys.Contains("FightPowerDict"))  | 
|                 {  | 
|                     var jsonPlusData = jsonData["FightPowerDict"];  | 
|                     if (jsonPlusData.IsObject)  | 
|                     {  | 
|                         foreach (var key in jsonPlusData.Keys)  | 
|                         {  | 
|                             int type = int.Parse(key);  | 
|                             fightPowerDict.Add(type, ulong.Parse(jsonPlusData[key].ToString()));  | 
|                         }  | 
|                     }  | 
|                 }  | 
|   | 
|                   | 
|                 // if (jsonData.Keys.Contains("Pet"))  | 
|                 // {  | 
|                 //     var jsonPlusData = jsonData["Pet"];  | 
|                 //     if (jsonPlusData.IsObject)  | 
|                 //     {  | 
|                 //         foreach (var _key in jsonPlusData.Keys)  | 
|                 //         {  | 
|                 //             if (_key.Equals("AtkSpeed"))  | 
|                 //             {  | 
|                 //                 AtkSpeed = int.Parse(jsonPlusData[_key].ToString());  | 
|                 //             }  | 
|                 //             else if (_key.Equals("PetLV"))  | 
|                 //             {  | 
|                 //                 var petInfos = JsonMapper.ToObject<PetInfo[]>(jsonPlusData[_key].ToJson());  | 
|                 //                 if (petInfos != null && petInfos.Length > 0)  | 
|                 //                 {  | 
|                 //                     for (int i = 0; i < petInfos.Length; i++)  | 
|                 //                     {  | 
|                 //                         var petInfo = petInfos[i];  | 
|                 //                         pets.Add(new PetInfo()  | 
|                 //                         {  | 
|                 //                             id = petInfo.id,  | 
|                 //                             lv = petInfo.lv + 1,  | 
|                 //                         });  | 
|                 //                     }  | 
|                 //                 }  | 
|                 //             }  | 
|                 //         }  | 
|                 //         pets.Sort(Compare);  | 
|                 //     }  | 
|                 //     Pet = pets.Count;  | 
|                 // }  | 
|                 // else  | 
|                 // {  | 
|                 //     Pet = 0;  | 
|                 // }  | 
|                   | 
|             }  | 
|             catch (Exception e)  | 
|             {  | 
|                 Debug.Log(e.StackTrace);  | 
|             }  | 
|         }  | 
|   | 
|         // int Compare(PetInfo x, PetInfo y)  | 
|         // {  | 
|         //     var config_x = PetInfoConfig.Get(x.id);  | 
|         //     var config_y = PetInfoConfig.Get(y.id);  | 
|         //     if (config_x == null || config_y == null)  | 
|         //     {  | 
|         //         return 0;  | 
|         //     }  | 
|         //     return -config_x.Sort.CompareTo(config_y.Sort);  | 
|         // }  | 
|   | 
|         // int Compare(HorseInfo x, HorseInfo y)  | 
|         // {  | 
|         //     var config_x = HorseConfig.Get(x.id);  | 
|         //     var config_y = HorseConfig.Get(y.id);  | 
|         //     if (config_x == null || config_y == null)  | 
|         //     {  | 
|         //         return 0;  | 
|         //     }  | 
|         //     return -config_x.Sort.CompareTo(config_y.Sort);  | 
|         // }  | 
|     }  | 
|   | 
|     public struct HorseInfo  | 
|     {  | 
|         public int id;  | 
|         public int lv;  | 
|     }  | 
|   | 
|     public struct PetInfo  | 
|     {  | 
|         public int id;  | 
|         public int lv;  | 
|     }  | 
|   | 
|     public struct AlchemyDrug  | 
|     {  | 
|         public int item;  | 
|         public int count;  | 
|     }  | 
| }  | 
|   |