Files
5.24BuYu/Assets/MyGame/Scripts/Net/WebSocketSendList_Fish.cs
T
2026-07-21 04:36:52 +08:00

344 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Assets.MyGame.Scripts.Net;
using Assets.MyGame.Scripts.Net.WebResponses;
using Assets.MyGame.Scripts.Net.WebResponses.ChineseChess;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using Unity.VisualScripting;
using UnityEngine;
public partial class WebSocketSendList
{
public static string MakeKillFishSign(
string roomId,
string userId,
string fishNumber,
string fishId,
long gold,
long timespan,
string bulletId,
long timestamp,
string signKey
)
{
string rawStr = $"{roomId}|{userId}|{fishNumber}|{fishId}|{gold}|{timespan}|{bulletId}|{timestamp}";
return Sign(rawStr, signKey);
}
public static string MakeFireCannonSign(string roomId, string userId, long gold, int count, long timestamp, string signKey)
{
string rawStr = $"{roomId}|{userId}|{gold}|{count}|{timestamp}";
Debug.Log($"生成签名的原始字符串:{rawStr}");
return Sign(rawStr, signKey);
}
public static string Sign(string rawStr, string signKey)
{
string input = rawStr + "|" + signKey;
using (var md5 = System.Security.Cryptography.MD5.Create())
{
byte[] bytes = Encoding.UTF8.GetBytes(input);
byte[] hash = md5.ComputeHash(bytes);
// 转成 hex 字符串(前 8 位)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("x2"));
}
return sb.ToString().Substring(0, 8);
}
}
/// <summary>
/// 获取房间信息
/// </summary>
public static void GetRoomListFish(int leave,int district)
{
WebSocketManager.Instance.Send(SocketType.room, "{\"type\":1,\"target\":\"GetRoomList\",\"invocationId\":\"1\",\"arguments\":[\"" + GameManager.Instance.user.id + "\"," + (int)GameManager.Instance.gameData.currGameType + "," + leave + ","+ district + "]}");
}
/// <summary>
/// 打中鱼
/// </summary>
/// <param name="roomId"></param>
/// <param name="userId"></param>
/// <param name="fishNumber">配置id</param>
/// <param name="fishId">唯一id</param>
public static void KillFish(
string roomId,
string userId,
string fishNumber,
string fishId,
int paoBei,
string bulletId,
string signKey
)
{
long timespan = BeijingTimeManager.Instance.CurrentTimestampMs; // 毫秒
long timestamp = timespan / 1000; // 秒级
// count 固定为 1
string sign = MakeKillFishSign(roomId, userId, fishNumber, fishId, paoBei, timespan, bulletId, timestamp, signKey);
var sendObj = new WebSocketSendList(
"KillFish",
roomId,
userId,
fishNumber,
fishId,
paoBei,
timespan,
bulletId,
timestamp,
sign
);
WebSocketManager.Instance.Send(SocketType.game, JsonConvert.SerializeObject(sendObj));
}
/// <summary>
/// 真人玩家发射子弹(对接后端最新签名)
/// 服务端方法:Task<List<string>> FireCannon(roomId, userId, gold, count, timestamp, sign, extra)
/// 返回值 List<string> 为服务端生成的 bulletIds,通过 RoomFireNotice 广播给房间所有人
/// </summary>
/// <param name="roomId">房间ID</param>
/// <param name="userId">玩家ID</param>
/// <param name="gold">单价</param>
/// <param name="count">数量</param>
/// <param name="timestamp">秒级时间戳</param>
/// <param name="sign">签名(MD5 前8位)</param>
/// <param name="extra">附加数据(SyncGameData)</param>
public static void FireCannon(
string roomId,
string userId,
long gold,
int count,
long timestamp,
string sign,
object extra = null
)
{
var sendObj = new WebSocketSendList(
"FireCannon",
roomId,
userId,
gold,
count,
timestamp,
sign,
extra
);
WebSocketManager.Instance.Send(SocketType.game, JsonConvert.SerializeObject(sendObj));
}
/// <summary>
/// 发射子弹
/// </summary>
/// <param name="roomId"></param>
/// <param name="userId"></param>
/// <param name="gold">单价</param>
/// <param name="count">数量</param>
public static void ShootBullet(string roomId, string userId, int gold, int count)
{
var sendObj = new WebSocketSendList("ShootBullet", roomId, userId, gold, count);
WebSocketManager.Instance.Send(SocketType.game, JsonConvert.SerializeObject(sendObj));
}
/// <summary>
/// 链接登录界面ws
/// </summary>
/// <param name="userId"></param>
public static void Bind(string userId)
{
var sendObj = new WebSocketSendList("Bind", userId);
WebSocketManager.Instance.Send(SocketType.login, JsonConvert.SerializeObject(sendObj));
}
/// <summary>
/// 断线重连(必须先调用,重新加入房间前调用)
/// 对应服务端 FishGameHub.Reconnect(string userId)
/// </summary>
public static void Reconnect(string userId)
{
var sendObj = new WebSocketSendList("Reconnect", userId);
WebSocketManager.Instance.Send(SocketType.game, JsonConvert.SerializeObject(sendObj));
}
/// <summary>
/// 获取玩家信息(结果通过 SendPlayerInfoResult 事件返回)
/// 对应服务端 FishGameHub.GetPlayerInfo(string roomId, string userId)
/// </summary>
public static void GetPlayerInfo(string roomId, string userId)
{
var sendObj = new WebSocketSendList("GetPlayerInfo", roomId, userId);
WebSocketManager.Instance.Send(SocketType.game, JsonConvert.SerializeObject(sendObj));
}
/// <summary>
/// 加入房间
/// </summary>
/// <param name="roomId"></param>
/// <param name="userId"></param>
/// <param name="level">房间等级</param>
public static void JoinRoom(string roomId, string userId, int sitID)
{
var sendObj = new WebSocketSendList("JoinRoom", roomId, userId, sitID);
WebSocketManager.Instance.Send(SocketType.game, JsonConvert.SerializeObject(sendObj));
}
/// <summary>
/// 获取房间信息
/// </summary>
/// <param name="roomId">房间id</param>
public static void GetRoomInfo(string roomId)
{
var sendObj = new WebSocketSendList("GetRoomInfo", roomId);
WebSocketManager.Instance.Send(SocketType.room, JsonConvert.SerializeObject(sendObj));
}
/// <summary>
/// 使用道具
/// </summary>
/// <param name="roomId"></param>
/// <param name="userId"></param>
/// <param name="propNumber">道具id</param>
/// <param name="diamond">道具消耗</param>
public static void UseProp(string roomId, string userId, string propNumber, int diamond)
{
var sendObj = new WebSocketSendList("UseProp", roomId, userId, propNumber, diamond);
WebSocketManager.Instance.Send(SocketType.game, JsonConvert.SerializeObject(sendObj));
}
/// <summary>
/// 离开房间
/// </summary>
/// <param name="roomId"></param>
/// <param name="userId"></param>
public static void LeaveRoom(string roomId, string userId)
{
WebSocketManager.Instance.isGame=false;
var sendObj = new WebSocketSendList("LeaveRoom", roomId, userId);
WebSocketManager.Instance.Send(SocketType.game, JsonConvert.SerializeObject(sendObj));
}
/// <summary>
/// 更改炮倍
/// </summary>
/// <param name="roomId"></param>
/// <param name="userId"></param>
/// <param name="multiple"></param>
public static void ChangeGunMultiple(string roomId, string userId,int multiple)
{
var sendObj = new WebSocketSendList("ChangeGunMultiple", roomId, userId, multiple);
WebSocketManager.Instance.Send(SocketType.game, JsonConvert.SerializeObject(sendObj));
}
/// <summary>
/// 同步等级常量(秒)
/// </summary>
public const float SYNC_LV1 = 0.2f;
public const float SYNC_LV2 = 0.5f;
public const float SYNC_LV3 = 1f;
// 队列
private static float _syncLv1Timer;
private static float _syncLv2Timer;
private static float _syncLv3Timer;
private static Dictionary<int, SyncGameData> _syncLv1Cover = new Dictionary<int, SyncGameData>();
private static List<SyncGameData> _syncLv1Append = new List<SyncGameData>();
private static List<SyncGameData> _syncLv2Append = new List<SyncGameData>();
private static List<SyncGameData> _syncLv3Append = new List<SyncGameData>();
/// <summary>数据同步(自动按类型分级入队)</summary>
public static void SyncGameData(object obj)
{
var sgd = obj as SyncGameData;
if (sgd == null)
{
SendImmediate(JsonConvert.SerializeObject(obj));
return;
}
switch (sgd.frameType)
{
case FrameDataType.fireBullet:
case FrameDataType.rotateTurrect:
// ⭐ 开火/旋转实时发送,和开炮一样立即广播,保证炮台旋转流畅
SendImmediate(BuildJson(sgd));
return;
case FrameDataType.changeAutoTarget:
_syncLv1Cover[sgd.sitPos] = sgd;
return;
case FrameDataType.randomDieFish:
_syncLv1Append.Add(sgd);
return;
case FrameDataType.createFish:
case FrameDataType.changeTurretState:
case FrameDataType.changeTurret:
case FrameDataType.freezeFish:
_syncLv2Append.Add(sgd);
return;
case FrameDataType.requestSyncFish:
// ⭐ 新玩家加载完成的"请求同步鱼":立即发送,房主尽快响应广播
SendImmediate(BuildJson(sgd));
return;
default:
_syncLv3Append.Add(sgd);
return;
}
}
/// <summary>每帧调用,由 GameMainPanel.Update 驱动</summary>
public static void FlushSyncQueues(float dt)
{
_syncLv1Timer += dt;
if (_syncLv1Timer >= SYNC_LV1) { _syncLv1Timer = 0f; FlushLv1(); }
_syncLv2Timer += dt;
if (_syncLv2Timer >= SYNC_LV2) { _syncLv2Timer = 0f; FlushLv2(); }
_syncLv3Timer += dt;
if (_syncLv3Timer >= SYNC_LV3) { _syncLv3Timer = 0f; FlushLv3(); }
}
private static void FlushLv1()
{
foreach (var kv in _syncLv1Cover) SendImmediate(BuildJson(kv.Value));
foreach (var sgd in _syncLv1Append) SendImmediate(BuildJson(sgd));
_syncLv1Cover.Clear();
_syncLv1Append.Clear();
}
private static void FlushLv2()
{
foreach (var sgd in _syncLv2Append) SendImmediate(BuildJson(sgd));
_syncLv2Append.Clear();
}
private static void FlushLv3()
{
foreach (var sgd in _syncLv3Append) SendImmediate(BuildJson(sgd));
_syncLv3Append.Clear();
}
private static void SendImmediate(string json)
{
WebSocketManager.Instance.Send(SocketType.game, json);
}
private static string BuildJson(object obj)
{
var sendObj = new WebSocketSendList
{
type = 1,
invocationId = "1",
target = "SyncGameData",
arguments = new System.Collections.Generic.List<object>
{
GameManager.Instance.gameData.currRoomData.roomId,
obj
}
};
return JsonConvert.SerializeObject(sendObj);
}
}