Advertisement
XConquer

ClientWrapper [Con AntiLag]

Jan 8th, 2021
1,792
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.18 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.Sockets;
  5. using System.Threading;
  6. using System.Collections.Concurrent;
  7. using System.Runtime.InteropServices;
  8. using System.Threading.Tasks;
  9. using COServer.Interfaces;
  10. using BigBOs_Lib.Tasks;
  11.  
  12. namespace COServer.Network.Sockets
  13. {
  14.     public class ClientWrapper : Writer, ISocket
  15.     {
  16.         [DllImport("ws2_32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  17.         public static extern int closesocket(IntPtr s);
  18.         [DllImport("ws2_32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  19.         public static extern int shutdown(IntPtr s, ShutDownFlags how);
  20.         public enum ShutDownFlags : int
  21.         {
  22.             SD_RECEIVE = 0,
  23.             SD_SEND = 1,
  24.             SD_BOTH = 2
  25.         }
  26.  
  27.         public int BufferSize;
  28.         public byte[] Buffer;
  29.         public Socket Socket;
  30.         public object Connector { get; set; }
  31.         public ServerSocket Server;
  32.  
  33.         public string IP { get; set; }
  34.         public string LocalIp { get; set; }
  35.         public string MAC;
  36.         public bool Alive { get; set; }
  37.         public bool OverrideTiming { get; set; }
  38.  
  39.         private Queue<byte[]> SendQueue;
  40.         private object SendSyncRoot;
  41.  
  42.         public Action<byte[], int, ClientWrapper> Callback;
  43.         public SingaleTask<ClientWrapper> ConnectionReceive, ConnectionReview, ConnectionSend;
  44.         public List<SingaleTask<ClientWrapper>> SocketTasks;
  45.         public void Create(Socket socket, ServerSocket server, Action<byte[], int, ClientWrapper> callBack)
  46.         {
  47.             Callback = callBack;
  48.             BufferSize = 2047;
  49.             Socket = socket;
  50.             Server = server;
  51.             Buffer = new byte[BufferSize];
  52.             LastReceive = Time64.Now;
  53.             OverrideTiming = false;
  54.             SendQueue = new Queue<byte[]>();
  55.             SendSyncRoot = new object();
  56.  
  57.             SocketTasks = new List<SingaleTask<ClientWrapper>>();
  58.             ConnectionReview = new SingaleTask<ClientWrapper>(connectionReview, 2, TaskCreationOptions.LongRunning, TaskScheduler.Default, this, SocketTasks);
  59.             ConnectionReceive = new SingaleTask<ClientWrapper>(connectionReceive, 2, TaskCreationOptions.LongRunning, TaskScheduler.Default, this, SocketTasks);
  60.             ConnectionSend = new SingaleTask<ClientWrapper>(connectionSend, 2, TaskCreationOptions.LongRunning, TaskScheduler.Default, this, SocketTasks);
  61.  
  62.         }
  63.         private void connectionReview(ClientWrapper wrapper)
  64.         {
  65.             ClientWrapper.TryReview(wrapper);
  66.         }
  67.         private void connectionReceive(ClientWrapper wrapper)
  68.         {
  69.             ClientWrapper.TryReceive(wrapper);
  70.         }
  71.         private void connectionSend(ClientWrapper wrapper)
  72.         {
  73.             ClientWrapper.TrySend(wrapper);
  74.         }
  75.         /// <summary>
  76.         /// To be called only from a syncrhonized block of code
  77.         /// </summary>
  78.         /// <param name="data"></param>
  79.         public void Send(byte[] data)
  80.         {
  81. #if DIRECTSEND
  82.             lock (SendSyncRoot)
  83.                 Socket.Send(data);
  84. #else
  85.             lock (SendSyncRoot)
  86.                 SendQueue.Enqueue(data);
  87. #endif
  88.         }
  89.         public void SendBytes(byte[] data)
  90.         {
  91. #if DIRECTSEND
  92.             lock (SendSyncRoot)
  93.                 Socket.Send(data);
  94. #else
  95.             lock (SendSyncRoot)
  96.                 SendQueue.Enqueue(data);
  97. #endif
  98.         }
  99.         public Time64 LastReceive;
  100.         public Time64 LastReceiveCall;
  101.  
  102.         public void Disconnect()
  103.         {
  104.             lock (Socket)
  105.             {
  106.                 int K = 1000;
  107.                 while (SendQueue.Count > 0 && Alive && (K--) > 0)
  108.                     System.Threading.Thread.Sleep(1);
  109.                 if (!Alive) return;
  110.                 Alive = false;
  111.  
  112.                 //for (int i = 0; i < SocketTasks.Count; i++)
  113.                 //   SocketTasks[i].Dispose();
  114.  
  115.                 shutdown(Socket.Handle, ShutDownFlags.SD_BOTH);
  116.                 closesocket(Socket.Handle);
  117.  
  118.                 Socket.Dispose();
  119.             }
  120.         }
  121.  
  122.         public static void TryReview(ClientWrapper wrapper)
  123.         {
  124.             if (wrapper.Alive)
  125.             {
  126.                 if (wrapper.OverrideTiming)
  127.                 {
  128.                     if (Time64.Now > wrapper.LastReceive.AddMilliseconds(180000))
  129.                         wrapper.Server.InvokeDisconnect(wrapper);
  130.                 }
  131.                 else
  132.                 {
  133.                     if (Time64.Now < wrapper.LastReceiveCall.AddMilliseconds(2000))
  134.                         if (Time64.Now > wrapper.LastReceive.AddMilliseconds(60000))
  135.                             wrapper.Server.InvokeDisconnect(wrapper);
  136.                 }
  137.             }
  138.         }
  139.  
  140.         private bool isValid()
  141.         {
  142.             if (!Alive)
  143.             {
  144.                 if (SocketTasks != null)
  145.                 {
  146.                     foreach (var item in SocketTasks.ToArray())
  147.                     {
  148.                         try
  149.                         {
  150.                             item.Breakwhile = true;
  151.                             if (item.MyTask != null)
  152.                                 item.MyTask.Dispose();
  153.                         }
  154.                         catch
  155.                         {
  156.                             //Alerady cloesd
  157.                         }
  158.                     }
  159.                     return false;
  160.                 }
  161.             }
  162.             return true;
  163.         }
  164.  
  165.         private void doReceive(int available)
  166.         {
  167.             LastReceive = Time64.Now;
  168.             try
  169.             {
  170.                 if (available > Buffer.Length) available = Buffer.Length;
  171.                 int size = Socket.Receive(Buffer, available, SocketFlags.None);
  172.  
  173.                 if (size != 0)
  174.                 {
  175.                     if (Callback != null)
  176.                         Callback(Buffer, size, this);
  177.                 }
  178.                 else
  179.                 {
  180.                     Server.InvokeDisconnect(this);
  181.                 }
  182.             }
  183.             catch (SocketException e)
  184.             {
  185.                 Server.InvokeDisconnect(this);
  186.             }
  187.             catch (Exception e)
  188.             {
  189.                 System.Console.WriteLine(e);
  190.             }
  191.         }
  192.         public static void TryReceive(ClientWrapper wrapper)
  193.         {
  194.             wrapper.LastReceiveCall = Time64.Now;
  195.             if (!wrapper.isValid()) return;
  196.             try
  197.             {
  198.                 bool poll = wrapper.Socket.Poll(0, SelectMode.SelectRead);
  199.                 int available = wrapper.Socket.Available;
  200.                 if (available > 0)
  201.                     wrapper.doReceive(available);
  202.                 else if (poll)
  203.                 {
  204.                     wrapper.Server.InvokeDisconnect(wrapper);
  205.                 }
  206.             }
  207.             catch (SocketException)
  208.             {
  209.                 wrapper.Server.InvokeDisconnect(wrapper);
  210.             }
  211.         }
  212.  
  213.         private bool TryDequeueSend(out byte[] buffer)
  214.         {
  215.             buffer = null;
  216.             lock (SendSyncRoot)
  217.                 if (SendQueue.Count != 0)
  218.                     buffer = SendQueue.Dequeue();
  219.             return buffer != null;
  220.         }
  221.  
  222.         public static void TrySend(ClientWrapper wrapper)
  223.         {
  224.             if (!wrapper.isValid()) return;
  225.             byte[] buffer;
  226.  
  227.             while (wrapper.TryDequeueSend(out buffer))
  228.             {
  229.                 try
  230.                 {
  231.  
  232.                     wrapper.Socket.Send(buffer);
  233.                     //wrapper.Socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, endSend, wrapper);
  234.                 }
  235.                 catch
  236.                 {
  237.                     wrapper.Server.InvokeDisconnect(wrapper);
  238.                 }
  239.             }
  240.         }
  241.  
  242.         private static void endSend(IAsyncResult ar)
  243.         {
  244.             var wrapper = ar.AsyncState as ClientWrapper;
  245.             try
  246.             {
  247.                 wrapper.Socket.EndSend(ar);
  248.             }
  249.             catch
  250.             {
  251.                 wrapper.Server.InvokeDisconnect(wrapper);
  252.             }
  253.         }
  254.     }
  255. }
  256.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement