如何有效地将TCP数据包重定向到服务器

时间:2016-08-11 12:36:14

标签: vb.net tcp proxy packets

所以,我正在修改游戏。 这是一个在线游戏,它连接到端口2050的服务器。现在我修改了游戏代码,因此它连接到127.0.0.1(本地)端口2050而不是游戏服务器。游戏想要发送Hello数据包和其他数据包,如“移动”数据包或Ping数据包或Tick数据包,然后服务器将使用Pong数据包或TickReceived等进行回复。我可以给你一个所有数据包的列表,但这不会帮助解决问题

因此,当游戏将数据包发送到接收它们的控制台应用程序时,游戏无法启动。为什么?因为我也必须用数据包回复它。所以我需要游戏向我发送数据包,然后我将这些数据包发送到服务器,从该服务器接收数据包,然后将这些数据包发送回游戏,并循环该过程,以便游戏保持活力。

以下是我尝试使用的代码:

Imports System.Net.Sockets
Imports System.Net
Imports System.Text

Module Module1
  Private theListener As TcpListener = Nothing
 Sub Main()
     Try
         theListener = New TcpListener(IPAddress.Parse("127.0.0.1"), 2050)
         theListener.Start()
         Threading.ThreadPool.QueueUserWorkItem(AddressOf newclient)

        Console.WriteLine("Listening...")
    Catch ex As Exception
        Console.WriteLine(ex.ToString)
    End Try
    Console.ReadLine()
End Sub
Sub newclient()
    Try
        Using client As TcpClient = theListener.AcceptTcpClient
            Console.ForegroundColor = ConsoleColor.Yellow
            Console.WriteLine("Client connected!")
            Console.ResetColor()
            Threading.ThreadPool.QueueUserWorkItem(AddressOf newclient)
            Using ns As NetworkStream = client.GetStream
                While True

                    Try
                        Dim toreceive(100000) As Byte
                        Dim length As Integer = ns.Read(toreceive, 0, toreceive.Length)
                        Dim text As String = Encoding.ASCII.GetString(toreceive, 0, length)
                        Console.WriteLine("Received packet.")
                        Try
                            Console.WriteLine("Sending to server.")
                            Dim serverh As TcpClient = New TcpClient
                            Try
                                serverh.Connect("this is the games ip address", 2050)
                                Try
                                    Dim serverstream = serverh.GetStream
                                    serverstream.Write(toreceive, 0, length)
                                    Console.WriteLine("Packet send to the server.")
                                    Try
                                        Dim toreceivefromserver(1000000) As Byte
                                        Dim lengthserver As Integer = serverstream.Read(toreceivefromserver, 0, toreceivefromserver.Length)
                                        Try

                                            ns.Write(toreceivefromserver, 0, length)
                                            Console.WriteLine("Packet that was received from server, sent to client")
                                        Catch ex As Exception

                                        End Try
                                    Catch ex As Exception
                                        MsgBox(ex.ToString)
                                    End Try

                                Catch ex As Exception
                                    Console.WriteLine("Problem when trying to send packet to server")
                                    MsgBox(ex.ToString)
                                End Try
                            Catch ex As Exception
                                Console.WriteLine("Could not connect to server.")
                                MsgBox(ex.ToString)

                            End Try

                        Catch ex As Exception

                        End Try


                        Catch ex As Exception
                            Console.ForegroundColor = ConsoleColor.Red
                        ' Console.WriteLine(ex.ToString)
                            Console.ResetColor()
                        End Try



                End While

            End Using
        End Using
    Catch ex As Exception
        ' Console.WriteLine(ex)
    End Try
End Sub

无论出于何种原因,这都行不通。我可以给你例外,但我更希望你有更好的想法来重定向数据包或者更简单的方法。

UPDATE *****

如果有人认为我不解释我需要做什么,这里是一张照片。 Top row:What happens - Bottom row: What I want to happen

UPDATE ******

这是hello数据包的结构。 (我知道术语“数据包”不正确,但请耐心等待我)

    namespace Lib_K_Relay.Networking.Packets.Client
   {
   public class HelloPacket : Packet
    {
     public string BuildVersion;
    public int GameId;
    public string GUID;
     public int Random1;
    public string Password;
    public int Random2;
    public string Secret;
    public int KeyTime;
    public byte[] Key;
    public string Obf1;
    public string Obf2;
    public string Obf3;
    public string Obf4;
    public string Obf5;
    public string Obf6;

    public byte[] RAW;

    public override PacketType Type
    { get { return PacketType.HELLO; } }

    public override void Read(PacketReader r)
    {
        BuildVersion = r.ReadString();
        GameId = r.ReadInt32();
        GUID = r.ReadString();
        Random1 = r.ReadInt32();
        Password = r.ReadString();
        Random2 = r.ReadInt32();
        Secret = r.ReadString();
        KeyTime = r.ReadInt32();
        Key = (byte[])(Array)r.ReadBytes(r.ReadInt16());
        Obf1 = r.ReadUTF32();
        Obf2 = r.ReadString();
        Obf3 = r.ReadString();
        Obf4 = r.ReadString();
        Obf5 = r.ReadString();
        Obf6 = r.ReadString();
    }

    public override void Write(PacketWriter w)
    {
        w.Write(BuildVersion);
        w.Write(GameId);
        w.Write(GUID);
        w.Write(Random1);
        w.Write(Password);
        w.Write(Random2);
        w.Write(Secret);
        w.Write(KeyTime);
        w.Write((short)Key.Length);
        w.Write((byte[])(Array)Key);
        w.WriteUTF32(Obf1);
        w.Write(Obf2);
        w.Write(Obf3);
        w.Write(Obf4);
        w.Write(Obf5);
        w.Write(Obf6);
    }
}
}

现在你看到了packetwriter和packetreader,它们是:

PacketWriter:

namespace Lib_K_Relay.Networking.Packets
{
      public class PacketWriter : BinaryWriter
   {
    public PacketWriter(MemoryStream input)
        : base(input) { }

    public override void Write(short value)
    {
        base.Write(IPAddress.NetworkToHostOrder(value));
    }

    public override void Write(ushort value)
    {
        base.Write((ushort)IPAddress.HostToNetworkOrder((short)value));
    }

    public override void Write(int value)
    {
        base.Write(IPAddress.NetworkToHostOrder(value));
    }

    public override void Write(float value)
    {
        byte[] b = BitConverter.GetBytes(value);
        Array.Reverse(b);
        base.Write(b);
    }

    public override void Write(string value)
    {
        byte[] data = Encoding.UTF8.GetBytes(value);
        Write((short)data.Length);
        base.Write(data);
    }

    public void WriteUTF32(string value)
    {
        Write(value.Length);
        Write(Encoding.UTF8.GetBytes(value));
    }

    public static void BlockCopyInt32(byte[] data, int int32)
    {
        byte[] lengthBytes = BitConverter.GetBytes(IPAddress.NetworkToHostOrder(int32));
        data[0] = lengthBytes[0];
        data[1] = lengthBytes[1];
        data[2] = lengthBytes[2];
        data[3] = lengthBytes[3];
    }
}
}

namespace Lib_K_Relay.Networking.Packets
 {
    public class PacketReader : BinaryReader
    {
      public PacketReader(MemoryStream input)
        : base(input, Encoding.UTF8) { }

    public override short ReadInt16()
    {
        return IPAddress.NetworkToHostOrder(base.ReadInt16());
    }

    public override ushort ReadUInt16()
    {
        return (ushort)IPAddress.NetworkToHostOrder((short)base.ReadUInt16());
    }

    public override int ReadInt32()
    {
        return IPAddress.NetworkToHostOrder(base.ReadInt32());
    }

    public override float ReadSingle()
    {
        byte[] arr = base.ReadBytes(4);
        Array.Reverse(arr);
        return BitConverter.ToSingle(arr, 0);
    }

    public override string ReadString()
    {
        return Encoding.UTF8.GetString(ReadBytes(ReadInt16()));
    }

    public string ReadUTF32()
    {
        return Encoding.UTF8.GetString(ReadBytes(ReadInt32()));
    }
}
}
;

一个名为Packet的课程:

 namespace Lib_K_Relay.Networking.Packets
{
  public class Packet
  {
     public bool Send = true;
     public byte Id;

     private byte[] _data;

     public virtual PacketType Type
     { get { return PacketType.UNKNOWN; } }

    public virtual void Read(PacketReader r)
    {
        _data = r.ReadBytes((int)r.BaseStream.Length - 5); // All of the packet data
    }

    public virtual void Write(PacketWriter w)
    {
        w.Write(_data); // All of the packet data
    }

    public static Packet Create(PacketType type)
    {
        Packet packet = (Packet)Activator.CreateInstance(
            Serializer.GetPacketType(type));
        packet.Id = Serializer.GetPacketId(type);
        return packet;
    }

