1
This commit is contained in:
@@ -18,7 +18,7 @@ namespace Assets.MyGame.Scripts.Net
|
||||
//public const string baseURL = "http://game5241.wzaxr.top";
|
||||
#if UNITY_EDITOR
|
||||
//public const string baseURL = "http://8.137.163.153";
|
||||
public const string baseURL = "http://47.109.34.50";
|
||||
public const string baseURL = "http://47.109.132.12";
|
||||
|
||||
#else
|
||||
//public const string baseURL = "http://8.137.8.46";
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Assets.MyGame.Scripts.Net.WebResponses
|
||||
none = 0,
|
||||
rotateTurrect=1,
|
||||
fireBullet=2,
|
||||
createFish=3,
|
||||
// createFish=3 已废弃:鱼创建改由服务端 OnFishSpawn 事件下发
|
||||
changeAutoTarget=4,
|
||||
randomDieFish=5,
|
||||
changeTurretState=6,
|
||||
@@ -52,8 +52,7 @@ namespace Assets.MyGame.Scripts.Net.WebResponses
|
||||
freezeFish=8,
|
||||
changeCannonMultiple=9,
|
||||
changeWing=10,
|
||||
/// <summary>新玩家资源加载完成,请求房主广播场上活鱼</summary>
|
||||
requestSyncFish=11
|
||||
// requestSyncFish=11 已废弃:鱼同步改由服务端 OnFishSpawn(type=sync) 事件下发
|
||||
}
|
||||
[Serializable]
|
||||
public class FireCannonSendData
|
||||
@@ -145,4 +144,93 @@ namespace Assets.MyGame.Scripts.Net.WebResponses
|
||||
{
|
||||
public int cannonMultiple;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// OnFishSpawn 事件数据结构 (服务端出鱼,破坏性替代 createFish 帧同步)
|
||||
// ================================================================
|
||||
|
||||
/// <summary>
|
||||
/// 服务端出鱼事件 OnFishSpawn 的数据载体。
|
||||
/// type:
|
||||
/// "init" - 首次出鱼(玩家进入房间后服务端推送初始鱼)
|
||||
/// "spawn" - 定时出鱼(游戏中持续刷怪)
|
||||
/// "sync" - 重连/取消挂机同步(把当前场上活鱼推送给回归玩家)
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class OnFishSpawnData
|
||||
{
|
||||
/// <summary>"init" | "spawn" | "sync"</summary>
|
||||
public string type;
|
||||
/// <summary>服务器当前时间戳(毫秒)</summary>
|
||||
public long timestamp;
|
||||
/// <summary>本批次出鱼列表</summary>
|
||||
public List<OnFishSpawnFishItem> fish;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnFishSpawn 单条鱼描述。
|
||||
/// 客户端据此调用 SpawnFishMainThread 生成鱼实例。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class OnFishSpawnFishItem
|
||||
{
|
||||
/// <summary>服务端分配的全局唯一鱼 ID(作为 guid 使用)</summary>
|
||||
public long fishId;
|
||||
/// <summary>鱼编号(配置 fishNumber)</summary>
|
||||
public string fishNumber;
|
||||
/// <summary>路径编号</summary>
|
||||
public int routeId;
|
||||
/// <summary>鱼阵编号(非鱼阵时为空字符串)</summary>
|
||||
public string fishArrayNumber;
|
||||
/// <summary>鱼阵的 Boss 鱼编号</summary>
|
||||
public string bossFishNumber;
|
||||
/// <summary>鱼阵普通鱼数量</summary>
|
||||
public int fishCount;
|
||||
/// <summary>鱼阵 Boss 数量</summary>
|
||||
public int bossCount;
|
||||
/// <summary>鱼过期时间戳(毫秒),到期自动移除</summary>
|
||||
public long expireAt;
|
||||
/// <summary>鱼剩余存活秒数(客户端做倒计时用)</summary>
|
||||
public int remainingSeconds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 机器人退出房间通知数据 BotLeaveRoomNotice: { userId }
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class BotLeaveRoomNoticeData
|
||||
{
|
||||
public string userId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 玩家挂机/取消挂机通知数据: { userId }
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class PlayerAfkNoticeData
|
||||
{
|
||||
public string userId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 全局击杀公告 KillNotice 数据。
|
||||
/// 真人击杀时只填基础字段;机器人模拟时额外填 fishName/multiplier/sceneName。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class KillNoticeData
|
||||
{
|
||||
/// <summary>鱼编号</summary>
|
||||
public string FishId;
|
||||
/// <summary>玩家名</summary>
|
||||
public string userName;
|
||||
/// <summary>金币</summary>
|
||||
public long gold;
|
||||
// —— 机器人模拟时额外字段 ——
|
||||
/// <summary>鱼名(机器人模拟时填充)</summary>
|
||||
public string fishName;
|
||||
/// <summary>倍数(机器人模拟时填充)</summary>
|
||||
public int? multiplier;
|
||||
/// <summary>场景名(机器人模拟时填充)</summary>
|
||||
public string sceneName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Assets.MyGame.Scripts.Net
|
||||
//private const string baseUrl = "ws://game5241.wzaxr.top";
|
||||
#if UNITY_EDITOR
|
||||
//private const string baseUrl = "ws://8.137.163.153";
|
||||
private const string baseUrl = "ws://47.109.34.50";
|
||||
private const string baseUrl = "ws://47.109.132.12";
|
||||
|
||||
#else
|
||||
//private const string baseUrl = "ws://8.137.8.46";
|
||||
|
||||
@@ -453,31 +453,20 @@ namespace Assets.MyGame.Scripts.Net
|
||||
break;
|
||||
case "ChangeControllerUser":
|
||||
{
|
||||
// ⭐ 房主控制权移交:仅维护 roomOwnerSit,不再设置 fangzhu
|
||||
// (鱼创建已由服务端 OnFishSpawn 统一下发,客户端无需房主出鱼)
|
||||
var userId = JsonConvert.DeserializeObject<WebSocketResponseBase<string>>(msg).arguments[0];
|
||||
if (userId == GameManager.Instance.user.id)
|
||||
{
|
||||
// 本地玩家成为房主:开启出鱼 + 同步本地房主引用
|
||||
CreateFishManager.Instance.fangzhu = true;
|
||||
if (SitPosData.localPlayerSit != null)
|
||||
SitPosData.roomOwnerSit = SitPosData.localPlayerSit;
|
||||
}
|
||||
else if (userId != null && userId.StartsWith("bot_"))
|
||||
{
|
||||
// 房主是人机:人机无法真正发包,由本地首个非人机玩家代发
|
||||
// 房主是人机:由本地首个非人机玩家代行房主显示职责
|
||||
SitPosData.TransferRoomOwner();
|
||||
CreateFishManager.Instance.fangzhu =
|
||||
SitPosData.roomOwnerSit != null &&
|
||||
SitPosData.roomOwnerSit.user == GameManager.Instance.user.id;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ⭐ 只在 userId 非空且确实是真人玩家时才停止本地出鱼
|
||||
// userId 为空(异常情况)时保持原状,避免误关出鱼导致 bot 退出后不出鱼
|
||||
if (!string.IsNullOrEmpty(userId))
|
||||
CreateFishManager.Instance.fangzhu = false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case "Exception":
|
||||
{
|
||||
@@ -590,18 +579,8 @@ namespace Assets.MyGame.Scripts.Net
|
||||
break;
|
||||
|
||||
case "KillNotice":
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<Dictionary<string, object>>>(msg).arguments[0];
|
||||
if (data == null) break;
|
||||
// { FishId, userName, gold }
|
||||
string userName = data.TryGetValue("userName", out var un) ? un?.ToString() : "";
|
||||
string fishId = data.TryGetValue("FishId", out var fi) ? fi?.ToString() : "";
|
||||
long gold = data.TryGetValue("gold", out var g) ? Convert.ToInt64(g) : 0;
|
||||
string roomName = GameManager.Instance.gameData.currRoomData?.roomName ?? "";
|
||||
string roomLevel = GameManager.Instance.gameData.currRoomData?.roomLevel.ToString() ?? "";
|
||||
string msgText = $"恭喜用户{userName} 在 {roomName} {roomLevel}场 捕获了{fishId}*{gold}倍";
|
||||
//UIManager.Instance.ShowBoardGongGao(msgText);
|
||||
}
|
||||
// 全局击杀公告(真人击杀/机器人模拟)
|
||||
WebSocketReponseList.KillNotice(msg);
|
||||
break;
|
||||
|
||||
case "OnFishExpired":
|
||||
@@ -612,49 +591,48 @@ namespace Assets.MyGame.Scripts.Net
|
||||
break;
|
||||
|
||||
case "OnFishList":
|
||||
{
|
||||
var fishList = JsonConvert.DeserializeObject<WebSocketResponseBase<object[]>>(msg).arguments[0];
|
||||
Debug.Log($"[FishGameHub] 鱼列表刷新, 数量={fishList?.Length}");
|
||||
}
|
||||
// 鱼列表刷新
|
||||
WebSocketReponseList.OnFishList(msg);
|
||||
break;
|
||||
|
||||
// ======== FishGameHub / FishRoomHub 补充事件 ========
|
||||
|
||||
case "BotLeaveRoomNotice":
|
||||
{
|
||||
// 机器人退出房间,数据 { userId }
|
||||
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<Dictionary<string, object>>>(msg).arguments[0];
|
||||
string botUserId = data != null && data.TryGetValue("userId", out var buid) ? buid?.ToString() : "";
|
||||
Debug.Log($"[FishGameHub] 机器人退出: {botUserId}");
|
||||
WebSocketReponseList.BotLeaveRoom(botUserId);
|
||||
}
|
||||
// 机器人退出房间,数据 { userId }
|
||||
WebSocketReponseList.BotLeaveRoomNotice(msg);
|
||||
break;
|
||||
|
||||
case "HostDisconnect":
|
||||
{
|
||||
// 房主断线,其他玩家可接受机器人控制权
|
||||
Debug.Log("[FishGameHub] 房主断线,可接受机器人控制权");
|
||||
WebSocketReponseList.HostDisconnect();
|
||||
}
|
||||
// 房主断线,其他玩家可接受机器人控制权
|
||||
WebSocketReponseList.HostDisconnectNotice(msg);
|
||||
break;
|
||||
|
||||
case "OnSeatChange":
|
||||
{
|
||||
// 座位变更 { type, userId, position, showWaiting? }
|
||||
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<Dictionary<string, object>>>(msg).arguments[0];
|
||||
if (data != null)
|
||||
{
|
||||
// 注意:JSON 字段可能是 long/double/string/bool 等任意类型,
|
||||
// 直接 Convert.ToInt32(object) 对字符串会走 int.Parse 抛 FormatException。
|
||||
// 这里统一通过 ToString() + TryParse 容错。
|
||||
int seatType = data.TryGetValue("type", out var t) && int.TryParse(t?.ToString(), out var st) ? st : 0;
|
||||
string userId = data.TryGetValue("userId", out var u) ? u?.ToString() : "";
|
||||
int position = data.TryGetValue("position", out var p) && int.TryParse(p?.ToString(), out var pos) ? pos : -1;
|
||||
bool showWaiting = data.TryGetValue("showWaiting", out var sw) && (sw is bool b ? b : (sw != null && bool.TryParse(sw.ToString(), out var bv) && bv));
|
||||
Debug.Log($"[FishGameHub] 座位变更: type={seatType}, userId={userId}, position={position}, showWaiting={showWaiting}");
|
||||
WebSocketReponseList.SeatChange(seatType, userId, position, showWaiting);
|
||||
}
|
||||
}
|
||||
// 座位变更 { type, userId, position, showWaiting? }
|
||||
WebSocketReponseList.OnSeatChange(msg);
|
||||
break;
|
||||
|
||||
// ======== 新协议事件 ========
|
||||
|
||||
case "OnFishSpawn":
|
||||
// ⭐ 服务端出鱼事件(破坏性替代 createFish 帧同步)
|
||||
// type: "init"=首次出鱼 / "spawn"=定时出鱼 / "sync"=重连或取消挂机同步
|
||||
WebSocketReponseList.OnFishSpawn(msg);
|
||||
break;
|
||||
|
||||
case "FishFrozen":
|
||||
// ⭐ 冰冻道具(40003)生效:鱼存活时间延长 15 秒,客户端写死 15s 倒计时
|
||||
WebSocketReponseList.FishFrozen(msg);
|
||||
break;
|
||||
|
||||
case "PlayerAfkNotice":
|
||||
// 玩家挂机通知 { userId }
|
||||
WebSocketReponseList.PlayerAfkNotice(msg);
|
||||
break;
|
||||
|
||||
case "PlayerCancelAfkNotice":
|
||||
// 玩家取消挂机通知 { userId }
|
||||
WebSocketReponseList.PlayerCancelAfkNotice(msg);
|
||||
break;
|
||||
|
||||
case "RoomChange":
|
||||
|
||||
@@ -233,9 +233,7 @@ namespace Assets.MyGame.Scripts.Net
|
||||
// 与 RoomFireNotice(FireCannonSendData) 分开处理,仅用于存储角度到 botLastAngle
|
||||
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_BotFireAngle, syncGameData);
|
||||
break;
|
||||
case FrameDataType.createFish:
|
||||
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_CreateFish, syncGameData);
|
||||
break;
|
||||
// createFish=3 已废弃:鱼创建改由服务端 OnFishSpawn 事件下发
|
||||
case FrameDataType.changeAutoTarget:
|
||||
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_ChangeTargetMonster, syncGameData);
|
||||
break;
|
||||
@@ -258,15 +256,123 @@ namespace Assets.MyGame.Scripts.Net
|
||||
case FrameDataType.changeWing:
|
||||
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_ChangeWing, syncGameData);
|
||||
break;
|
||||
case FrameDataType.requestSyncFish:
|
||||
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_RequestSyncFish, syncGameData);
|
||||
break;
|
||||
// requestSyncFish=11 已废弃:鱼同步改由服务端 OnFishSpawn(type=sync) 下发
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 新协议事件分发 (OnFishSpawn / PlayerAfk / FishFrozen / KillNotice 等)
|
||||
// ================================================================
|
||||
|
||||
/// <summary>
|
||||
/// 服务端出鱼事件 OnFishSpawn 处理。
|
||||
/// 破坏性替代旧 createFish 帧同步:服务端统一出鱼,客户端只接收并生成。
|
||||
/// </summary>
|
||||
public static void OnFishSpawn(string msg)
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<OnFishSpawnData>>(msg).arguments[0];
|
||||
if (data == null) return;
|
||||
EventCenter.Instance.EventTrigger<OnFishSpawnData>(ConstEventString.OnFishSpawn, data);
|
||||
}
|
||||
|
||||
/// <summary>鱼列表刷新</summary>
|
||||
public static void OnFishList(string msg)
|
||||
{
|
||||
var fishList = JsonConvert.DeserializeObject<WebSocketResponseBase<object[]>>(msg).arguments[0];
|
||||
EventCenter.Instance.EventTrigger<object[]>(ConstEventString.OnFishList, fishList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 冰冻道具(40003)生效事件 FishFrozen。
|
||||
/// 鱼存活时间延长 15 秒,客户端写死 15s 倒计时。
|
||||
/// </summary>
|
||||
public static void FishFrozen(string msg)
|
||||
{
|
||||
EventCenter.Instance.EventTrigger(ConstEventString.FishFrozen);
|
||||
}
|
||||
|
||||
/// <summary>玩家挂机通知</summary>
|
||||
public static void PlayerAfkNotice(string msg)
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<PlayerAfkNoticeData>>(msg).arguments[0];
|
||||
if (data == null) return;
|
||||
EventCenter.Instance.EventTrigger<PlayerAfkNoticeData>(ConstEventString.PlayerAfkNotice, data);
|
||||
}
|
||||
|
||||
/// <summary>玩家取消挂机通知</summary>
|
||||
public static void PlayerCancelAfkNotice(string msg)
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<PlayerAfkNoticeData>>(msg).arguments[0];
|
||||
if (data == null) return;
|
||||
EventCenter.Instance.EventTrigger<PlayerAfkNoticeData>(ConstEventString.PlayerCancelAfkNotice, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 全局击杀公告 KillNotice。
|
||||
/// 真人击杀/机器人模拟,机器人模拟时额外带 fishName/multiplier/sceneName。
|
||||
/// </summary>
|
||||
public static void KillNotice(string msg)
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<KillNoticeData>>(msg).arguments[0];
|
||||
if (data == null) return;
|
||||
EventCenter.Instance.EventTrigger<KillNoticeData>(ConstEventString.KillNotice, data);
|
||||
}
|
||||
|
||||
/// <summary>机器人退出房间通知</summary>
|
||||
public static void BotLeaveRoomNotice(string msg)
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<BotLeaveRoomNoticeData>>(msg).arguments[0];
|
||||
if (data == null) return;
|
||||
WebSocketReponseList.BotLeaveRoom(data.userId);
|
||||
}
|
||||
|
||||
/// <summary>房主断线</summary>
|
||||
public static void HostDisconnectNotice(string msg)
|
||||
{
|
||||
EventCenter.Instance.EventTrigger(ConstEventString.HostDisconnect);
|
||||
WebSocketReponseList.HostDisconnect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 座位变更 OnSeatChange。
|
||||
/// 数据: { type, userId, position, showWaiting? }
|
||||
/// </summary>
|
||||
public static void OnSeatChange(string msg)
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<Dictionary<string, object>>>(msg).arguments[0];
|
||||
if (data == null) return;
|
||||
// JSON 字段可能是 long/double/string/bool 等任意类型,统一 ToString()+TryParse 容错
|
||||
int seatType = data.TryGetValue("type", out var t) && int.TryParse(t?.ToString(), out var st) ? st : 0;
|
||||
string userId = data.TryGetValue("userId", out var u) ? u?.ToString() : "";
|
||||
int position = data.TryGetValue("position", out var p) && int.TryParse(p?.ToString(), out var pos) ? pos : -1;
|
||||
bool showWaiting = data.TryGetValue("showWaiting", out var sw) && (sw is bool b ? b : (sw != null && bool.TryParse(sw.ToString(), out var bv) && bv));
|
||||
WebSocketReponseList.SeatChange(seatType, userId, position, showWaiting);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 房主控制权移交 ChangeControllerUser。
|
||||
/// 仅维护 SitPosData.roomOwnerSit,不再设置 fangzhu(鱼创建已由服务端统一出鱼)。
|
||||
/// </summary>
|
||||
public static void ChangeControllerUser(string msg)
|
||||
{
|
||||
var userId = JsonConvert.DeserializeObject<WebSocketResponseBase<string>>(msg).arguments[0];
|
||||
if (userId == GameManager.Instance.user.id)
|
||||
{
|
||||
// 本地玩家成为房主:同步本地房主引用
|
||||
if (SitPosData.localPlayerSit != null)
|
||||
SitPosData.roomOwnerSit = SitPosData.localPlayerSit;
|
||||
}
|
||||
else if (userId != null && userId.StartsWith("bot_"))
|
||||
{
|
||||
// 房主是人机:人机无法真正发包,由本地首个非人机玩家代行房主显示职责
|
||||
SitPosData.TransferRoomOwner();
|
||||
}
|
||||
// 其他真人玩家成为房主时无需本地操作(roomOwnerSit 由 TransferRoomOwner/ShowPlayer 维护)
|
||||
}
|
||||
public static void LeaveRoomResult(string msg)
|
||||
{
|
||||
//WebSocketManager.Instance.isGame = false;
|
||||
|
||||
@@ -242,6 +242,26 @@ public partial class WebSocketSendList
|
||||
var sendObj = new WebSocketSendList("ChangeGunMultiple", roomId, userId, multiple);
|
||||
WebSocketManager.Instance.Send(SocketType.game, JsonConvert.SerializeObject(sendObj));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 玩家挂机(对应服务端 SetPlayerAfkNEW)
|
||||
/// 服务端会向房间组广播 PlayerAfkNotice 事件
|
||||
/// </summary>
|
||||
public static void SetPlayerAfk(string roomId, string userId)
|
||||
{
|
||||
var sendObj = new WebSocketSendList("SetPlayerAfkNEW", roomId, userId);
|
||||
WebSocketManager.Instance.Send(SocketType.game, JsonConvert.SerializeObject(sendObj));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消挂机(对应服务端 CancelPlayerAfkNEW)
|
||||
/// 服务端会向房间组广播 PlayerCancelAfkNotice 事件,并通过 OnFishSpawn(type=sync) 同步当前鱼
|
||||
/// </summary>
|
||||
public static void CancelPlayerAfk(string roomId, string userId)
|
||||
{
|
||||
var sendObj = new WebSocketSendList("CancelPlayerAfkNEW", roomId, userId);
|
||||
WebSocketManager.Instance.Send(SocketType.game, JsonConvert.SerializeObject(sendObj));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步等级常量(秒)
|
||||
@@ -284,17 +304,14 @@ public partial class WebSocketSendList
|
||||
_syncLv1Append.Add(sgd);
|
||||
return;
|
||||
|
||||
case FrameDataType.createFish:
|
||||
// createFish=3 已废弃:鱼创建改由服务端 OnFishSpawn 下发
|
||||
case FrameDataType.changeTurretState:
|
||||
case FrameDataType.changeTurret:
|
||||
case FrameDataType.freezeFish:
|
||||
_syncLv2Append.Add(sgd);
|
||||
return;
|
||||
|
||||
case FrameDataType.requestSyncFish:
|
||||
// ⭐ 新玩家加载完成的"请求同步鱼":立即发送,房主尽快响应广播
|
||||
SendImmediate(BuildJson(sgd));
|
||||
return;
|
||||
// requestSyncFish=11 已废弃:鱼同步改由服务端 OnFishSpawn(type=sync) 下发
|
||||
|
||||
default:
|
||||
_syncLv3Append.Add(sgd);
|
||||
|
||||
Reference in New Issue
Block a user