|
||
|
|
#1 (permalink) |
|
Newbie
Join Date: Sep 2006
Age: 20
Posts: 11
|
OK, so I'm trying to understand the UO protocol. I've found several pages describing the packets that make up the protocol, amongst others;
- POLServer.com UO Packets Site - Home - Category:UO Protocol - Wolfpack Wiki - Ultima Online Protocol The problem that all these pages have in common is that none of them describe the order in which the packets are sent. If anyone could give me a brief overview, that would be very much appreciated! I've come as far as to intercept the client's seed packet and login packet (0x80), and now I'm wondering what packet to send in response. It seems that RunUO is sending the Game Server List packet (0xA8) for a successful login, and the Login Failed packet (0x82) for failed login. Sending the Login Failed packet for a failed login works out perfectly for me - the messagebox is displayed in the client with the correct failure message. However, no matter what I do, I just cannot get the Server List packet to work! :\ If anyone could take a look at my code and spot any obvious flaws in the way I'm building my Server List packet, I'd greatly appreciate it! Code:
if (Database.DoesAccountPassExist(AccountPwd))
{
using (AuthPacketOut OutPacket = new AuthPacketOut(AuthServerOpCode.ACCOUNT_LOGIN_OK))
{
OutPacket.Write((byte)0x5D); //Unknown
OutPacket.Write((ushort)RealmServerManager.Realms.Count);
for (int i = 0; i < RealmServerManager.Realms.Count; i++)
{
ServerInfo Realm = RealmServerManager.Realms[i];
OutPacket.Write((ushort)i);
OutPacket.WriteAsciiFixed(Realm.Name, 32);
OutPacket.Write((byte)Realm.FullPercent);
OutPacket.Write((sbyte)Realm.TimeZone);
OutPacket.Write((int)BitConverter.ToInt32(Realm.Address.Address.GetAddressBytes(), 0));
}
OutPacket.BaseStream.Position = 1;
OutPacket.Write((ushort)OutPacket.Length);
Client.Send(OutPacket);
if (Globals.IsDebugEnabled)
Console.WriteLine("Login OK - sent packet!\n");
}
}
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using WowServ.Cryptography;
namespace WowServ.Network
{
public class PacketOut : BinaryWriter
{
PacketID m_ID;
public PacketOut(PacketID ID)
: base(new MemoryStream())
{
m_ID = ID;
}
/// <summary>
/// Writes a number of 0x00 byte values to the underlying stream.
/// </summary>
public void Fill(int length)
{
if (Position == Length)
{
this.BaseStream.SetLength(Length + length);
Seek(0, SeekOrigin.End);
}
else
Write(new byte[length], 0, length);
}
/// <summary>
/// Writes a fixed-length ASCII-encoded string value to the underlying stream. To fit (size), the string content is either truncated or padded with null characters.
/// </summary>
public void WriteAsciiFixed(string value, int size)
{
if (value == null)
{
Console.WriteLine("Network: Attempted to WriteAsciiFixed() with null value\n");
value = String.Empty;
}
byte[] buffer = Encoding.ASCII.GetBytes(value);
if (buffer.Length >= size)
Write(buffer, 0, size);
else
{
Write(buffer, 0, buffer.Length);
Fill(size - buffer.Length);
}
}
/// <summary>
/// Writes a C-style string to the stream
/// </summary>
/// <param name="str">String to write</param>
public virtual void WriteCString(string str)
{
Write(Encoding.ASCII.GetBytes(str));
Write('\0');
}
/// <summary>
/// Writes a BigInteger to the stream
/// </summary>
/// <param name="bigInt">BigInteger to write</param>
public virtual void WriteBigInt(BigInteger bigInt)
{
byte[] data = bigInt.GetBytes();
base.Write(data);
}
/// <summary>
/// Writes a BigInteger to the stream
/// </summary>
/// <param name="bigInt">BigInteger to write</param>
/// <param name="length">maximum numbers of bytes to write for th BigInteger</param>
public virtual void WriteBigInt(BigInteger bigInt, int length)
{
byte[] data = bigInt.GetBytes(length);
base.Write(data);
}
/// <summary>
/// Writes a BigInteger to the stream, while writing the length before it
/// </summary>
/// <param name="bigInt">BigInteger to write</param>
public virtual void WriteBigIntLength(BigInteger bigInt)
{
byte[] data = bigInt.GetBytes();
base.Write((byte)data.Length);
base.Write(data);
}
/// <summary>
/// Writes a BigInteger to the stream, while writing the length before it
/// </summary>
/// <param name="bigInt">BigInteger to write</param>
/// <param name="length">maximum numbers of bytes to write for th BigInteger</param>
public virtual void WriteBigIntLength(BigInteger bigInt, int length)
{
byte[] data = bigInt.GetBytes(length);
base.Write((byte)length);
base.Write(data);
}
/// <summary>
/// Writes a short to the stream
/// </summary>
/// <param name="val">the value to write</param>
public virtual void WriteShort(int val)
{
Write((short)val);
}
/// <summary>
/// Writes a short to the stream
/// </summary>
/// <param name="val">the value to write</param>
public virtual void WriteShort(uint val)
{
Write((short)val);
}
/// <summary>
/// Writes the supplied value to the stream for a specified number of bytes
/// </summary>
/// <param name="val">Value to write</param>
/// <param name="num">Number of bytes to write</param>
public virtual void Fill(byte val, int num)
{
for (int i = 0; i < num; ++i)
{
Write((byte)val);
}
}
/// <summary>
/// Fetches all the data in this Packet's stream
/// and returns them as a byte array for sending.
/// Should NOT be called before ALL data is written
/// to the packet!!
/// </summary>
/// <returns>A byte array of the packet's data.</returns>
public byte[] GetBytes()
{
MemoryStream MemStream;
MemStream = (MemoryStream)base.BaseStream;
return MemStream.ToArray();
}
public int Position
{
get { return (int)base.BaseStream.Position; }
set { base.BaseStream.Position = value; }
}
public int Length
{
get { return (int)base.BaseStream.Length; }
}
public UInt16 LengthUInt16
{
get { return (UInt16)base.BaseStream.Length; }
}
}
}
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WowServ.Network;
namespace ServeUO.Network
{
public class AuthPacketOut : PacketOut
{
public AuthPacketOut(AuthServerOpCode OpCode)
: base(new PacketID(OpCode))
{
Write((byte)OpCode);
}
public AuthPacketOut(RealmAuthProofErrorCodes OpCode)
: base(new PacketID(IDType.Authentication, (byte)OpCode))
{
}
}
}
Thanks in advance! PS: Sorry to mods if this was in the wrong forum section. Didn't quite know where to put this... |
|
|
|
|
|
#3 (permalink) |
|
Newbie
Join Date: Sep 2006
Age: 20
Posts: 11
|
Thanks, that turned out to be very informative actually!
According to the logging I did with a program called UOLog, the packet coming from the server at this point in the login process is indeed the Server List packet. However, with one server in the list, the packet I logged was at 46 bytes (coming from one of the Razor servers), and the one I'm sending is only 44 bytes! I can't for the life of me figure out why, however I changed this: Code:
OutPacket.Write((int)BitConverter.ToInt32(Realm.Address.Address.GetAddressBytes(), 0)); But what? Thanks in advance! Edit - Log: Code:
This log was recorded with Folko's UOLog. Using client 4.0.8a T2A. 00:26:42.632 Client -> Server: 0x80 (AuthRequest), frequ: 1, len: 0x3E 0000: 80 41 66 72 30 00 00 00 00 00 00 00 00 00 00 00 ->.Afr0........... 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70 ->...............p 0020: 72 69 6E 73 00 00 00 00 00 00 00 00 00 00 00 00 ->rins............ 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 5D ->.............] 00:26:43.198 Server -> Client: 0xA8 (SendShards), frequ: 1, len: 0x2E 0000: A8 2E 00 5D 00 01 00 00 55 4F 47 61 6D 65 72 73 ->...]....UOGamers 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0020: 00 00 00 00 00 00 00 00 00 FA F0 25 7E 4B ->...........%~K 00:26:43.200 Client -> Server: 0xD9 (Unknown), frequ: 1, len: 0x10C 0000: D9 02 47 94 B2 45 00 00 00 06 00 00 00 00 00 00 ->..G..E.......... 0010: 17 70 02 00 00 00 06 00 00 00 0F 00 00 07 CF 02 ->.p.............. 0020: 00 00 08 00 00 00 05 00 00 00 04 00 00 00 00 20 ->............... 0030: 00 09 00 00 4E 00 56 00 49 00 44 00 49 00 41 00 ->....N.V.I.D.I.A. 0040: 20 00 47 00 65 00 46 00 6F 00 72 00 63 00 65 00 -> .G.e.F.o.r.c.e. 0050: 20 00 38 00 36 00 30 00 30 00 20 00 47 00 54 00 -> .8.6.0.0. .G.T. 0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 00B0: 00 00 00 00 00 00 10 DE 00 00 04 02 00 00 00 F8 ->................ 00C0: 0A 02 06 10 6E 00 6F 00 72 00 00 00 00 00 00 00 ->....n.o.r....... 00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0100: 00 00 00 00 00 00 00 00 00 00 00 00 ->............ 00:27:32.30 Client -> Server: 0xA0 (SelectShard), frequ: 1, len: 0x03 0000: A0 00 00 ->... 00:27:32.224 Server -> Client: 0x8C (Relay), frequ: 1, len: 0x0B 0000: 8C 4B 7E 25 F0 0A 21 C4 D4 C8 9C ->.K~%..!.... 00:27:32.419 Client -> Server: 0x91 (RelayAuth), frequ: 1, len: 0x41 0000: 91 C4 D4 C8 9C 41 66 72 30 00 00 00 00 00 00 00 ->.....Afr0....... 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0020: 00 00 00 70 72 69 6E 73 00 00 00 00 00 00 00 00 ->...prins........ 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0040: 00 ->. 00:27:32.998 Server -> Client: 0xA9 (SendCharsAndCities), frequ: 1, len: 0x3AB 0000: A9 AB 03 05 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0130: 0A 00 59 65 77 00 00 00 00 00 00 00 00 00 00 00 ->..Yew........... 0140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0150: 00 54 68 65 20 45 6D 70 61 74 68 20 41 62 62 65 ->.The Empath Abbe 0160: 79 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->y............... 0170: 01 4D 69 6E 6F 63 00 00 00 00 00 00 00 00 00 00 ->.Minoc.......... 0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0190: 54 68 65 20 42 61 72 6E 61 63 6C 65 00 00 00 00 ->The Barnacle.... 01A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ->................ 01B0: 42 72 69 74 61 69 6E 00 00 00 00 00 00 00 00 00 ->Britain......... 01C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 53 ->...............S 01D0: 77 65 65 74 20 44 72 65 61 6D 73 20 49 6E 6E 00 ->weet Dreams Inn. 01E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 4D ->...............M 01F0: 6F 6F 6E 67 6C 6F 77 00 00 00 00 00 00 00 00 00 ->oonglow......... 0200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 54 68 ->..............Th 0210: 65 20 53 63 68 6F 6C 61 72 73 20 49 6E 6E 00 00 ->e Scholars Inn.. 0220: 00 00 00 00 00 00 00 00 00 00 00 00 00 04 54 72 ->..............Tr 0230: 69 6E 73 69 63 00 00 00 00 00 00 00 00 00 00 00 ->insic........... 0240: 00 00 00 00 00 00 00 00 00 00 00 00 00 54 68 65 ->.............The 0250: 20 54 72 61 76 65 6C 65 72 27 73 20 49 6E 6E 00 -> Traveler's Inn. 0260: 00 00 00 00 00 00 00 00 00 00 00 00 05 4D 61 67 ->.............Mag 0270: 69 6E 63 69 61 00 00 00 00 00 00 00 00 00 00 00 ->incia........... 0280: 00 00 00 00 00 00 00 00 00 00 00 00 54 68 65 20 ->............The 0290: 47 72 65 61 74 20 48 6F 72 6E 73 20 54 61 76 65 ->Great Horns Tave 02A0: 72 6E 00 00 00 00 00 00 00 00 00 06 4A 68 65 6C ->rn..........Jhel 02B0: 6F 6D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->om.............. 02C0: 00 00 00 00 00 00 00 00 00 00 00 54 68 65 20 4D ->...........The M 02D0: 65 72 63 65 6E 61 72 79 20 49 6E 6E 00 00 00 00 ->ercenary Inn.... 02E0: 00 00 00 00 00 00 00 00 00 00 07 53 6B 61 72 61 ->...........Skara 02F0: 20 42 72 61 65 00 00 00 00 00 00 00 00 00 00 00 -> Brae........... 0300: 00 00 00 00 00 00 00 00 00 00 54 68 65 20 46 61 ->..........The Fa 0310: 6C 63 6F 6E 65 72 27 73 20 49 6E 6E 00 00 00 00 ->lconer's Inn.... 0320: 00 00 00 00 00 00 00 00 00 08 56 65 73 70 65 72 ->..........Vesper 0330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0340: 00 00 00 00 00 00 00 00 00 54 68 65 20 49 72 6F ->.........The Iro 0350: 6E 77 6F 6F 64 20 49 6E 6E 00 00 00 00 00 00 00 ->nwood Inn....... 0360: 00 00 00 00 00 00 00 00 09 48 61 76 65 6E 00 00 ->.........Haven.. 0370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ->................ 0380: 00 00 00 00 00 00 00 00 42 75 63 6B 6C 65 72 27 ->........Buckler' 0390: 73 20 48 69 64 65 61 77 61 79 00 00 00 00 00 00 ->s Hideaway...... 03A0: 00 00 00 00 00 00 00 00 00 00 08 ->........... 00:28:33.76 Client -> Server: 0x73 (PingPong), frequ: 1, len: 0x02 0000: 73 00 ->s. 00:28:33.257 Server -> Client: 0x73 (PingPong), frequ: 2, len: 0x02 0000: 73 00 ->s. Packet statistics Client->Server: 80: 1 times, 62 bytes (~62 bytes per packet) //AuthRequest 91: 1 times, 65 bytes (~65 bytes per packet) //RelayAuth A0: 1 times, 3 bytes (~3 bytes per packet) //SelectShard D9: 1 times, 268 bytes (~268 bytes per packet) //Unknown Server->Client: 8C: 1 times, 11 bytes (~11 bytes per packet) //Relay A8: 1 times, 46 bytes (~46 bytes per packet) //SendShards A9: 1 times, 939 bytes (~939 bytes per packet) //SendCharsAndCities Bidirectional packets: 73: 2 times, 4 bytes (~2 bytes per packet) //PingPong End of statistics Bytes sent: 400. Bytes received: 998. Total 1398 bytes. Client was active for 1 minutes That results in 0.02 kb/s. |
|
|
|
|
|
#4 (permalink) |
|
Newbie
Join Date: Nov 2007
Age: 22
Posts: 69
|
it looks like your forgetting to add the packet length. because its a dynamic size packet you need to add a ushort after the packet id that will tell the client the packet size. when you create the packet you should write the packet id and if it is a dynamic size packet you should write two extra byte, then when you're compiling the packet you want to Seek(1, SeekOrgin.Begin) and write the packet lenght.
Take a look at RunUOs Packet class if you're having trouble. |
|
|
|
|
|
#5 (permalink) |
|
Newbie
Join Date: Sep 2006
Age: 20
Posts: 11
|
I'd advise you to take your password out of the packet log, Afr0.
Edit: Hm? I didn't post this? Who did? A mod? Anyways, thanks for warning me, but that account was created yesterday on server with auto account creation on, and I've no use for it other than for testing purposes. Last edited by Afr0man; 01-31-2008 at 10:12 AM. |
|
|
|
|
|
#6 (permalink) |
|
Newbie
Join Date: Sep 2006
Age: 20
Posts: 11
|
Thanks for your response Chase.XNA!
I now did like this to pad out the packet length: Code:
if (Database.DoesAccountPassExist(AccountPwd))
{
using (AuthPacketOut OutPacket = new AuthPacketOut(AuthServerOpCode.ACCOUNT_LOGIN_OK))
{
OutPacket.Write((byte)0x5D); //Unknown
OutPacket.Write((ushort)0x00); //Packet length
OutPacket.Write((ushort)RealmServerManager.Realms.Count);
for (int i = 0; i < RealmServerManager.Realms.Count; i++)
{
ServerInfo Realm = RealmServerManager.Realms[i];
OutPacket.Write((ushort)i);
OutPacket.WriteAsciiFixed(Realm.Name, 32);
OutPacket.Write((byte)Realm.FullPercent);
OutPacket.Write((sbyte)Realm.TimeZone);
OutPacket.Write((int)Realm.Address.Address.Address);
}
OutPacket.BaseStream.Position = 1;
OutPacket.Write((ushort)OutPacket.Length);
Console.WriteLine("PacketLength: " + OutPacket.Length.ToString());
Client.Send(OutPacket);
if (Globals.IsDebugEnabled)
Console.WriteLine("Login OK - sent packet!n");
}
I'm going to try to experiment with RunUO's EnsurePacketLength() function, but in the meantime I'd appreciate any further help on this issue. Thanks! |
|
|
|
|
|
#7 (permalink) | |
|
Master of the Internet
|
Quote:
__________________
![]() Now open - uo15.net - The best in Publish 15 emulation |
|
|
|
|
|
|
#8 (permalink) |
|
Newbie
Join Date: Sep 2006
Age: 20
Posts: 11
|
Aaah I need help! Aren't there any RunUO devs on these forums somewhere?
I tried wrapping BinaryWriter.BaseStream.SetLength() into a function called EnsureCapacity(), to ensure that the packet was 46 bytes (even though it already was, since I padded out the packet length). Still nothing! :\ BTW, are all members on this forum as 'helpful' as Radwen? I strongly advice staying away from the 'Ask Radwen' thread for answers to technical issues. |
|
|
|
|
|
#10 (permalink) |
|
Newbie
Join Date: Sep 2006
Age: 20
Posts: 11
|
PacketOut.cs:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using WowServ.Cryptography;
namespace WowServ.Network
{
public class PacketOut : BinaryWriter
{
PacketID m_ID;
public PacketOut(PacketID ID)
: base(new MemoryStream())
{
m_ID = ID;
}
/// <summary>
/// Writes a number of 0x00 byte values to the underlying stream.
/// </summary>
public void Fill(int length)
{
if (Position == Length)
{
this.BaseStream.SetLength(Length + length);
Seek(0, SeekOrigin.End);
}
else
Write(new byte[length], 0, length);
}
/// <summary>
/// Ensures that the packet's datastream is set to a given length.
/// </summary>
/// <param name="Length">The length of the stream, in bytes.</param>
public void EnsureCapacity(int Length)
{
this.BaseStream.SetLength(Length);
}
/// <summary>
/// Writes a fixed-length ASCII-encoded string value to the underlying stream. To fit (size), the string content is either truncated or padded with null characters.
/// </summary>
public void WriteAsciiFixed(string value, int size)
{
if (value == null)
{
Console.WriteLine("Network: Attempted to WriteAsciiFixed() with null valuen");
value = String.Empty;
}
byte[] buffer = Encoding.ASCII.GetBytes(value);
if (buffer.Length >= size)
Write(buffer, 0, size);
else
{
Write(buffer, 0, buffer.Length);
Fill(size - buffer.Length);
}
}
/// <summary>
/// Writes a C-style string to the stream
/// </summary>
/// <param name="str">String to write</param>
public virtual void WriteCString(string str)
{
Write(Encoding.ASCII.GetBytes(str));
Write(' ');
}
/// <summary>
/// Writes a BigInteger to the stream
/// </summary>
/// <param name="bigInt">BigInteger to write</param>
public virtual void WriteBigInt(BigInteger bigInt)
{
byte[] data = bigInt.GetBytes();
base.Write(data);
}
/// <summary>
/// Writes a BigInteger to the stream
/// </summary>
/// <param name="bigInt">BigInteger to write</param>
/// <param name="length">maximum numbers of bytes to write for th BigInteger</param>
public virtual void WriteBigInt(BigInteger bigInt, int length)
{
byte[] data = bigInt.GetBytes(length);
base.Write(data);
}
/// <summary>
/// Writes a BigInteger to the stream, while writing the length before it
/// </summary>
/// <param name="bigInt">BigInteger to write</param>
public virtual void WriteBigIntLength(BigInteger bigInt)
{
byte[] data = bigInt.GetBytes();
base.Write((byte)data.Length);
base.Write(data);
}
/// <summary>
/// Writes a BigInteger to the stream, while writing the length before it
/// </summary>
/// <param name="bigInt">BigInteger to write</param>
/// <param name="length">maximum numbers of bytes to write for th BigInteger</param>
public virtual void WriteBigIntLength(BigInteger bigInt, int length)
{
byte[] data = bigInt.GetBytes(length);
base.Write((byte)length);
base.Write(data);
}
/// <summary>
/// Writes a short to the stream
/// </summary>
/// <param name="val">the value to write</param>
public virtual void WriteShort(int val)
{
Write((short)val);
}
/// <summary>
/// Writes a short to the stream
/// </summary>
/// <param name="val">the value to write</param>
public virtual void WriteShort(uint val)
{
Write((short)val);
}
/// <summary>
/// Writes the supplied value to the stream for a specified number of bytes
/// </summary>
/// <param name="val">Value to write</param>
/// <param name="num">Number of bytes to write</param>
public virtual void Fill(byte val, int num)
{
for (int i = 0; i < num; ++i)
{
Write((byte)val);
}
}
/// <summary>
/// Fetches all the data in this Packet's stream
/// and returns them as a byte array for sending.
/// Should NOT be called before ALL data is written
/// to the packet!!
/// </summary>
/// <returns>A byte array of the packet's data.</returns>
public byte[] GetBytes()
{
MemoryStream MemStream;
MemStream = (MemoryStream)base.BaseStream;
return MemStream.ToArray();
}
public int Position
{
get { return (int)base.BaseStream.Position; }
set { base.BaseStream.Position = value; }
}
public int Length
{
get { return (int)base.BaseStream.Length; }
}
public UInt16 LengthUInt16
{
get { return (UInt16)base.BaseStream.Length; }
}
}
}
Code:
private static void SendLoginOKPacket(AuthClient Client)
{
using (AuthPacketOut OutPacket = new AuthPacketOut(AuthServerOpCode.ACCOUNT_LOGIN_OK))
{
OutPacket.EnsureCapacity(6 + (RealmServerManager.Realms.Count * 40));
OutPacket.Write((ushort)0x00); //Packet length
OutPacket.Write((byte)0x5D); //Unknown
OutPacket.Write((ushort)RealmServerManager.Realms.Count);
for (int i = 0; i < RealmServerManager.Realms.Count; i++)
{
ServerInfo Realm = RealmServerManager.Realms[i];
OutPacket.Write((ushort)i);
OutPacket.WriteAsciiFixed(Realm.Name, 32);
OutPacket.Write((byte)Realm.FullPercent);
OutPacket.Write((sbyte)Realm.TimeZone);
OutPacket.Write((int)Globals.GetAddressValue(Realm.Address.Address));
}
OutPacket.BaseStream.Position = 0;
OutPacket.Write((ushort)OutPacket.Length);
Console.WriteLine("PacketLength: " + OutPacket.Length.ToString());
Client.Send(OutPacket);
if (Globals.IsDebugEnabled)
Console.WriteLine("Login OK - sent packet!n");
}
}
|
|
|
|
|
|
#11 (permalink) |
|
Newbie
Join Date: Nov 2007
Age: 22
Posts: 69
|
OutPacket.BaseStream.Position = 0;
OutPacket.Write((ushort)OutPacket.Length); isn't right, you're overwriting the packet id, it should be "OutPacket.BaseStream.Position = 1;." It would be better to write the length in the EnsureCapacity method. Also, Im not sure if you can use a BinaryWriter, I've never tried it but you might want to compare the bytes of your packet to the bytes of a packet you logged from the EA client. **edit daat99: removed irrelevant and unhelpful comment that wasn't supposed to be here... If you want to make comments like that in the future please provide some helpful insight with them.** Last edited by daat99; 02-05-2008 at 11:37 PM. |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|