    public static T Create<T>(PacketType type)
    {
        Packet packet = (Packet)Activator.CreateInstance(typeof(T));
        packet.Id = Serializer.GetPacketId(type);
        return (T)Convert.ChangeType(packet, typeof(T));
    }

    public T To<T>()
    {
        return (T)Convert.ChangeType(this, typeof(T));
    }

    public static Packet Create(byte[] data)
    {
        using (PacketReader r = new PacketReader(new MemoryStream(data)))
        {
            r.ReadInt32(); // Skip over int length
            byte id = r.ReadByte();
            PacketType packetType = Serializer.GetPacketPacketType(id);
            Type type = Serializer.GetPacketType(packetType);
            // Reflect the type to a new instance and read its data from the PacketReader
            Packet packet = (Packet)Activator.CreateInstance(type);
            packet.Id = id;
            packet.Read(r);

            return packet;
        }
    }

    public override string ToString()
    {
        // Use reflection to get the packet's fields and values so we don't have
        // to formulate a ToString method for every packet type.
        FieldInfo[] fields = GetType().GetFields(BindingFlags.Public |
                                          BindingFlags.NonPublic |
                                          BindingFlags.Instance);

        StringBuilder s = new StringBuilder();
        s.Append(Type + "(" + Id + ") Packet Instance");
        foreach (FieldInfo f in fields)
            s.Append("\n\t" + f.Name + " => " + f.GetValue(this));
        return s.ToString();
    }

    public string ToStructure()
    {
        // Use reflection to build a list of the packet's fields.
        FieldInfo[] fields = GetType().GetFields(BindingFlags.Public |
                                          BindingFlags.NonPublic |
                                          BindingFlags.Instance);

        StringBuilder s = new StringBuilder();
        s.Append(Type + " [" + Serializer.GetPacketId(Type) + "] \nPacket Structure:\n{");
        foreach (FieldInfo f in fields)
            s.Append("\n  " + f.Name + " => " + f.FieldType.Name);
        s.Append("\n}");
        return s.ToString();
    }
}

public enum PacketType
{
    UNKNOWN,
    FAILURE,
    CREATESUCCESS,
    CREATE,
    PLAYERSHOOT,
    MOVE,
    PLAYERTEXT,
    TEXT,
    SHOOT2,
    DAMAGE,
    UPDATE,
    UPDATEACK,
    NOTIFICATION,
    NEWTICK,
    INVSWAP,
    USEITEM,
    SHOWEFFECT,
    HELLO,
    GOTO,
    INVDROP,
    INVRESULT,
    RECONNECT,
    PING,
    PONG,
    MAPINFO,
    LOAD,
    PIC,
    SETCONDITION,
    TELEPORT,
    USEPORTAL,
    DEATH,
    BUY,
    BUYRESULT,
    AOE,
    GROUNDDAMAGE,
    PLAYERHIT,
    ENEMYHIT,
    AOEACK,
    SHOOTACK,
    OTHERHIT,
    SQUAREHIT,
    GOTOACK,
    EDITACCOUNTLIST,
    ACCOUNTLIST,
    QUESTOBJID,
    CHOOSENAME,
    NAMERESULT,
    CREATEGUILD,
    CREATEGUILDRESULT,
    GUILDREMOVE,
    GUILDINVITE,
    ALLYSHOOT,
    SHOOT,
    REQUESTTRADE,
    TRADEREQUESTED,
    TRADESTART,
    CHANGETRADE,
    TRADECHANGED,
    ACCEPTTRADE,
    CANCELTRADE,
    TRADEDONE,
    TRADEACCEPTED,
    CLIENTSTAT,
    CHECKCREDITS,
    ESCAPE,
    FILE,
    INVITEDTOGUILD,
    JOINGUILD,
    CHANGEGUILDRANK,
    PLAYSOUND,
    GLOBALNOTIFICATION,
    RESKIN,
    ENTERARENA,
    LEAVEARENA,
    PETCOMMAND,
    PETYARDCOMMAND,
    TINKERQUEST,
    VIEWQUESTS,
    ARENADEATH,
    ARENANEXTWAVE,
    HATCHEGG,
    NEWABILITYUNLOCKED,
    PASSWORDPROMPT,
    EVOLVEPET,
    QUESTFETCHRESPONSE,
    REMOVEPET,
    UPDATEPET,
    UPGRADEPETYARDRESULT,
    VERIFYEMAILDIALOG,
    QUESTREDEEMRESPONSE
}
}

这取自名为K_Relay的代理的来源,区别在于某个代理允许您修改值并发送自定义数据包。

0 个答案:

没有答案