upm_guru_dof_lib/Runtime/GameKcpClient.cs

182 lines
5.9 KiB
C#
Raw Normal View History

2023-08-30 12:26:51 +00:00
using System;
using System.Net;
using System.IO;
using dotNetty_kcp;
using DotNetty.Buffers;
using UnityEngine;
using Guru;
using Dof;
namespace DofLibrary
{
public class GameKcpClient : KcpListener
{
public Action OnConnected;
2023-09-18 03:02:00 +00:00
public Action OnDisConnected;
2023-08-30 12:26:51 +00:00
private KcpClient _kcpClient;
public IMessageSender sender { get; private set; } = new MessageSender();
private IMessageReceiver _receiver;
private bool _running;
2023-09-04 10:48:51 +00:00
2023-08-30 12:26:51 +00:00
public GameKcpClient(DotNetty.Unity.Level level = DotNetty.Unity.Level.ALL)
{
// 指定DotNetty日志的显示级别
DotNetty.Unity.UnityLoggerFactory.Default.Level = level;
}
/// <summary>
/// 当前 Client 是否处于连接状态
/// </summary>
public bool Running => _running;
/// <summary>
/// 创建一个到 Dof GameServer 的连接
/// </summary>
/// <param name="serverAddress">Dof GameServer 的地址,形如 xxx.xxx.xxx.xxx</param>
/// <param name="port">房间ID</param>
/// <param name="receiver">事件回调接口</param>
public async void Connect(string serverAddress, int port, IMessageReceiver receiver)
{
_receiver = receiver;
_receiver.MessageSender = sender;
_running = true;
var channelConfig = new ChannelConfig();
channelConfig.initNodelay(true, 40, 2, true);
channelConfig.Sndwnd = 512;
channelConfig.Rcvwnd = 512;
channelConfig.Mtu = 512;
channelConfig.FecDataShardCount = 10;
channelConfig.FecParityShardCount = 3;
channelConfig.AckNoDelay = true;
channelConfig.Crc32Check = false;
channelConfig.UseConvChannel = true;
//channelConfig.Conv = UnityEngine.Random.Range(1, int.MaxValue);
channelConfig.TimeoutMillis = 10000;
_kcpClient = new KcpClient();
_kcpClient.init(channelConfig);
var remoteAddress = new IPEndPoint(IPAddress.Parse(serverAddress), port);
var task = _kcpClient.BindLocal();
await task;
var channel = task.Result;
_kcpClient.connect(channel, remoteAddress, channelConfig, this);
}
private void ProcessMessage(ServerMessage serverMessage)
{
2023-09-04 10:48:51 +00:00
Debug.Log("[ProcessMessage]");
2023-08-30 12:26:51 +00:00
if (serverMessage.PlayerEntered != null)
{
2023-09-04 10:48:51 +00:00
//Debug.Log("[ProcessMessage]PlayerEntered");
2023-08-30 12:26:51 +00:00
var cid = serverMessage.PlayerEntered.Cid;
sender.Cid = cid;
_receiver.OnPlayerEntered(cid);
}
2023-09-04 10:48:51 +00:00
else if (serverMessage.GameStart != null)
2023-08-30 12:26:51 +00:00
{
2023-09-04 10:48:51 +00:00
//Debug.Log("[ProcessMessage]GameStart");
2023-08-30 12:26:51 +00:00
_receiver.OnGameStart(serverMessage.GameStart);
}
else if (serverMessage.LevelStart != null)
{
2023-09-04 10:48:51 +00:00
//Debug.Log("[ProcessMessage]LevelStart");
2023-08-30 12:26:51 +00:00
_receiver.OnLevelStart(serverMessage.LevelStart);
}
else if (serverMessage.PointFound != null)
{
2023-09-04 10:48:51 +00:00
//Debug.Log("[ProcessMessage]PointFound");
2023-08-30 12:26:51 +00:00
_receiver.OnPointFound(serverMessage.PointFound);
}
else if (serverMessage.GameFinish != null)
{
2023-09-04 10:48:51 +00:00
//Debug.Log("[ProcessMessage]GameFinish");
2023-08-30 12:26:51 +00:00
_receiver.OnGameFinish(serverMessage.GameFinish);
}
}
/// <summary>
/// kcp 连接后的回调函数
/// </summary>
/// <param name="ukcp">kcp连接</param>
public void onConnected(Ukcp ukcp)
{
Debug.Log($"[GameKcpClient]onConnected: conv = {ukcp.getConv()}");
sender.Client = ukcp;
if (OnConnected != null)
{
Loom.QueueOnMainThread(() =>
{
OnConnected.Invoke();
});
}
}
/// <summary>
/// kcp 接收到消息的回调函数
/// </summary>
/// <param name="byteBuf">接收到的消息buffer</param>
/// <param name="ukcp">kcp连接</param>
public void handleReceive(IByteBuffer byteBuf, Ukcp ukcp)
{
Debug.Log("[GameKcpClient]handleReceive");
var ms = new MemoryStream(1024 * 1024 * 1);
var data_len = byteBuf.ReadableBytes;
byteBuf.ReadBytes(ms, data_len);
var msg = ProtobufHelper.FromBytes(typeof(ServerMessage), ms.GetBuffer(), 0, data_len);
if (msg is ServerMessage server_msg)
{
Loom.QueueOnMainThread(() =>
{
ProcessMessage(server_msg);
});
}
else
{
Debug.LogError("[GameKcpClient]handleReceive: Fail to Deserialize ServerMessage");
}
}
/// <summary>
/// kcp 连接或者接收消息出错的回调函数
/// </summary>
/// <param name="ex">异常</param>
/// <param name="ukcp">kcp连接</param>
public void handleException(Exception ex, Ukcp ukcp)
{
Debug.LogError($"[GameKcpClient]handleException: {ex}");
}
/// <summary>
/// kcp 连接关闭时的回调函数
/// </summary>
/// <param name="ukcp">kcp连接</param>
public void handleClose(Ukcp ukcp)
{
Debug.Log("[GameKcpClient]: Connection closed");
2023-09-18 03:02:00 +00:00
if (OnDisConnected != null)
{
Loom.QueueOnMainThread(() =>
{
OnDisConnected.Invoke();
});
}
2023-08-30 12:26:51 +00:00
}
/// <summary>
/// 关闭 Client应该在游戏结束时调用
/// </summary>
public void Close()
{
_kcpClient?.stop();
_running = false;
}
}
}