|
You last visited: Today at 01:00
Advertisement
[Release] Simple Packet Writer
Discussion on [Release] Simple Packet Writer within the CO2 PServer Guides & Releases forum part of the CO2 Private Server category.
11/15/2012, 00:43
|
#1
|
elite*gold: 12
Join Date: Jul 2011
Posts: 8,211
Received Thanks: 4,114
|
[Release] Simple Packet Writer
Hey everyone.
This was a request by a few friends of mine to make a simple, managed packet writer for C#. You can use it to create packets of all different styles. Using it is easy as well. I'll give you all a few examples of what it can do and how to use it in a minute. First, here's the download for the source code. You may also choose to download it in the form of a dll (which is available through my mediafire account).
Source Download:
Alright, so let's go over how to implement it. It's pretty easy. First, create a new class and inherit the packet structure class (like so):
PHP Code:
// This is an example of a packet: public class PacketName : PacketStructure { public PacketName(byte[] receivedPacket) : base(receivedPacket) { } }
Just by doing this, you've successfully implemented all of the methods from the Packet Structure class. You can now send your class as a byte array at any time. For example, if your character's send method accepts byte arrays, you don't need to do anything to send the packet as a byte array. My class does that implicitly (automatically). It will convert it to a byte array for you. If you wish to change the build method (maybe add some string building calls before finally building the packet), you can always override it by overriding the Build method.
Let's talk about constructing packets. You have two options. You can create your own to send to the client, or receive a packet from the client. Reading and Writing values is easy as well. I've supplied you with a variety of methods. I also gave my Write methods different names (on request) so you can easily see the type of value being written. Feel free to explore the class. I haven't tested it at all, so if you find an error, let me know.
Finally, here are a few examples of it in use:
(Incomplete, just an example)
There are other things you can do as well. I hope this is what you guys asked for.
Cheers,
Spirited Fang.
|
|
|
11/15/2012, 09:23
|
#2
|
elite*gold: 0
Join Date: Dec 2011
Posts: 1,537
Received Thanks: 785
|
Make a property for the pointer, so you don't need to declare it every time.
And a suggestion for WriteStringWithLength make it have an out parameter to spit out the next offset.
And WriteRandomInt, maybe consider doing a static random for the class and a thread-safe one.
I think that's it. Just skimmed through it fast.
#Edit got a last one. Make a constructor for setting a type/size of the packet, so it's not for reading or so you won't need to make a byte array and pass it as argument to it...
#Edit noticed another thing you said that you can send the class as a byte array, might reword that, because you don't send the class. You're using an implicit type-conversion from your packetwriter class to a byte array and it won't actually work. Have you tested it? Pretty sure it will say that you can't convert x to a byte array, where x is the class inheriting the packet writer, but if using the packet writer alone you can. I had that problem with earlier packet writers of mine, so actually you'd also have to create the 2 implicit operators within that instead of the base class only.
|
|
|
11/15/2012, 12:52
|
#3
|
elite*gold: 0
Join Date: Jun 2005
Posts: 692
Received Thanks: 353
|
I've tried to move away from explicitly defined offsets in packet structures. You never know if TQ is going to add new content in the middle of the packet structure and cause your packet structure beyond that new content's offset to become invalid.
|
|
|
11/15/2012, 16:29
|
#4
|
elite*gold: 12
Join Date: Jul 2011
Posts: 8,211
Received Thanks: 4,114
|
Thanks for the suggestions. I'll keep them in mind. I don't actually use this in my project though. It was designed on request for the base I released. I'll add something that spits out the next offset for writing. I like that idea quite a lot. The random they can edit to work with their server. Again, thanks.
@nTLfTy: I write my packets for Kibou using sequential structures and an interface.
|
|
|
11/15/2012, 22:05
|
#5
|
elite*gold: 0
Join Date: Sep 2012
Posts: 775
Received Thanks: 327
|
good job fang , it need some work but basically it's good
keep it up
|
|
|
11/16/2012, 16:00
|
#6
|
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
|
Sorry but what is the use of type there ?
Code:
public LoginPacket(int length, int type)
: base(length, type)
{
}
i tried to send a packet using your class and whatever type i use does not matter in the packet mmm.
|
|
|
11/16/2012, 17:35
|
#7
|
elite*gold: 12
Join Date: Jul 2011
Posts: 8,211
Received Thanks: 4,114
|
Quote:
Originally Posted by Danial Eugen
Sorry but what is the use of type there ?
Code:
public LoginPacket(int length, int type)
: base(length, type)
{
}
i tried to send a packet using your class and whatever type i use does not matter in the packet mmm.
|
You're not supposed to have the length and type in the constructor of the packet itself, only in the base constructor. I should also say that this packet writer is aimed at 5017 and below. "base" is my class, the class you inherited. You inherited it into your own packet class to help you construct and manage the packet. Look at the example I provided.
|
|
|
11/16/2012, 19:54
|
#8
|
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
|
I rewrote your class using Binary Reader\Writer but i got kinda screwed problem that the write string method adds white spaces to the value
Here is the class without the use of pointers [still non complete]
Code:
using System;
using System.IO;
namespace Packets
{
public abstract class PacketStructure
{
private readonly byte[] _array;
readonly BinaryWriter _writer;
readonly BinaryReader _reader;
/// <summary>
/// This class encapsulates a packet structure in the form of a byte array. By inheriting this class, you can make
/// any class a packet that contains methods for reading and writing data values to the packet. After inheriting
/// this class, you may send it to any method that accepts a byte array (this class will automatically convert it).
/// When constructing a new packet, it will write the header for you.
/// </summary>
/// <param name="data">The packet received from the client..</param>
protected PacketStructure(byte[] data)
{
_reader = new BinaryReader(new MemoryStream(_array = data));
}
/// <summary>
/// This class encapsulates a packet structure in the form of a byte array. By inheriting this class, you can make
/// any class a packet that contains methods for reading and writing data values to the packet. After inheriting
/// this class, you may send it to any method that accepts a byte array (this class will automatically convert it).
/// When constructing a new packet, it will write the header for you.
/// </summary>
/// <param name="size">The size of the new packet to be sent to the client.</param>
/// <param name="type">The type of packet being sent.</param>
protected PacketStructure(int size, int type)
{
if (size < 4)
throw new IndexOutOfRangeException("Packet cannot be constructed. size must be 4 or greater.");
_writer = new BinaryWriter(new MemoryStream(_array = new byte[size]));
_writer.Write((ushort)size);
_writer.Write((ushort)type);
}
#region ReadMethods
/// <summary> Reads a one-byte boolean value. </summary>
public bool ReadBoolean()
{
return _reader.ReadBoolean();
}
/// <summary> Reads the next byte value. </summary>
public byte ReadByte()
{
return _reader.ReadByte();
}
/// <summary> Reads a signed byte value. </summary>
public sbyte ReadSByte()
{
return _reader.ReadSByte();
}
/// <summary> Reads the specified number of bytes. </summary>
public byte[] ReadByteArray(int count)
{
return _reader.ReadBytes(count);
}
/// <summary> Reads the next character value. </summary>
public char ReadChar()
{
return _reader.ReadChar();
}
/// <summary> Reads the specified number of characters value. </summary>
public char[] ReadCharArray(int count)
{
return _reader.ReadChars(count);
}
/// <summary> Reads a decimal value. </summary>
public decimal ReadDecimal()
{
return _reader.ReadDecimal();
}
/// <summary> Reads an eight-byte floating point value. </summary>
public double ReadDouble()
{
return _reader.ReadDouble();
}
/// <summary> Reads a four-byte floating point value. </summary>
public float ReadFloat()
{
return _reader.ReadSingle();
}
/// <summary> Reads a four-byte signed integer. </summary>
public int ReadInt()
{
return _reader.ReadInt32();
}
/// <summary> Reads a four-byte unsigned integer. </summary>
public uint ReadUInt()
{
return _reader.ReadUInt32();
}
/// <summary> Reads an eight-byte signed integer. </summary>
public long ReadLong()
{
return _reader.ReadInt64();
}
/// <summary> Reads an eight-byte unsigned integer. </summary>
public ulong ReadULong()
{
return _reader.ReadUInt64();
}
/// <summary> Reads a two-byte signed integer. </summary>
public short ReadShort()
{
return _reader.ReadInt16();
}
/// <summary> Reads a two-byte unsigned integer. </summary>
public ushort ReadUShort()
{
return _reader.ReadUInt16();
}
/// <summary> Reads a string value. </summary>
/// <summary> Reads a string value. </summary>
public string ReadString(int length, bool unicode)
{
var tmp = new byte[length];
for (var i = 0; i < length; i++)
tmp[i] = ReadByte();
return unicode ? Encoding.Unicode.GetString(tmp) : Encoding.ASCII.GetString(tmp);
}
#endregion
#region WriteMethods
/// <summary> Writes a one-byte boolean value. </summary>
public void Write(bool value)
{
_writer.Write(value);
}
/// <summary> Writes an unsigned byte. </summary>
public void Write(byte value)
{
_writer.Write(value);
}
/// <summary> Writes a signed byte. </summary>
public void Write(sbyte value)
{
_writer.Write(value);
}
/// <summary> Writes a byte. </summary>
public void Write(byte[] value)
{
_writer.Write(value);
}
/// <summary> Writes a Unicode character. </summary>
public void Write(char value)
{
_writer.Write(value);
}
/// <summary> Writes a character array. </summary>
public void Write(char[] value)
{
_writer.Write(value);
}
/// <summary> Writes a decimal value. </summary>
public void Write(decimal value)
{
_writer.Write(value);
}
/// <summary> Writes an eight-byte floating point value. </summary>
public void Write(double value)
{
_writer.Write(value);
}
/// <summary> Writes a four-byte floating point value. </summary>
public void Write(float value)
{
_writer.Write(value);
}
/// <summary> Writes a four-byte signed integer. </summary>
public void Write(int value)
{
_writer.Write(value);
}
/// <summary> Writes a four-byte unsigned integer. </summary>
public void Write(uint value)
{
_writer.Write(value);
}
/// <summary> Writes an eight-byte signed integer. </summary>
public void Write(long value)
{
_writer.Write(value);
}
/// <summary> Writes an eight-byte unsigned integer. </summary>
public void Write(ulong value)
{
_writer.Write(value);
}
/// <summary> Writes a two-byte signed integer. </summary>
public void Write(short value)
{
_writer.Write(value);
}
/// <summary> Writes a two-byte unsigned integer. </summary>
public void Write(ushort value)
{
_writer.Write(value);
}
/// <summary> Writes a length-prefixed string. </summary>
public void Write(string value, bool unicode)
{
var tmp = unicode ? Encoding.Unicode.GetBytes(value) : Encoding.ASCII.GetBytes(value);
for (byte i = 0; i < tmp.Length; i++)
Write(tmp[i]);
}
#endregion
#region Reconstruction Methods
#endregion
/// <summary>
/// This method should not be called in a method outside the packet structure class. This method is called
/// by the packet structure class during packet construction (when passing it as a byte array). For advanced
/// packet construction, you may override this method and define how the array is constructed.
/// </summary>
protected virtual byte[] Build()
{
return _array;
}
/// <summary> This method converts the packet class inheriting this into an unsigned byte array. </summary>
/// <param name="structure">The structure being converted into an unsigned byte array.</param>
/// <returns>This method returns the array built by the packet structure class.</returns>
public static implicit operator byte[](PacketStructure structure)
{
return structure.Build();
}
/// <summary> This method creates a new string that represents the packet structure. </summary>
/// <returns>This method returns the string representation of the array.</returns>
public override string ToString()
{
return BitConverter.ToString(_array).Replace("-", " ");
}
/// <summary> Returns the hash code of the packet array. </summary>
public override int GetHashCode()
{
unchecked
{
var hashCode = (_array != null ? _array.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (_writer != null ? _writer.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (_reader != null ? _reader.GetHashCode() : 0);
return hashCode;
}
}
}
}
|
|
|
11/16/2012, 21:24
|
#9
|
elite*gold: 12
Join Date: Jul 2011
Posts: 8,211
Received Thanks: 4,114
|
Quote:
Originally Posted by Danial Eugen
I rewrote your class using Binary Reader\Writer but i got kinda screwed problem that the write string method adds white spaces to the value
Here is the class without the use of pointers [still non complete]
|
Why are you using the old version that I didn't even release here? Use the version from this thread. And with the string method, it's supposed to write white space. It clears the previous value out from the packet so it doesn't get corrupted (hence why I ask for the maximum string length).
EDIT: Oh, I see. You just severely edited it to make it look like the one in the base I gave out (which is completely managed). I would highly recommend you don't do that. My writer is much more efficient than that.
|
|
|
11/16/2012, 21:39
|
#10
|
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
|
Quote:
Originally Posted by Fаng
Why are you using the old version that I didn't even release here? Use the version from this thread. And with the string method, it's supposed to write white space. It clears the previous value out from the packet so it doesn't get corrupted (hence why I ask for the maximum string length).
|
Is that your old one ?
This one i just wrote myself depending on your class layout...
|
|
|
11/16/2012, 21:41
|
#11
|
elite*gold: 12
Join Date: Jul 2011
Posts: 8,211
Received Thanks: 4,114
|
You responded before I saved my edit.
"Oh, I see. You just severely edited it to make it look like the one in the base I gave out (which is completely managed). I would highly recommend you don't do that. My writer is much more efficient than that."
I recommend you don't do what you're doing. If you want sequential packet construction, use a struct and pointers. Besides, how are you going to write over fields when you need to later in processing with that? You can't specify offsets to write to.
|
|
|
11/16/2012, 21:44
|
#12
|
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
|
Quote:
Originally Posted by Fаng
You responded before I saved my edit.
"Oh, I see. You just severely edited it to make it look like the one in the base I gave out (which is completely managed). I would highly recommend you don't do that. My writer is much more efficient than that."
I recommend you don't do what you're doing. If you want sequential packet construction, use a struct and pointers. Besides, how are you going to write over fields when you need to later in processing with that? You can't specify offsets to write to.
|
I don't know about the base you are talking about i was editing your class without any background to make it looks like. Also about the offset i just finished creating a Seek function [that will move the writing\reading position to the specified one] but i wonder why you are saying that Pointers are more efficient than Binary Writer\Reader ?
|
|
|
11/16/2012, 23:43
|
#13
|
elite*gold: 12
Join Date: Jul 2011
Posts: 8,211
Received Thanks: 4,114
|
Quote:
Originally Posted by Danial Eugen
I don't know about the base you are talking about i was editing your class without any background to make it looks like. Also about the offset i just finished creating a Seek function [that will move the writing\reading position to the specified one] but i wonder why you are saying that Pointers are more efficient than Binary Writer\Reader ?
|
Well.... let's think about this. There's my method which just reads from a memory location using a pointer... and then we're comparing that to the binary reader (for now) defined under the .NET framework. The binary reader works by first encoding the stream its handling (already less efficient than just accepting the byte array for my constructor). Then, (since you're asking about the method I use vs. their method), their method calls on the memory stream's readInt32 method which: (1) increments the position it's at using a temporary integer, comparison, and assignment (less efficient than my checking), and (2) uses an algorithm to get the integer from the buffer (less efficient than just getting the pointer of the byte array and getting the value at the address). So yes, I'm prepared to say that my packet writer (which was designed for packet writing and reading) is more efficient than a binary writer (which was designed for stream writing).
|
|
|
11/16/2012, 23:50
|
#14
|
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
|
Quote:
Originally Posted by Fаng
Well.... let's think about this. There's my method which just reads from a memory location using a pointer... and then we're comparing that to the binary reader (for now) defined under the .NET framework. The binary reader works by first encoding the stream its handling (already less efficient than just accepting the byte array for my constructor). Then, (since you're asking about the method I use vs. their method), their method calls on the memory stream's readInt32 method which: (1) increments the position it's at using a temporary integer, comparison, and assignment (less efficient than my checking), and (2) uses an algorithm to get the integer from the buffer (less efficient than just getting the pointer of the byte array and getting the value at the address). So yes, I'm prepared to say that my packet writer (which was designed for packet writing and reading) is more efficient than a binary writer (which was designed for stream writing).
|
Well seems legit! you persuaded me . so you are speaking about speed too...
Could you mention the drawbacks you consider in this PacketLiberary you posted so i can have the time fixing them ? or\and the things that it needs {from your point of view}
|
|
|
11/17/2012, 00:12
|
#15
|
elite*gold: 12
Join Date: Jul 2011
Posts: 8,211
Received Thanks: 4,114
|
Quote:
Originally Posted by Danial Eugen
Well seems legit! you persuaded me . so you are speaking about speed too...
Could you mention the drawbacks you consider in this PacketLiberary you posted so i can have the time fixing them ? or\and the things that it needs {from your point of view}
|
Well, I disagree with this method of writing packets. I use structs and pointers to write and handle my packets. If you like this style of writing packets though (I have to admit, it makes the concept a lot easier to understand at first), then there's no problem with that.
Answering your question though, things that can be improved... There's a lot. You could manage the memory instead of using a managed byte array (however, that's too much for something like this). I would just leave it as it is really. You could add a few methods here and there if you'd like. Make better get hash and string methods and such. It's really up to you. Here's a method you can add if you'd like (as an example):
Code:
using System.Drawing;
Code:
/// <summary> This method returns a color from the packet at the specified offset. </summary>
/// <param name="offset">The position at which the reader will read from.</param>
/// <returns>The color read from the packet at the specified offset.</returns>
public Color ReadColor(int offset)
{
// Error check the length:
if (offset + 4 > _array.Length)
throw new IndexOutOfRangeException("Attempted to read out of the bounds of the packet array.");
// Read the value:
fixed (byte* ptr = _array)
return *(Color*)(ptr + offset);
}
Code:
/// <summary> This method writes a color to the packet structure. </summary>
/// <param name="value">The value being written to the packet.</param>
/// <param name="offset">The position where the value will be written to.</param>
public void WriteColor(Color value, int offset)
{
// Error check the length:
if (offset + 4 > _array.Length)
throw new IndexOutOfRangeException("Attempted to write out of the bounds of the packet array.");
// Write the value:
fixed (byte* ptr = _array)
*(Color*)(ptr + offset) = value;
}
|
|
|
|
|
Similar Threads
|
[Release]Flyff D3D Writer
03/23/2012 - Flyff PServer Guides & Releases - 11 Replies
Ich release hier mal einen D3D Writer für Flyff
er tut nix anderes als einen Text in Flyff in gewünschter höhe, breite und größe zu rendern.
Wer sich fragt wofür?
Mann kan es einfach nutzen um Videos Diebstahl sicher zu machen vor leuten die es für seine ausgeben oder Auf screens hinweise hinschreiben ohne großen aufwand.
VT: 2/43 DIESE SIND KEINE BACKDOORS ES SIND DIE D3D dll's Klick
|
Hmm packet writer question.
09/21/2011 - CO2 Private Server - 11 Replies
Why do everybody uses something like.
WriteByte(byte value);
WriteUInt32(uint value);
//....
When you could just do something like.
public unsafe class ConquerPacket
|
[RELEASE]API Tool Writer 1.0
07/20/2011 - Metin2 Hacks, Bots, Cheats, Exploits & Macros - 11 Replies
Heyho liebe e*pvper.
Ich wollte heute mal mein kleines Tool für das Api Tool veröffentlichen.
Ich selbst benutze es schon länger, wollte es aber mal Public machen, da es doch viel schneller ist, als wenn man per Hand schreiben würde (hilfreich wenn man z.B. schnell die GM Rechte ausschalten möchte).
Die Version 1.0 enthält nur alle wichtigen "Befehle".
http://img233.imageshack.us/img233/4369/writer12. jpg
‪API Tool Writer‬‏ - YouTube
Virusscan
|
Simple Packet based Shaiyabot Beta
05/19/2010 - Shaiya Hacks, Bots, Cheats & Exploits - 0 Replies
removed
|
Simple packet bot/app/tool?
01/28/2009 - Silkroad Online - 0 Replies
I have minimal-basic programming experience, what i am wanting to do is set up a char (preferably clientless) that searched the stall network (weapons 9 degrees) for items suitable to rondo (eg if 85 + Blue and price < 5.6m then buy)
How would i go about doing this? I presume i would need to do something with edx33/sr33? Is that even plausible or possible? Or is there another way to do this?
|
All times are GMT +2. The time now is 01:00.
|
|