| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 | #if COMBAT_SERVERusing System;using System.Buffers;using System.Collections.Generic;using System.IO.Compression;using System.Net;using System.Net.Sockets;using System.Net.Sockets.Kcp;using System.Threading;using Com.Fort23.Protocol.Protobuf;using Fort23.UTool;using Utility;namespace Core.KCPTool{    public class KCPServer : IServer    {        private Socket socket;        private Thread _udpClientThread;        private byte[] buffer = new byte[2048];        private ArraySegment<byte> ArraySegment;        public Map<long, IServerConnection> KcpServerConnections = new Map<long, IServerConnection>();        private List<CombatSynchronizeRequest> CombatSynchronizeRequests = new List<CombatSynchronizeRequest>();        // private List<IServerConnection> awaitConnections = new List<IServerConnection>();        private IServerManager iServerManager;        private Queue<SendDataBuffer> _sendDataBuffers = new Queue<SendDataBuffer>();        private long lasetSendTime = 0;        public KCPServer(int port, IServerManager iServerManager)        {            this.iServerManager = iServerManager;            LogTool.Log("创建UDP链接端口"+port+"__");            socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);            socket.Bind(new IPEndPoint(IPAddress.Any, port));            ArraySegment = new ArraySegment<byte>(buffer);            _udpClientThread = new Thread(BeginRecv);            _udpClientThread.Start();        }        public void SocketSendTo(byte[] buffer, EndPoint endPoint)        {            // if (_sendDataBuffers.Count > 0)            {                // LogTool.Log("发送消息:"+endPoint.GetHashCode());                SendDataBuffer sendDataBuffer = new SendDataBuffer();                sendDataBuffer.buffer = buffer;                sendDataBuffer.endPoint = endPoint;                _sendDataBuffers.Enqueue(sendDataBuffer);            }            // else            // {            // SocketSendToForBuffer(buffer, endPoint);            // }        }        private void SocketSendToForBuffer(byte[] buffer, EndPoint endPoint)        {            socket.SendTo(buffer, endPoint);        }        private byte[] AssembleData(SendDataType sendDataType, byte[] buffer)        {            byte[] sendBuff = new byte[buffer.Length + 1];            sendBuff[0] = (byte)sendDataType;            Array.Copy(buffer, 0, sendBuff, 1, buffer.Length);            return sendBuff;        }        public bool SendToPlayer(SendDataType sendDataType, CombatSynchronizeType combatSynchronizeType, byte[] buffer,            long playerId)        {            if (KcpServerConnections.Count <= 0)            {                return true;            }            byte[] sendBuff = AssembleData(sendDataType, buffer);                        bool isOk = false;            lock (KcpServerConnections)            {                for (KcpServerConnections.Begin(); KcpServerConnections.Next();)                {                    if (KcpServerConnections.Value.isConnected)                    {                        isOk = true;                    }                    if (playerId != -1 && KcpServerConnections.Value.playerId != playerId)                    {                        continue;                    }                    KcpServerConnections.Value.SendData(sendBuff, sendBuff.Length);                }            }            return isOk;        }        public void AddCombatSynchronizeRequest(CombatSynchronizeRequest combatSynchronizeRequest)        {            lock (CombatSynchronizeRequests)            {                CombatSynchronizeRequests.Add(combatSynchronizeRequest);            }        }        public CombatSynchronizeRequest[] GetCombatSynchronizeRequest(bool isClear)        {            if (CombatSynchronizeRequests.Count <= 0)            {                return null;            }            lock (CombatSynchronizeRequests)            {                CombatSynchronizeRequest[] allData = CombatSynchronizeRequests.ToArray();                CombatSynchronizeRequests.Clear();                return allData;            }        }        public bool UpdateKCP()        {            bool isConnected = false;            if (_sendDataBuffers.TryDequeue(out SendDataBuffer sendDataBuffer))            {                SocketSendToForBuffer(sendDataBuffer.buffer, sendDataBuffer.endPoint);            }            long currTime = DateTime.Now.Ticks;            if (currTime - lasetSendTime > 50000000)            {                lasetSendTime = currTime;                SendToPlayer(SendDataType.Heartbeat, CombatSynchronizeType.PrepareStart, new byte[1], -1);            }            lock (KcpServerConnections)            {                for (KcpServerConnections.Begin(); KcpServerConnections.Next();)                {                    if (KcpServerConnections.Value.isConnected)                    {                        isConnected = true;                        KcpServerConnections.Value.Update();                    }                }            }            // lock (awaitConnections)            // {            //     for (int i = 0; i < awaitConnections.Count; i++)            //     {            //         awaitConnections[i].Update();            //     }            // }            return isConnected;        }        public void RecvKCP()        {            lock (KcpServerConnections)            {                for (KcpServerConnections.Begin(); KcpServerConnections.Next();)                {                    if (KcpServerConnections.Value.isConnected)                    {                        KcpServerConnections.Value.ReceiveAsync();                    }                }            }            // lock (awaitConnections)            // {            //     for (int i = 0; i < awaitConnections.Count; i++)            //     {            //         awaitConnections[i].ReceiveAsync();            //     }            // }        }        private async void BeginRecv()        {            while (_udpClientThread != null)            {                EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);                try                {                    SocketReceiveFromResult receiveFromResult =                        await socket.ReceiveFromAsync(ArraySegment, SocketFlags.None, newClientEP);                    if (receiveFromResult.ReceivedBytes <= 0)                    {                        Thread.Sleep(10);                        continue;                    }                    newClientEP = receiveFromResult.RemoteEndPoint;                    byte[] data = new byte[receiveFromResult.ReceivedBytes];                    Array.Copy(buffer, 0, data, 0, data.Length);                    if (receiveFromResult.ReceivedBytes == 8) //链接到了                    {                        long playerId = SocketTool.ByteToLong(data);                        CreateNewConnections(newClientEP, playerId);                        continue;                    }                    else                    {                        IServerConnection kcpServerConnection = GetConnection(newClientEP.GetHashCode());                        if (kcpServerConnection == null)                        {                            LogTool.Error("没有找到对应的客户端链接");                        }                        else                        {                            int ok = kcpServerConnection.Input(data);                        }                    }                }                catch (Exception e)                {                    // SocketException socketException = e as SocketException;                    // if (socketException.ErrorCode == 10054)                    // {                    //     IServerConnection kcpServerConnection = GetConnection(newClientEP.GetHashCode());                    //     if (kcpServerConnection != null) //链接已经断开                    //     {                    //         kcpServerConnection.isConnected = false;                    //     }                    // }                    LogTool.Error(e);                    Thread.Sleep(10);                    // socket.Disconnect();                }            }        }        public void RemovePlayer(long playerId)        {            lock (KcpServerConnections)            {                KcpServerConnections.Remove(playerId);            }        }        public IServerConnection GetConnection(long playerId)        {            lock (KcpServerConnections)            {                for (KcpServerConnections.Begin(); KcpServerConnections.Next();)                {                    if (playerId != -1 && KcpServerConnections.Value.playerId != playerId)                    {                        continue;                    }                    return KcpServerConnections.Value;                }            }            return null;        }        public IServerConnection GetConnection(int connectionId)        {            lock (KcpServerConnections)            {                for (KcpServerConnections.Begin(); KcpServerConnections.Next();)                {                    if (connectionId != -1 && KcpServerConnections.Value.connectionID != connectionId)                    {                        continue;                    }                    return KcpServerConnections.Value;                }            }            return null;        }        public void RemoveServerConnection(long playerId)        {            lock (KcpServerConnections)            {                if (KcpServerConnections.TryGetValue(playerId, out IServerConnection serverConnection))                {                    LogTool.Log("移除成功UDP" + playerId);                    serverConnection.Dispose();                    KcpServerConnections.Remove(playerId);                }            }        }        public void ConnectionUpdate()        {            if (socket != null)            {                try                {                    UpdateKCP();                    RecvKCP();                }                catch (Exception e)                {                    LogTool.Exception(e);                }            }        }          public async void SendGameFrame(int gameFrame, IServerConnection kcpServerConnection)        {            // if (gameFrame > 0)            {                LogTool.Log("重传数据开始" + gameFrame);                int maxCount = iServerManager.GetSendBufferSize();                for (int i = gameFrame; i < maxCount; i++)                {                    byte[] _sendBufferdata = iServerManager.GetSendBuffer(i);                    if (_sendBufferdata != null)                    {                        _sendBufferdata = AssembleData(SendDataType.Data, _sendBufferdata);                        kcpServerConnection.SendData(_sendBufferdata, _sendBufferdata.Length);                        await System.Threading.Tasks.Task.Delay(1);                    }                }            }        }        public void AddServerConnection(long playerId, int gameFrame, IServerConnection kcpServerConnection)        {            lock (KcpServerConnections)            {                RemoveServerConnection(playerId);                iServerManager.AddServerConnection(this, kcpServerConnection);                KcpServerConnections.Add(playerId, kcpServerConnection);                LogTool.Log("握手成功UDP" + playerId);                iServerManager.AddServerConnection(this, kcpServerConnection);                byte[] data = SocketTool.LongToByte(playerId);                SendToPlayer(SendDataType.ShakeHands, CombatSynchronizeType.PrepareStart, data, playerId);            }            // lock (awaitConnections)            // {            //     awaitConnections.Remove(kcpServerConnection);            // }        }        public IServerConnection CreateNewConnections(EndPoint newClientEP, long playerId)        {            // int code = newClientEP.GetHashCode();            KCPServerConnection kcpServerConnection = new KCPServerConnection(this, (IPEndPoint)newClientEP);            kcpServerConnection.playerId = playerId;            kcpServerConnection.connectionID = newClientEP.GetHashCode();            LogTool.Log("创建新的链接UDP" + newClientEP);            AddServerConnection(playerId, 0, kcpServerConnection);            return kcpServerConnection;        }        public void Dispose()        {            _udpClientThread = null;            socket?.Dispose();            socket = null;        }    }}#endif
 |