2023-08-30 08:17:12 +00:00
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using DotNetty.Buffers;
|
|
|
|
|
using dotNetty_kcp;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using Guru;
|
|
|
|
|
using Dof;
|
|
|
|
|
|
|
|
|
|
public class KcpDofClient : KcpListener
|
|
|
|
|
{
|
|
|
|
|
public Action OnConnected;
|
|
|
|
|
public Action<ServerMessage> OnServerMessage;
|
|
|
|
|
|
|
|
|
|
private Ukcp _ukcp;
|
|
|
|
|
private KcpClient _kcpClient;
|
2023-08-30 10:08:28 +00:00
|
|
|
private MemoryStream _localSendMs = new (1024 * 1024 * 1);
|
2023-08-30 08:17:12 +00:00
|
|
|
|
|
|
|
|
public long Cid { get; private set; }
|
|
|
|
|
|
|
|
|
|
public KcpDofClient()
|
|
|
|
|
{
|
|
|
|
|
// 指定DotNetty日志的显示级别
|
|
|
|
|
DotNetty.Unity.UnityLoggerFactory.Default.Level = DotNetty.Unity.Level.ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async void Connect(string ip_str, int port)
|
|
|
|
|
{
|
|
|
|
|
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(ip_str), port);
|
|
|
|
|
var task = _kcpClient.BindLocal();
|
|
|
|
|
await task;
|
|
|
|
|
var channel = task.Result;
|
|
|
|
|
_ukcp = _kcpClient.connect(channel, remoteAddress, channelConfig, this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Send(ClientMessage msg)
|
|
|
|
|
{
|
|
|
|
|
_localSendMs.SetLength(0);
|
|
|
|
|
_localSendMs.Position = 0;
|
|
|
|
|
|
|
|
|
|
ProtobufHelper.ToStream(msg, _localSendMs);
|
|
|
|
|
|
|
|
|
|
var dataBuf = Unpooled.DirectBuffer(1024 * 1024 * 1);
|
|
|
|
|
dataBuf.WriteBytes(_localSendMs.GetBuffer(), 0, (int)_localSendMs.Length);
|
|
|
|
|
_ukcp.write(dataBuf);
|
|
|
|
|
dataBuf.Release();
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-30 08:49:30 +00:00
|
|
|
public void Close()
|
|
|
|
|
{
|
|
|
|
|
_kcpClient.stop();
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-30 08:17:12 +00:00
|
|
|
public void onConnected(Ukcp ukcp)
|
|
|
|
|
{
|
|
|
|
|
Debug.Log($"[KcpDofClient]onConnected");
|
|
|
|
|
|
|
|
|
|
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("[KcpDofClient]handleReceive");
|
|
|
|
|
|
2023-08-30 10:08:28 +00:00
|
|
|
var ms = new MemoryStream(1024 * 1024 * 1);
|
2023-08-30 08:17:12 +00:00
|
|
|
var data_len = byteBuf.ReadableBytes;
|
2023-08-30 10:08:28 +00:00
|
|
|
byteBuf.ReadBytes(ms, data_len);
|
|
|
|
|
var msg = ProtobufHelper.FromBytes(typeof(ServerMessage), ms.GetBuffer(), 0, data_len);
|
2023-08-30 08:17:12 +00:00
|
|
|
var server_msg = msg as ServerMessage;
|
|
|
|
|
|
|
|
|
|
if (server_msg != null)
|
|
|
|
|
{
|
|
|
|
|
ServerMessageHandler(server_msg);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError("[KcpDofClient]handleReceive: Fail to Deserialize ServerMessage");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void handleException(Exception ex, Ukcp ukcp)
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError($"[KcpDofClient]{ex}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void handleClose(Ukcp ukcp)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ServerMessageHandler(ServerMessage msg)
|
|
|
|
|
{
|
|
|
|
|
if (msg.PlayerEntered != null)
|
|
|
|
|
{
|
|
|
|
|
Cid = msg.PlayerEntered.Cid;
|
|
|
|
|
Debug.Log($"Player Enter cid: {Cid}");
|
|
|
|
|
}
|
|
|
|
|
else if (msg.GameStart != null)
|
|
|
|
|
{
|
|
|
|
|
Debug.Log($"Game Start");
|
|
|
|
|
}
|
|
|
|
|
else if (msg.LevelStart != null)
|
|
|
|
|
{
|
|
|
|
|
Debug.Log($"Level Start");
|
|
|
|
|
}
|
|
|
|
|
else if (msg.PointFound != null)
|
|
|
|
|
{
|
|
|
|
|
Debug.Log($"Point Found");
|
|
|
|
|
}
|
|
|
|
|
else if (msg.GameFinish != null)
|
|
|
|
|
{
|
|
|
|
|
Debug.Log($"Game Finish");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError($"Unhandled ServerMessage");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (OnServerMessage != null)
|
|
|
|
|
{
|
|
|
|
|
Loom.QueueOnMainThread(() =>
|
|
|
|
|
{
|
|
|
|
|
OnServerMessage.Invoke(msg);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|