using Assets.MyGame.Scripts.Net.API.GameConfig_SubClass; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace Assets.MyGame.Scripts.Net.WebResponses { public static class FrameDataParser { public static T Parse(object frameData) where T : class, new() { if (frameData == null) return null; // 如果已经是目标类型,直接返回 if (frameData is T typed) return typed; // 如果是字符串,直接反序列化 if (frameData is string str) return JsonConvert.DeserializeObject(str); // 如果是 JObject,轻量解析 if (frameData is JObject jObj) return jObj.ToObject(); // 兜底:调用 ToString 再反序列化 return JsonConvert.DeserializeObject(frameData.ToString()); } } [Serializable] public enum FrameDataType { none = 0, rotateTurrect=1, fireBullet=2, // createFish=3 已废弃:鱼创建改由服务端 OnFishSpawn 事件下发 changeAutoTarget=4, randomDieFish=5, changeTurretState=6, changeTurret=7, freezeFish=8, changeCannonMultiple=9, changeWing=10, // requestSyncFish=11 已废弃:鱼同步改由服务端 OnFishSpawn(type=sync) 事件下发 /// 爆奖结束:某玩家爆奖流程完成,广播给其他客户端显示最终 BJEndUI 并加分 baoJiangEnd=12, /// 切换战神:某玩家装备/卸下战神,广播给其他客户端在对应座位加载/清除战神模型 changeZhanShen=13, /// 表情包:某玩家发送表情(spine动画/文字),广播给其他客户端在对应座位显示 biaoQing=14, /// 钻头蟹/激光蟹释放:击杀者点击(或超时)发射钻头/激光,广播给房间所有客户端(含发送者回广播),各端统一时刻发射 zuanTouRelease=15, /// 加金币:某玩家通过刮刮卡等 HTTP 途径获得金币(服务端不加房间推送),发送端本地加好后广播,各客户端给对应座位加金币 addGold=16, } [Serializable] public class FireCannonSendData { public string roomId; public string userId; public long gold; public int count; public List bulletIds; public SyncGameData extra; public bool isBot; /// 服务端权威:每发子弹扣费明细(bulletId + gold) public List bullets; /// 服务端时间戳 public long timestamp; } /// /// 单发子弹扣费明细:服务端在 FireCannon 广播里返回的权威扣费金额 /// [Serializable] public class BulletGold { public string bulletId; public long gold; } /// /// 同步游戏数据 /// [Serializable] public class SyncGameData { public int sitPos; public FrameDataType frameType; public long time; public object frameData; } [Serializable] public class FrameData { } [Serializable] public class FrameData_Rotate : FrameData { public float angle; } [Serializable] public class FrameData_FireBullet : FrameData { public float angle; public long gold; public bool isSanShe; public bool isSuoDing; public bool auto; public bool twoRTruuect; public string monsterID; public bool isZuanTou; /// 三发锁定时每个子弹对应的鱼 GUID(3个),按优先级排序 public List monsterIDs; } [Serializable] public class FrameData_CreateFish : FrameData { public string fishNumber; public string guid; public string moveLineId; } [Serializable] public class FrameData_ChangeAutoTarget : FrameData { public List< string> targetGuid; public int colliderIndex; } [Serializable] public class FrameData_RandomDieFish : FrameData { public float x; public float y; public float z; public List guids=new List(); public List coinNum=new List(); public int count; } [Serializable] public class FrameData_TurretState : FrameData { public TurretState state; } [Serializable] public class FrameData_ChangeTurret : FrameData { public int turretIndex; } [Serializable] public class FrameData_FreezeFish : FrameData { public bool isFreeze; } [Serializable] public class FrameData_ChangeCannonMultiple : FrameData { public int cannonMultiple; } /// /// 爆奖结束帧数据(frameType=baoJiangEnd)。 /// 服务端在玩家爆奖流程完成时广播,其他客户端据此显示最终 BJEndUI 并加分。 /// [Serializable] public class FrameData_BaoJiangEnd : FrameData { /// 爆奖玩家 ID public string userId; /// 击杀者座位 ID public int posID; /// 死亡的鱼 ID(用于匹配 pending 的 not-self 爆奖) public string fishId; /// 最终倍数 public int beishu; /// 最终得分(金币) public long score; } /// /// 加金币帧数据(frameType=addGold)。 /// 刮刮卡等 HTTP 途径获得金币后,由获得者客户端广播,各客户端给对应座位(sync.sitPos)加金币并刷新显示。 /// [Serializable] public class FrameData_AddGold : FrameData { /// 增加的金币数 public long gold; /// 来源描述(金币流水日志用,如 "GuaGuaKa") public string source; } /// /// 表情包类型:spine 动画表情 / 文字表情 /// [Serializable] public enum BiaoQingType { /// Spine 动画表情(frameData.content=动画名,spineIndex=配置下标) spine = 1, /// 文字表情(frameData.content=文字内容) zi = 2, } /// /// 表情包帧数据(frameType=biaoQing)。 /// 某玩家点击表情后广播,各客户端在发送者座位上显示表情。 /// [Serializable] public class FrameData_BiaoQing : FrameData { /// 表情类型:spine=动画表情 zi=文字表情 public BiaoQingType biaoQingType; /// spine 表情:GameMainPanel_FishBase.list_BiaoQingSpine 的下标(文字表情不用) public int spineIndex; /// spine 表情=动画名;文字表情=文字内容 public string content; } /// /// 钻头蟹/激光蟹释放帧数据(frameType=zuanTouRelease)。 /// 击杀者点击(或超时)时由击杀者客户端发送(机器人击杀由房主代发), /// 服务器广播给房间所有人(含发送者回广播),各客户端按 fishId 匹配本地爆奖事件统一发射。 /// [Serializable] public class FrameData_ZuanTouRelease : FrameData { /// 击杀者 userId public string userId; /// 死亡的特殊鱼 ID(各端用它匹配本地正在等待释放的爆奖事件实例) public string fishId; /// 发射时的炮台源角度(下方座位坐标系,接收端按该座位在本端显示位置用 SeatMirror 还原) public float angle; } // ================================================================ // OnFishSpawn 事件数据结构 (服务端出鱼,破坏性替代 createFish 帧同步) // ================================================================ /// /// 服务端出鱼事件 OnFishSpawn 的数据载体。 /// type: /// "init" - 首次出鱼(玩家进入房间后服务端推送初始鱼) /// "spawn" - 定时出鱼(游戏中持续刷怪) /// "sync" - 重连/取消挂机同步(把当前场上活鱼推送给回归玩家) /// [Serializable] public class OnFishSpawnData { /// "init" | "spawn" | "sync" public string type; /// 服务器当前时间戳(毫秒) public long timestamp; /// 本批次出鱼列表 public List fish; } /// /// OnFishSpawn 单条鱼描述。 /// 客户端据此调用 SpawnFishMainThread 生成鱼实例。 /// [Serializable] public class OnFishSpawnFishItem { /// 服务端分配的全局唯一鱼 ID(作为 guid 使用) public long fishId; /// 鱼编号(配置 fishNumber) public string fishNumber; /// 路径编号 public int routeId; /// 鱼阵编号(非鱼阵时为空字符串) public string fishArrayNumber; /// 鱼阵的 Boss 鱼编号 public string bossFishNumber; /// 鱼阵普通鱼数量 public int fishCount; /// 鱼阵 Boss 数量 public int bossCount; /// 鱼创建时间戳(毫秒),到期自动移除 public long createdAt; /// 鱼过期时间戳(毫秒),到期自动移除 public long expireAt; /// 鱼剩余存活秒数(客户端做倒计时用) public int remainingSeconds; } /// /// 机器人退出房间通知数据 BotLeaveRoomNotice: { userId } /// [Serializable] public class BotLeaveRoomNoticeData { public string userId; } /// /// 玩家挂机/取消挂机通知数据: { userId } /// [Serializable] public class PlayerAfkNoticeData { public string userId; } /// /// 玩家信息同步 OnPlayerInfo 数据(GetPlayerInfo 的新响应,发送给调用者)。 /// 旧事件 SendPlayerInfoResult 只返回 gold;本事件返回完整玩家信息。 /// [Serializable] public class OnPlayerInfoData { /// 玩家ID public string userId; /// 玩家昵称 public string userName; /// 金币 public long gold; /// 钻石 public int diamond; /// VIP等级 public int viplvl; /// 炮倍 public int cannonMultiple; /// 炮台ID public string cannonId; /// 翅膀ID public string wingsId; /// 座位位置 public int position; } /// /// 召唤卡召唤通知 SummonCardFishNotice 数据。 /// 仅用于播放召唤提示/特效/显示召唤玩家,实际鱼对象仍由 OnFishSpawn 创建。 /// [Serializable] public class SummonCardFishNoticeData { /// 房间ID public string roomId; /// 使用召唤卡的玩家ID public string userId; /// 玩家编号 public string userNumber; /// 玩家昵称 public string userName; /// 鱼类型 2=Boss鱼(飞机场/星际迷航场次), 3=黄金鱼(其他场次) public int fishType; /// "Boss鱼"或"黄金鱼" public string fishTypeName; /// 鱼配置编号 public string fishNumber; /// 鱼实例ID,与 OnFishSpawn 中的 fishId 一致 public long fishId; } /// /// 全局击杀公告 KillNotice 数据。 /// 真人击杀时只填基础字段;机器人模拟时额外填 fishName/multiplier/sceneName。 /// [Serializable] public class KillNoticeData { /// 鱼编号 public string FishId; /// 玩家名 public string userName; /// 金币 public long gold; // —— 机器人模拟时额外字段 —— /// 鱼名(机器人模拟时填充) public string fishName; /// 倍数(机器人模拟时填充) public int? multiplier; /// 场景名(机器人模拟时填充) public string sceneName; } }