所以,我正在修改游戏。 这是一个在线游戏,它连接到端口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的代理的来源,区别在于某个代理允许您修改值并发送自定义数据包。