|
||
|
|||||||
| Network Modifications This forum is for modifications to the networking code of RunUO |
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 (permalink) |
|
Newbie
Join Date: Sep 2006
Age: 20
Posts: 11
|
Ok, so I'm making a WoW emu using a stripped down version of the RunUO core. So far, everything's fine, however I need to figure out how on earth to read variable length packets?
This is the description for the packet I'm trying to receive: Code:
'Client Side Description:
Data Type Field Name Details
uint8 OpCode The Opcode that identifies the current packet. (CMD_AUTH_LOGON_CHALLENGE)
uint8 Error Ignored. (0x02)
uint16 Size Size of the rest of the packet excluding previous fields.
uint8[4] GameName 4 bytes containing the name of the game. ("WoW\0")
uint8[3] GameVersion 3 bytes containing the version of the game. (0x01,0x0C,0x00)
uint16 GameBuild Build Number of the Client
uint8[4] Platform Client Platform Name ("x86\0")
uint8[4] OperatingSystem Client OS Name ("Win\0")
uint8[4] Area Client Area/Localization ("enUS")
uint32 TimeZone Client Time Zone
uint8[4] ClientIP Client IP (got locally)
uint8 AccountNameLen Length of Account name. (\0) terminator excluded.
uint8[x] AccountName Account name. (\0) terminator excluded.'
I don't know if it's of any importance, but here is my PacketHandlers.cs file so far: Code:
using System;
using System.Collections.Generic;
using System.Text;
namespace LoginServer.Network
{
class PacketHandlers
{
private static PacketHandler[] m_Handlers;
static PacketHandlers()
{
m_Handlers = new PacketHandler[0x100];
//This packet seems to take 35 bytes + Accountname,
//which is of variable length. I.E I HAVE A PROBLEM! o.O
Register(0x00, 35, false, new OnPacketReceive(AuthLogon));
}
public static PacketHandler GetHandler(int PacketID)
{
return m_Handlers[PacketID];
}
public static void Register(int packetID, int length, bool ingame, OnPacketReceive onReceive)
{
m_Handlers[packetID] = new PacketHandler(packetID, length, ingame, onReceive);
}
public static void AuthLogon(NetState state, PacketReader pvSrc)
{
}
}
}
![]() Edit: D'oh! The Packethandler events are where you actually read the packet data - the size of the packet registered for a particular Packethandler doesn't actually matter when you receive the packet, because the Bytequeue class seems to take care of aqcuiring the full packet anyway, as seen in Messagepump.cs here: Code:
Console.WriteLine("Length: {0}, PacketLength: {1}", length, packetLength);
if (length >= packetLength)
{
byte[] packetBuffer;
if (BufferSize >= packetLength)
packetBuffer = m_Buffers.AcquireBuffer();
else
packetBuffer = new byte[packetLength];
packetLength = buffer.Dequeue(packetBuffer, 0, packetLength);
PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0);
handler.OnReceive(ns, r);
length = buffer.Length;
if (BufferSize >= packetLength)
m_Buffers.ReleaseBuffer(packetBuffer);
}
![]() BTW: Kudos to the devs for making the best core I have ever seen so far. The quality of it never ceases to amaze me, even when I am at a loss in times like these! Last edited by Afr0man; 03-13-2007 at 07:05 PM. |
|
|
|
|
|
#2 (permalink) |
|
Forum Newbie
Join Date: Jun 2006
Posts: 93
|
You should set length to 0 for custom length packets.
Code:
Register( 0x12, 0, true, new OnPacketReceive( TextCommand ) ); Code:
public static void TextCommand( NetState state, PacketReader pvSrc )
{
int type = pvSrc.ReadByte();
string command = pvSrc.ReadString();
Mobile m = state.Mobile;
switch ( type )
{
case 0x00: // Go
{
if ( VerifyGC( state ) )
{
try
{
string[] split = command.Split( ' ' );
int x = Utility.ToInt32( split[0] );
int y = Utility.ToInt32( split[1] );
int z;
if ( split.Length >= 3 )
z = Utility.ToInt32( split[2] );
else if ( m.Map != null )
z = m.Map.GetAverageZ( x, y );
else
z = 0;
m.Location = new Point3D( x, y, z );
}
catch
{
}
}
break;
}
case 0xC7: // Animate
{
EventSink.InvokeAnimateRequest( new AnimateRequestEventArgs( m, command ) );
break;
}
case 0x24: // Use skill
{
int skillIndex;
try{ skillIndex = Convert.ToInt32( command.Split( ' ' )[0] ); }
catch{ break; }
Skills.UseSkill( m, skillIndex );
break;
}
case 0x43: // Open spellbook
{
int booktype;
try{ booktype = Convert.ToInt32( command ); }
catch{ booktype = 1; }
EventSink.InvokeOpenSpellbookRequest( new OpenSpellbookRequestEventArgs( m, booktype ) );
break;
}
case 0x27: // Cast spell from book
{
string[] split = command.Split( ' ' );
if ( split.Length > 0 )
{
int spellID = Utility.ToInt32( split[0] ) - 1;
int serial = split.Length > 1 ? Utility.ToInt32( split[1] ) : -1;
EventSink.InvokeCastSpellRequest( new CastSpellRequestEventArgs( m, spellID, World.FindItem( serial ) ) );
}
break;
}
case 0x58: // Open door
{
EventSink.InvokeOpenDoorMacroUsed( new OpenDoorMacroEventArgs( m ) );
break;
}
case 0x56: // Cast spell from macro
{
int spellID = Utility.ToInt32( command ) - 1;
EventSink.InvokeCastSpellRequest( new CastSpellRequestEventArgs( m, spellID, null ) );
break;
}
case 0xF4: // Invoke virtues from macro
{
int virtueID = Utility.ToInt32( command ) - 1;
EventSink.InvokeVirtueMacroRequest( new VirtueMacroRequestEventArgs( m, virtueID ) );
break;
}
default:
{
Console.WriteLine( "Client: {0}: Unknown text-command type 0x{1:X2}: {2}", state, type, command );
break;
}
}
}
|
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|