544 lines
18 KiB
C#
Raw Normal View History

2025-06-03 14:21:19 +08:00
2025-04-18 19:18:15 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TEngine;
using UnityEngine;
using UnityWebSocket;
using System.Linq;
using System.Text;
using Cysharp.Threading.Tasks;
using System.Net.Sockets;
using System.Xml.Linq;
namespace GameLogic
{
public class ProtCust : GameBase.Singleton<ProtCust>
{
private WebSocket m_WebSocket;
// 异步线程回归到主线程处理
private Dictionary<string, List<ProtCustMessageData>> m_ListProCustMessageDatas = new Dictionary<string, List<ProtCustMessageData>>();
Dictionary<string, int> ack = new Dictionary<string, int>();//json1.data.msgId
Dictionary<string, string> dct = new Dictionary<string, string>();
Dictionary<string, byte> handled = new Dictionary<string, byte>(1000);//已处理的消息
public async void OpenWebSocket()
{
if (m_WebSocket != null)
{
// 断开连接..
m_WebSocket.CloseAsync();
m_WebSocket = null;
await UniTask.Delay(1000);
}
// 初始化消息队列
m_ListProCustMessageDatas.Add(EventConts.GiftInfo, new List<ProtCustMessageData>());
m_ListProCustMessageDatas.Add(EventConts.LickInfo, new List<ProtCustMessageData>());
m_ListProCustMessageDatas.Add(EventConts.MessageInfo, new List<ProtCustMessageData>());
switch (EventConts.PlatformType)
{
case PlatformType.None:
NoneSocketInit();
break;
case PlatformType.DyTest:
DyTestSocketInit();
break;
case PlatformType.Dy:
DySocketInit();
break;
default:
Log.Error("没有支持的平台:{0}", EventConts.PlatformType);
break;
}
}
/// <summary>
/// 切换网络连接平台
/// </summary>
/// <param name="platformType"></param>
public async void SwitchPlatform(PlatformType platformType)
{
if (m_WebSocket != null)
{
// 断开连接..
m_WebSocket.CloseAsync();
m_WebSocket = null;
await UniTask.Delay(1000);
}
switch (EventConts.PlatformType)
{
case PlatformType.None:
NoneSocketInit();
break;
case PlatformType.DyTest:
DyTestSocketInit();
break;
case PlatformType.Dy:
DySocketInit();
break;
default:
Log.Error("没有支持的平台:{0}", EventConts.PlatformType);
break;
}
}
2025-06-11 14:22:24 +08:00
float timerDt = 2;
2025-04-18 19:18:15 +08:00
public void OnUpdate()
{
if (m_WebSocket != null && m_WebSocket.ReadyState == WebSocketState.Open)
{
DOSendAck();
}
foreach (var item in m_ListProCustMessageDatas)
{
if (item.Value.Count <= 0)
{
continue;
}
foreach (var data in item.Value)
{
GameEvent.Send(item.Key, data);
}
item.Value.Clear();
}
2025-06-11 14:22:24 +08:00
timerDt -= Time.deltaTime;
if (timerDt <= 0)
{
// 执行一次Ack
timerDt = 2;
OnHbTimer();
}
2025-04-18 19:18:15 +08:00
}
2025-06-11 14:22:24 +08:00
/// <summary>
/// 心跳包
/// </summary>
private void OnHbTimer()
{
// 心跳包
Dictionary<string, string> dis = new Dictionary<string, string>();
dis.Add("type", "hb");
m_WebSocket.SendAsync(dis.ToJson());
}
2025-04-18 19:18:15 +08:00
/// <summary>
/// 测试服流程初始化
/// </summary>
private void NoneSocketInit()
{
int id = UnityEngine.Random.Range(0, 1000);
string edit = "Jscc";
var room_id = "test" + id + edit;
m_WebSocket = new WebSocket(string.Format(EventConts.ServerUrlTest,
WebUtility.UrlEncode(room_id), WebUtility.UrlEncode("test" + id + edit),
WebUtility.UrlEncode(EventConts.TestPlayerUrl),
WebUtility.UrlEncode("测试主播" + id + edit),
WebUtility.UrlEncode(EventConts.app_id_test)));
// 主播信息
EventConts.RoomData = new RoomInfoData
{
room_id = room_id,
anchor_open_id = "test" + id + edit,
avatar_url = EventConts.TestPlayerUrl,
nick_name = "测试主播" + id + edit,
};
m_WebSocket.OnMessage += SocketOnMessage;
m_WebSocket.OnError += SocketOnError;
m_WebSocket.OnOpen += SocketOnOpen;
m_WebSocket.ConnectAsync();
Log.Info("NoneSocket Init ....");
}
private void DySocketInit()
{
// 获取token
string[] arguments = Environment.GetCommandLineArgs();
if (arguments == null || arguments.Length == 0)
{
Debug.LogError("启动参数:无");
}
if (arguments[1].Length < 8)
{
Log.Error("Token参数异常");
}
string token = string.Empty;
for (int i = 0; i < arguments.Length; i++)
{
if (arguments[i].Contains("-token"))
{
token = arguments[i].Substring(7);
}
}
// 没有token 提示,关闭游戏。。
if (string.IsNullOrEmpty(token))
{
// Log.Error("token获取失败");
UITip.ShowMessageBox("获取token失败,确保打开直播伴侣", MessageShowType.TwoButton, () =>
{
DySocketInit();
}, () =>
{
Application.Quit();
});
return;
}
// 设置token
EventConts.Token = token;
GetRoomIdData data = new GetRoomIdData
{
token = EventConts.Token,
};
var roomJsonData = HttpSendHelper.HttpPostRequest(EventConts.GetRoomInfo, data.ToJson());
try
{
GetRoomDataRoot getRoomDataRoot = JsonHelper.Deserialize<GetRoomDataRoot>(roomJsonData);
if (getRoomDataRoot.code == 500)
{
UITip.ShowMessageBox(getRoomDataRoot.msg, MessageShowType.TwoButton, () =>
{
DySocketInit();
}, () =>
{
Application.Quit();
});
}
else
{
m_WebSocket = new WebSocket(string.Format(EventConts.ServerUrl,
WebUtility.UrlEncode(getRoomDataRoot.data.room_id),
WebUtility.UrlEncode(getRoomDataRoot.data.anchor_open_id),
WebUtility.UrlEncode(getRoomDataRoot.data.avatar_url),
WebUtility.UrlEncode(getRoomDataRoot.data.nick_name),
WebUtility.UrlEncode(EventConts.app_id)));
// 设置房间数据
EventConts.RoomData = getRoomDataRoot.data;
m_WebSocket.OnMessage += SocketOnMessage;
m_WebSocket.OnError += SocketOnError;
m_WebSocket.OnOpen += SocketOnOpen;
m_WebSocket.ConnectAsync();
Log.Info("DySocket Init ....");
}
}
catch (Exception e)
{
Debug.LogError($"GetRoomInfo 解析错误,返回值:{roomJsonData}");
UITip.ShowMessageBox("解析房间信息失败", MessageShowType.TwoButton, () =>
{
DySocketInit();
}, () =>
{
Application.Quit();
});
}
}
private void DyTestSocketInit()
{
int id = UnityEngine.Random.Range(0, 1000);
string edit = "Jscc";
var room_id = "1222222222222222222";
m_WebSocket = new WebSocket(string.Format(EventConts.ServerUrl,
WebUtility.UrlEncode(room_id), WebUtility.UrlEncode("test" + id + edit),
WebUtility.UrlEncode(EventConts.TestPlayerUrl),
WebUtility.UrlEncode("测试主播" + id + edit),
WebUtility.UrlEncode(EventConts.app_id)));
// 主播信息
EventConts.RoomData = new RoomInfoData
{
room_id = room_id,
anchor_open_id = "test" + id + edit,
avatar_url = EventConts.TestPlayerUrl,
nick_name = "测试主播" + id + edit,
};
m_WebSocket.OnMessage += SocketOnMessage;
m_WebSocket.OnError += SocketOnError;
m_WebSocket.OnOpen += SocketOnOpen;
m_WebSocket.ConnectAsync();
Log.Info("DyTestSocket Init ....");
}
private long timerId;
private void SocketOnOpen(object o, OpenEventArgs e)
{
Log.Debug("连接服务器,服务器地址:{0}", (o as WebSocket).Address);
if (timerId != 0)
{
GameModule.Timer.RemoveTimer((int)timerId);
}
// 增加心跳包
timerId = GameModule.Timer.AddTimer((e) =>
{
if (m_WebSocket != null)
{
Dictionary<string, string> dis = new Dictionary<string, string>();
dis.Add("type", "hb");
dis.Add("data", "ping");
m_WebSocket.SendAsync(dis.ToJson());
}
}, 5, true);
}
private void SocketOnMessage(object o, MessageEventArgs e)
{
try
{
// 异常数据处理
if (e.Data == null || e.Data == string.Empty)
{
return;
}
// 先根据解析出来的类型处理
var mj = JObject.Parse(e.Data);
string Info = mj["type"].ToString();
// 处理消息协议
if (Info == "roundEnd")
{
}
else if (Info != "hb")
{
ParentProtCustMessageData json1 = JsonConvert.DeserializeObject<ParentProtCustMessageData>(e.Data);
ProtCustMessageData protCustMessageData = new ProtCustMessageData();
if (json1.data == null)
{
return;
}
if (handled.ContainsKey(json1.data.msgId) == false)
{
handled[json1.data.msgId] = 1;
switch (json1.type)
{
case "MemberMessage":
break;
case "gift":
protCustMessageData.imgURL = json1.data.avatar;
protCustMessageData.nickName = json1.data.name;
protCustMessageData.content = json1.data.giftId;
protCustMessageData.Count = json1.data.repeatCount.ToString();
protCustMessageData.openId = string.IsNullOrEmpty(json1.data.uid) ? json1.data.openId : json1.data.uid;
protCustMessageData.giftValue = json1.data.giftValue;
protCustMessageData.rankRo = json1.data.rankRo;
protCustMessageData.customCamp = json1.data.customCamp;
protCustMessageData.roomId = json1.data.roomId;
// GameEvent.Send(EventConts.GiftInfo, protCustMessageData);
m_ListProCustMessageDatas[EventConts.GiftInfo].Add(protCustMessageData);
break;
case "like":
protCustMessageData.imgURL = json1.data.avatar;
protCustMessageData.nickName = json1.data.name;
protCustMessageData.content = "点赞";
protCustMessageData.Count = json1.data.likeCount;
protCustMessageData.openId = string.IsNullOrEmpty(json1.data.uid) ? json1.data.openId : json1.data.uid;
protCustMessageData.rankRo = json1.data.rankRo;
protCustMessageData.customCamp = json1.data.customCamp;
protCustMessageData.roomId = json1.data.roomId;
// GameEvent.Send(EventConts.LickInfo, protCustMessageData);
m_ListProCustMessageDatas[EventConts.LickInfo].Add(protCustMessageData);
break;
case "chat":
protCustMessageData.imgURL = json1.data.avatar;
protCustMessageData.nickName = json1.data.name;
protCustMessageData.content = json1.data.comment;
protCustMessageData.openId = string.IsNullOrEmpty(json1.data.uid) ? json1.data.openId : json1.data.uid;
protCustMessageData.rankRo = json1.data.rankRo;
protCustMessageData.customCamp = json1.data.customCamp;
protCustMessageData.roomId = json1.data.roomId;
// GameEvent.Send(EventConts.MessageInfo, protCustMessageData);
m_ListProCustMessageDatas[EventConts.MessageInfo].Add(protCustMessageData);
break;
}
}
// 礼物消息重发
if (json1.type == "chat" || json1.type == "gift")
{
#region
Dictionary<string, string> dis = new Dictionary<string, string>();
dis.Add("type", "dmAck");
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("msgId", json1.data.msgId);
data.Add("ackType", "show");
dis.Add("data", data.ToJson());
m_WebSocket.SendAsync(dis.ToJson());
#endregion
}
}
}
catch (Exception es)
{
Log.Error(es.Message);
throw;
}
}
private void SocketOnError(object o, ErrorEventArgs e)
{
Log.Error("Socket Error:" + e.Message.ToString());
UITip.ShowMessageBox("网络波动请尝试重连", MessageShowType.TwoButton, () =>
{
// socketIo.CloseAsync();
// socketIo = null;
// InitSelfServer();
}, () =>
{
// Application.Quit();
});
}
#region
public void SendRoundVo_Start()
{
RoundVo roundVo = new RoundVo();
roundVo.type = "PVP";
Dictionary<string, string> dct = new Dictionary<string, string>();
//roundStart roundEnd
dct["type"] = "roundStart";
dct["data"] = roundVo.ToJson();
m_WebSocket.SendAsync(dct.ToJson());
}
public void SendRoundVo_End()
{
RoundVo roundVo = new RoundVo();
roundVo.type = "PVP";
roundVo.winSide = "blue";
Dictionary<string, string> dct = new Dictionary<string, string>();
dct["type"] = "roundEnd";
dct["data"] = roundVo.ToJson();
m_WebSocket.SendAsync(dct.ToJson());
}
#endregion
#region GM
public void SendMessage_GM(string type, ProtCustMessageData protCustMessageData)
{
GMMessage gmMessage = new GMMessage
{
type = type,
nickName = protCustMessageData.nickName,
openId = protCustMessageData.openId,
imageUrl = protCustMessageData.imgURL,
content = protCustMessageData.content,
count = protCustMessageData.Count,
giftValue = protCustMessageData.giftValue,
customCamp = (int)protCustMessageData.customCamp,
};
Dictionary<string, string> dic = new Dictionary<string, string>();
if (dic.Count == 0)
{
dic.Add("type", "gm");
}
dic["data"] = gmMessage.ToJson();
var json = dic.ToJson();
SendGMMessage(json);
}
private void SendGMMessage(string gmMessage)
{
if (m_WebSocket != null)
{
m_WebSocket.SendAsync(gmMessage);
}
}
#endregion
public void DOSendAck()
{
if (ack.Count > 0)
{
foreach (var item in ack)
{
var k = item.Key;
SendAckMessage(k);
}
ack.Clear();
}
}
AckData ack_data = new AckData();
public void SendAckMessage(string msg_id)
{
if (dct.Count == 0)
{
dct.Add("type", "dmAck");
}
ack_data.msgId = msg_id;
ack_data.ackType = "receive";
dct["data"] = ack_data.ToJson();
var content = dct.ToJson();
//Debug.LogError("发送ack:"+ content);
m_WebSocket.SendAsync(content);
}
}
}