// public virtual void SendHttpMsg<T>(T obj) // { // if (null == httpMsgRouter) // { // return; // } // // string method = (string)GetStaticMethodInfo<T>("GetHttpMethod").Invoke(null, null); // // string directory = (string)GetStaticMethodInfo<T>("GetUrl").Invoke(null, null); // // string parameters = ""; // string body = ""; // // if ("GET" == method.ToUpper() || "DELETE" == method.ToUpper()) // { // parameters = ProtoBufUtil.ToUrlParams<T>(obj); // } // else // { // body = ProtoBufUtil.ToJson<T>(obj); // } // // httpMsgRouter.SendMsg(method, directory, body, parameters); // } public virtual void SendHttpMsg <T>(T obj, string url, string method, bool getOriginData = false, bool needResp = true) where T : IProtocolHead, IMessage <T> { if (null == httpMsgRouter) { return; } string directory = url; string parameters = ""; string body = ""; UInt16 appCode = 0, funcCode = 0; byte flag = 0; GetProtoArgs <T>(out appCode, out funcCode, out flag); byte[] data = PackageUtils.Serialize2Binary <T> (obj, appCode, funcCode, PackageUtils.OpCode); if ("GET" == method.ToUpper() || "DELETE" == method.ToUpper()) { parameters = ProtoBufUtil.ToUrlParams <T>(obj); } else { body = "content=" + Convert.ToBase64String(data); //ProtoBufUtil.ToJson<T>(obj); } httpMsgRouter.SendMsg(method, directory, body, parameters, null, false, data, needResp); }
public void OnOneClientAccepted(IAsyncResult result) { Socket server = result.AsyncState as Socket; //这就是客户端的Socket实例,我们后续可以将其保存起来 Socket client = server.EndAccept(result); try { //接受多个客户端 ,准备接受下一个客户端请求 server.BeginAccept(new AsyncCallback(OnOneClientAccepted), server); byte[] buffer = new byte[1024]; //给客户端发送一个欢迎消息 SendOneMsg(client, ProtoBufUtil.PackNetMsg(new NetMsgData(0, "[Server]Hi there, I accept you request at " + DateTime.Now.ToString()))); ClientInfo info = new ClientInfo(); info.Id = client.RemoteEndPoint; info.handle = client.Handle; info.buffer = buffer; m_clientPool.Add(client, info); Console.WriteLine(string.Format("One Client {0} connected!!", client.RemoteEndPoint)); //HeartBeat(client); //接收客户端的消息(这个和在客户端实现的方式是一样的) client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveMessage), client); } catch (Exception ex) { Console.WriteLine("Error :\r\n\t" + ex.ToString()); } }
// 广播 private void Broadcast() { Thread broadcast = new Thread(() => { while (true) { if (m_msgPool.Count > 0) { byte[] msg = ProtoBufUtil.PackNetMsg(m_msgPool[0]); foreach (KeyValuePair <Socket, ClientInfo> cs in m_clientPool) { // client客户端socket对象 Socket client = cs.Key; if (client.Connected) { client.Send(msg, msg.Length, SocketFlags.None); } } m_msgPool.RemoveAt(0); } } }); broadcast.Start(); }
public void HeartBeat(Socket client) { //实现每隔两秒钟给服务器发一个消息 //这里我们使用了一个定时器 var timer = new System.Timers.Timer(); timer.Interval = 2000D; timer.Enabled = true; timer.Elapsed += (o, a) => { //检测客户端的活动状态 if (client.Connected) { try { SendOneMsg(client, ProtoBufUtil.PackNetMsg(new NetMsgData(0, "[Server]HeartBeat:" + DateTime.Now.ToString()))); Console.WriteLine("[Server]HeartBeat:" + client.GetHost() + DateTime.Now.ToString()); } catch (Exception ex) { Console.WriteLine(ex.Message); } } else { timer.Stop(); timer.Enabled = false; Console.WriteLine("Client is disconnected, the timer is stop."); } }; timer.Start(); }
// 发送请求 public static void SendMsg(Socket socket, IMessage data, ushort id) { var content = data.ToByteArray(); var byteArray = ProtoBufUtil.Encode(content, id); socket.BeginSend(byteArray, 0, byteArray.Length, SocketFlags.None, null, null); Debug.Log($"[Client]client send: ID:{id},DataLen:{content.Length}"); }
// 发送请求 public static void SendMsg(Socket socket, IMessage data, ushort id) { var content = data.ToByteArray(); var msg = ProtoBufUtil.Encode(content, id); socket.Send(msg); Console.WriteLine($"[Server] Server send: ID:{id},DataLen:{content.Length}"); }
/// <summary> /// 根据具体内容初始化 /// </summary> /// <param name="packageId">packageId</param> /// <param name="ChannelName">ChannelName</param> /// <param name="ChannelData">ChannelData</param> public PackagePlugin(byte packageId, string ChannelName, byte[] ChannelData, bool is112) { //成员 this.ChannelName = ChannelName; this.ChannelData = ChannelData; byte[] channelDataLengthBytes = BitConverter.GetBytes((Int16)ChannelData.Length).Reverse(); //Data List <byte> data = new List <byte>(); data.AddRange(ProtoBufUtil.GetVarStringBytes(ChannelName)); if (!is112) { data.AddRange(channelDataLengthBytes); } data.AddRange(ChannelData); //OriginData List <byte> originData = new List <byte>(); List <byte> packageIdAndData = new List <byte>(); packageIdAndData.Add(packageId); packageIdAndData.AddRange(data); if (is112) { // 如果大于阈值 , 就压缩 if (packageIdAndData.Count > Global.CompressionThreshold) { byte[] compressData = ZLibUtil.Compress(packageIdAndData.ToArray()); byte[] compressDataLengthBytes = ProtoBufUtil.GetVarIntBytes(packageIdAndData.Count); byte[] lengthBytes = ProtoBufUtil.GetVarIntBytes(compressDataLengthBytes.Length + compressData.Length); originData.AddRange(lengthBytes); originData.AddRange(compressDataLengthBytes); originData.AddRange(compressData); } else { byte[] lengthBytes = ProtoBufUtil.GetVarIntBytes(packageIdAndData.Count + 1); originData.AddRange(lengthBytes); originData.Add(0); originData.AddRange(packageIdAndData); } } else { byte[] lengthBytes = ProtoBufUtil.GetVarIntBytes(packageIdAndData.Count); originData.AddRange(lengthBytes); originData.AddRange(packageIdAndData); } //父类成员 this.PackageId = packageId; this.Data = data.ToArray(); this.OriginData = originData.ToArray(); }
/// <summary> /// 处理服务端classcheck /// 1.2.7 之后会随机发送一个类, 所以这里如果找到了就返回 /// 如果找不到就说明是之前的版本, 就返回别的 /// </summary> /// <param name="package"></param> /// <param name="toClientWriter"></param> /// <param name="toServerWriter"></param> /// <returns></returns> private bool ClassCheckHandle(PackagePlugin package, BinaryWriter toClientWriter, BinaryWriter toServerWriter) { List <string> randomClassNames = new List <string> { // v1.2.7 "net.minecraft.launchwrapper.Launch", "net.minecraft.launchwrapper.LogWrapper", "net.minecraft.launchwrapper.AlphaVanillaTweaker", // v1.2.8 "net.minecraft.launchwrapper.injector.VanillaTweakInjector", "io.netty.bootstrap.Bootstrap" }; using (MemoryStream ms = new MemoryStream(package.ChannelData, 1, package.ChannelData.Length - 1)) { using (BinaryReader br = new BinaryReader(ms)) { Int16 size = br.ReadInt16BE(); List <string> classNames = new List <string>(); for (int i = 0; i < size; i++) { classNames.Add(br.ReadVarString()); } var exist = classNames.Intersect(randomClassNames).FirstOrDefault(); List <byte> bytes = new List <byte>(); if (string.IsNullOrEmpty(exist)) { bytes = new List <byte> { (byte)CatAntiCheatMessageType.CTSClassFound, 0, 0, salt }; Console.WriteLine($"[CatAntiCheat]收到服务端ClassCheck请求, 直接返回无作弊!"); } else { bytes = new List <byte> { (byte)CatAntiCheatMessageType.CTSClassFound }; bytes.AddRange(BitConverter.GetBytes((short)1).Reverse()); bytes.AddRange(ProtoBufUtil.GetVarStringBytes(exist)); bytes.Add(salt); Console.WriteLine($"[CatAntiCheat]收到服务端ClassCheck请求, 直接返回[{exist}]"); } PackagePlugin fake = new PackagePlugin(CTSPluginPackageId, package.ChannelName, bytes.ToArray(), Global.IsVersion1_12_2); toServerWriter.Write(fake.OriginData); return(true); } } }
/// <summary> /// 客户端往服务端发包 /// </summary> /// <param name="obj"></param> private void ServerToClient(dynamic obj) { TcpClient tc1 = obj.tc1; TcpClient tc2 = obj.tc2; NetworkStream ns1 = tc1.GetStream(); NetworkStream ns2 = tc2.GetStream(); BinaryReader reader = new BinaryReader(ns1); toClientWriter = new BinaryWriter(ns2); Global.ToClientWriter = toClientWriter; while (status) { try { Package package = reader.ReadPackage(); if (Plugins.Plugins.STCHandle(package, toClientWriter, toServerWriter)) { continue; } // 设置压缩阈值 if (Global.IsVersion1_12_2 && Global.IsCompression == false && package.PackageId == 0x03) { int maximum = ProtoBufUtil.GetVarIntFromBytes(package.Data); if (maximum >= 0) { Global.IsCompression = true; Global.CompressionThreshold = maximum; } } toClientWriter.Write(package.OriginData); } catch { break; } } toClientWriter.Close(); reader.Close(); ns1.Dispose(); ns2.Dispose(); tc1.Close(); tc2.Close(); }
// 派发 public static void HandleMsg(byte[] buffer) { NetMsgData data = ProtoBufUtil.UnpackNetMsg(buffer); var protoID = data.ID; NetHandler callback; if (m_EventMap.TryGetValue(protoID, out callback)) { GameLog.Log("[Receive]Server :protoID:{0},data:{1}", protoID, data.Data); if (callback != null) { callback(data.Data); } } else { GameLog.Log("[Receive]收到未监听的服务器消息:protoID:{0},data:{1}", protoID, data.Data); } }
public static Package Create(byte packageId, byte[] data, bool is112) { Package package = new Package(); package.PackageId = packageId; package.Data = data; List <byte> packageIdAndData = new List <byte>(); List <byte> originData = new List <byte>(); packageIdAndData.Add(packageId); packageIdAndData.AddRange(data); if (is112) { // 如果大于阈值 , 就压缩 if (packageIdAndData.Count > Global.CompressionThreshold) { byte[] compressData = ZLibUtil.Compress(packageIdAndData.ToArray()); byte[] compressDataLengthBytes = ProtoBufUtil.GetVarIntBytes(packageIdAndData.Count); byte[] lengthBytes = ProtoBufUtil.GetVarIntBytes(compressDataLengthBytes.Length + compressData.Length); originData.AddRange(lengthBytes); originData.AddRange(compressDataLengthBytes); originData.AddRange(compressData); } else { byte[] lengthBytes = ProtoBufUtil.GetVarIntBytes(packageIdAndData.Count + 1); originData.AddRange(lengthBytes); originData.Add(0); originData.AddRange(packageIdAndData); } } else { byte[] lengthBytes = ProtoBufUtil.GetVarIntBytes(packageIdAndData.Count); originData.AddRange(lengthBytes); originData.AddRange(packageIdAndData); } package.OriginData = originData.ToArray(); return(package); }
private void HandleMessage(Socket client, byte[] buffer) { NetMsgData data = ProtoBufUtil.UnpackNetMsg(buffer); var protoID = data.ID; Console.WriteLine("[Receive]{0} | {1} | {2} | {3}", client.RemoteEndPoint, data.ID, data.Data, DateTime.Now); switch (protoID) { case (OpCode.C2S_TestRequest): data.ID = OpCode.S2C_TestResponse; data.Data = "Test OK!!"; SendOneMsg(client, ProtoBufUtil.PackNetMsg(data)); Console.WriteLine($"[Send]ID:{data.ID},Data:{data.Data}"); break; default: break; } //m_msgPool.Add(data); }
public static void SendKCPMsg(NetMsgData data) { KCPClient.instance.Send(ProtoBufUtil.PackNetMsg(data)); GameLog.Log("[Send]ID:{0},Data:{1}", data.ID, data.Data); }