Kcp.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. using System;
  2. using System.Runtime.InteropServices;
  3. namespace ET
  4. {
  5. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  6. public delegate int KcpOutput(IntPtr buf, int len, IntPtr kcp, IntPtr user);
  7. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  8. public delegate void KcpLog(IntPtr buf, int len, IntPtr kcp, IntPtr user);
  9. public static class Kcp
  10. {
  11. public const int OneM = 1024 * 1024;
  12. public const int InnerMaxWaitSize = 1024 * 1024;
  13. public const int OuterMaxWaitSize = 1024 * 1024;
  14. private static KcpOutput KcpOutput;
  15. private static KcpLog KcpLog;
  16. #if UNITY_IPHONE && !UNITY_EDITOR
  17. const string KcpDLL = "__Internal";
  18. #else
  19. const string KcpDLL = "kcp";
  20. #endif
  21. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  22. private static extern uint ikcp_check(IntPtr kcp, uint current);
  23. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  24. private static extern IntPtr ikcp_create(uint conv, IntPtr user);
  25. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  26. private static extern void ikcp_flush(IntPtr kcp);
  27. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  28. private static extern uint ikcp_getconv(IntPtr ptr);
  29. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  30. private static extern int ikcp_input(IntPtr kcp, byte[] data, int offset, int size);
  31. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  32. private static extern int ikcp_nodelay(IntPtr kcp, int nodelay, int interval, int resend, int nc);
  33. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  34. private static extern int ikcp_peeksize(IntPtr kcp);
  35. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  36. private static extern int ikcp_recv(IntPtr kcp, byte[] buffer, int index, int len);
  37. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  38. private static extern void ikcp_release(IntPtr kcp);
  39. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  40. private static extern int ikcp_send(IntPtr kcp, byte[] buffer, int offset, int len);
  41. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  42. private static extern void ikcp_setminrto(IntPtr ptr, int minrto);
  43. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  44. private static extern int ikcp_setmtu(IntPtr kcp, int mtu);
  45. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  46. private static extern void ikcp_setoutput(KcpOutput output);
  47. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  48. private static extern void ikcp_setlog(KcpLog log);
  49. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  50. private static extern void ikcp_update(IntPtr kcp, uint current);
  51. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  52. private static extern int ikcp_waitsnd(IntPtr kcp);
  53. [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
  54. private static extern int ikcp_wndsize(IntPtr kcp, int sndwnd, int rcvwnd);
  55. public static uint KcpCheck(IntPtr kcp, uint current)
  56. {
  57. if (kcp == IntPtr.Zero)
  58. {
  59. throw new Exception($"kcp error, kcp point is zero");
  60. }
  61. uint ret = ikcp_check(kcp, current);
  62. return ret;
  63. }
  64. public static IntPtr KcpCreate(uint conv, IntPtr user)
  65. {
  66. return ikcp_create(conv, user);
  67. }
  68. public static void KcpFlush(IntPtr kcp)
  69. {
  70. if (kcp == IntPtr.Zero)
  71. {
  72. throw new Exception($"kcp error, kcp point is zero");
  73. }
  74. ikcp_flush(kcp);
  75. }
  76. public static uint KcpGetconv(IntPtr ptr)
  77. {
  78. if (ptr == IntPtr.Zero)
  79. {
  80. throw new Exception($"kcp error, kcp point is zero");
  81. }
  82. return ikcp_getconv(ptr);
  83. }
  84. public static int KcpInput(IntPtr kcp, byte[] buffer, int offset, int len)
  85. {
  86. if (kcp == IntPtr.Zero)
  87. {
  88. throw new Exception($"kcp error, kcp point is zero");
  89. }
  90. if (offset + len > buffer.Length)
  91. {
  92. throw new Exception($"kcp error, KcpInput {buffer.Length} {offset} {len}");
  93. }
  94. int ret = ikcp_input(kcp, buffer, offset, len);
  95. return ret;
  96. }
  97. public static int KcpNodelay(IntPtr kcp, int nodelay, int interval, int resend, int nc)
  98. {
  99. if (kcp == IntPtr.Zero)
  100. {
  101. throw new Exception($"kcp error, kcp point is zero");
  102. }
  103. return ikcp_nodelay(kcp, nodelay, interval, resend, nc);
  104. }
  105. public static int KcpPeeksize(IntPtr kcp)
  106. {
  107. if (kcp == IntPtr.Zero)
  108. {
  109. throw new Exception($"kcp error, kcp point is zero");
  110. }
  111. int ret = ikcp_peeksize(kcp);
  112. return ret;
  113. }
  114. public static int KcpRecv(IntPtr kcp, byte[] buffer, int index, int len)
  115. {
  116. if (kcp == IntPtr.Zero)
  117. {
  118. throw new Exception($"kcp error, kcp point is zero");
  119. }
  120. if (buffer.Length < index + len)
  121. {
  122. throw new Exception($"kcp error, KcpRecv error: {index} {len}");
  123. }
  124. int ret = ikcp_recv(kcp, buffer, index, len);
  125. return ret;
  126. }
  127. public static void KcpRelease(IntPtr kcp)
  128. {
  129. if (kcp == IntPtr.Zero)
  130. {
  131. throw new Exception($"kcp error, kcp point is zero");
  132. }
  133. ikcp_release(kcp);
  134. }
  135. public static int KcpSend(IntPtr kcp, byte[] buffer, int offset, int len)
  136. {
  137. if (kcp == IntPtr.Zero)
  138. {
  139. throw new Exception($"kcp error, kcp point is zero");
  140. }
  141. if (offset + len > buffer.Length)
  142. {
  143. throw new Exception($"kcp error, KcpSend {buffer.Length} {offset} {len}");
  144. }
  145. int ret = ikcp_send(kcp, buffer, offset, len);
  146. return ret;
  147. }
  148. public static void KcpSetminrto(IntPtr kcp, int minrto)
  149. {
  150. if (kcp == IntPtr.Zero)
  151. {
  152. throw new Exception($"kcp error, kcp point is zero");
  153. }
  154. ikcp_setminrto(kcp, minrto);
  155. }
  156. public static int KcpSetmtu(IntPtr kcp, int mtu)
  157. {
  158. if (kcp == IntPtr.Zero)
  159. {
  160. throw new Exception($"kcp error, kcp point is zero");
  161. }
  162. return ikcp_setmtu(kcp, mtu);
  163. }
  164. public static void KcpSetoutput(KcpOutput output)
  165. {
  166. KcpOutput = output;
  167. ikcp_setoutput(KcpOutput);
  168. }
  169. public static void KcpSetLog(KcpLog kcpLog)
  170. {
  171. KcpLog = kcpLog;
  172. ikcp_setlog(KcpLog);
  173. }
  174. public static void KcpUpdate(IntPtr kcp, uint current)
  175. {
  176. if (kcp == IntPtr.Zero)
  177. {
  178. throw new Exception($"kcp error, kcp point is zero");
  179. }
  180. ikcp_update(kcp, current);
  181. }
  182. public static int KcpWaitsnd(IntPtr kcp)
  183. {
  184. if (kcp == IntPtr.Zero)
  185. {
  186. throw new Exception($"kcp error, kcp point is zero");
  187. }
  188. int ret = ikcp_waitsnd(kcp);
  189. return ret;
  190. }
  191. public static int KcpWndsize(IntPtr kcp, int sndwnd, int rcvwnd)
  192. {
  193. if (kcp == IntPtr.Zero)
  194. {
  195. throw new Exception($"kcp error, kcp point is zero");
  196. }
  197. return ikcp_wndsize(kcp, sndwnd, rcvwnd);
  198. }
  199. }
  200. }