Помощь - Поиск - Пользователи - Календарь
Полная версия: Логирование пакетного обмена
UoKit.com Форумы > Ultima Online : Dev > Работа с клиентом UO
Wap
Не подскажете, чем можно логировать пакетный обмен в клиенте так, чтобы при крэше клиента все последние пакеты были сохранены?
Насколько я слышал, SpyUO и Razor падают вместе с клиентом...
Juzzver
Самим же сервером и можно. На RunUO это выглядит следующим образом:

Цитата
Client: 195.182.194.104: Unhandled packet 0xF4
0 1 2 3 4 5 6 7 8 9 A B C D E F
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
0000 F4 01 3A 07 00 1C 00 00 00 00 00 00 00 66 72 65 ..:..........fre
0010 65 6D 61 6E 30 34 00 35 01 F0 CC 36 5F 09 00 00 eman04.5...6_...
0020 00 0F 00 00 00 00 00 00 00 A8 66 4B 5F 4C 65 67 ..........fK_Leg
0030 65 6E 64 00 00 00 00 00 00 00 00 00 00 00 00 00 end.............
0040 00 00 00 00 00 00 00 00 00 00 00 00 00 31 36 39 .............169
0050 2E 32 35 34 2E 32 35 32 2E 32 30 31 00 01 57 C0 .254.252.201..W.
0060 C0 00 00 05 63 6C 69 65 6E 74 2E 65 78 65 00 00 ....client.exe..
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 43 52 41 53 48 00 00 00 ........CRASH...
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 05 B0 99 ................
0130 2B 02 00 5A 93 66 F9 63 00 40 +..Z.f.c.@


Скрипт как пример, может подскажет:

Исходный код
/***************************************************************************
* PacketReader.cs
* -------------------
* begin : May 1, 2002
* copyright : © The RunUO Software Team
* email : info@runuo.com
*
* $Id: PacketReader.cs 4 2006-06-15 04:28:39Z mark $
*
***************************************************************************/

/***************************************************************************
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
***************************************************************************/

using System;
using System.Text;
using System.IO;

namespace Server.Network
{
public class PacketReader
{
private byte[] m_Data;
private int m_Size;
private int m_Index;

public PacketReader( byte[] data, int size, bool fixedSize )
{
m_Data = data;
m_Size = size;
m_Index = fixedSize ? 1 : 3;
}

public byte[] Buffer
{
get
{
return m_Data;
}
}

public int Size
{
get
{
return m_Size;
}
}

public void Trace( NetState state )
{
try
{
using ( StreamWriter sw = new StreamWriter( "Packets.log", true ) )
{
byte[] buffer = m_Data;

if ( buffer.Length > 0 )
sw.WriteLine( "Client: {0}: Unhandled packet 0x{1:X2}", state, buffer[0] );

using ( MemoryStream ms = new MemoryStream( buffer ) )
Utility.FormatBuffer( sw, ms, buffer.Length );

sw.WriteLine();
sw.WriteLine();
}
}
catch
{
}
}

public int Seek( int offset, SeekOrigin origin )
{
switch ( origin )
{
case SeekOrigin.Begin: m_Index = offset; break;
case SeekOrigin.Current: m_Index += offset; break;
case SeekOrigin.End: m_Index = m_Size - offset; break;
}

return m_Index;
}

public int ReadInt32()
{
if ( (m_Index + 4) > m_Size )
return 0;

return (m_Data[m_Index++] << 24)
| (m_Data[m_Index++] << 16)
| (m_Data[m_Index++] << 8)
| m_Data[m_Index++];
}

public short ReadInt16()
{
if ( (m_Index + 2) > m_Size )
return 0;

return (short)((m_Data[m_Index++] << 8) | m_Data[m_Index++]);
}

public byte ReadByte()
{
if ( (m_Index + 1) > m_Size )
return 0;

return m_Data[m_Index++];
}

public uint ReadUInt32()
{
if ( (m_Index + 4) > m_Size )
return 0;

return (uint)((m_Data[m_Index++] << 24) | (m_Data[m_Index++] << 16) | (m_Data[m_Index++] << 8) | m_Data[m_Index++]);
}

public ushort ReadUInt16()
{
if ( (m_Index + 2) > m_Size )
return 0;

return (ushort)((m_Data[m_Index++] << 8) | m_Data[m_Index++]);
}

public sbyte ReadSByte()
{
if ( (m_Index + 1) > m_Size )
return 0;

return (sbyte)m_Data[m_Index++];
}

public bool ReadBoolean()
{
if ( (m_Index + 1) > m_Size )
return false;

return ( m_Data[m_Index++] != 0 );
}

public string ReadUnicodeStringLE()
{
StringBuilder sb = new StringBuilder();

int c;

while ( (m_Index + 1) < m_Size && (c = (m_Data[m_Index++] | (m_Data[m_Index++] << 8))) != 0 )
sb.Append( (char)c );

return sb.ToString();
}

public string ReadUnicodeStringLESafe( int fixedLength )
{
int bound = m_Index + (fixedLength << 1);
int end = bound;

if ( bound > m_Size )
bound = m_Size;

StringBuilder sb = new StringBuilder();

int c;

while ( (m_Index + 1) < bound && (c = (m_Data[m_Index++] | (m_Data[m_Index++] << 8))) != 0 )
{
if ( IsSafeChar( c ) )
sb.Append( (char)c );
}

m_Index = end;

return sb.ToString();
}

public string ReadUnicodeStringLESafe()
{
StringBuilder sb = new StringBuilder();

int c;

while ( (m_Index + 1) < m_Size && (c = (m_Data[m_Index++] | (m_Data[m_Index++] << 8))) != 0 )
{
if ( IsSafeChar( c ) )
sb.Append( (char)c );
}

return sb.ToString();
}

public string ReadUnicodeStringSafe()
{
StringBuilder sb = new StringBuilder();

int c;

while ( (m_Index + 1) < m_Size && (c = ((m_Data[m_Index++] << 8) | m_Data[m_Index++])) != 0 )
{
if ( IsSafeChar( c ) )
sb.Append( (char)c );
}

return sb.ToString();
}

public string ReadUnicodeString()
{
StringBuilder sb = new StringBuilder();

int c;

while ( (m_Index + 1) < m_Size && (c = ((m_Data[m_Index++] << 8) | m_Data[m_Index++])) != 0 )
sb.Append( (char)c );

return sb.ToString();
}

public bool IsSafeChar( int c )
{
return ( c >= 0x20 && c < 0xFFFE );
}

public string ReadUTF8StringSafe( int fixedLength )
{
if ( m_Index >= m_Size )
{
m_Index += fixedLength;
return String.Empty;
}

int bound = m_Index + fixedLength;
//int end = bound;

if ( bound > m_Size )
bound = m_Size;

int count = 0;
int index = m_Index;
int start = m_Index;

while ( index < bound && m_Data[index++] != 0 )
++count;

index = 0;

byte[] buffer = new byte[count];
int value = 0;

while ( m_Index < bound && (value = m_Data[m_Index++]) != 0 )
buffer[index++] = (byte)value;

string s = Utility.UTF8.GetString( buffer );

bool isSafe = true;

for ( int i = 0; isSafe && i < s.Length; ++i )
isSafe = IsSafeChar( (int) s[i] );

m_Index = start + fixedLength;

if ( isSafe )
return s;

StringBuilder sb = new StringBuilder( s.Length );

for ( int i = 0; i < s.Length; ++i )
if ( IsSafeChar( (int) s[i] ) )
sb.Append( s[i] );

return sb.ToString();
}

public string ReadUTF8StringSafe()
{
if ( m_Index >= m_Size )
return String.Empty;

int count = 0;
int index = m_Index;

while ( index < m_Size && m_Data[index++] != 0 )
++count;

index = 0;

byte[] buffer = new byte[count];
int value = 0;

while ( m_Index < m_Size && (value = m_Data[m_Index++]) != 0 )
buffer[index++] = (byte)value;

string s = Utility.UTF8.GetString( buffer );

bool isSafe = true;

for ( int i = 0; isSafe && i < s.Length; ++i )
isSafe = IsSafeChar( (int) s[i] );

if ( isSafe )
return s;

StringBuilder sb = new StringBuilder( s.Length );

for ( int i = 0; i < s.Length; ++i )
{
if ( IsSafeChar( (int) s[i] ) )
sb.Append( s[i] );
}

return sb.ToString();
}

public string ReadUTF8String()
{
if ( m_Index >= m_Size )
return String.Empty;

int count = 0;
int index = m_Index;

while ( index < m_Size && m_Data[index++] != 0 )
++count;

index = 0;

byte[] buffer = new byte[count];
int value = 0;

while ( m_Index < m_Size && (value = m_Data[m_Index++]) != 0 )
buffer[index++] = (byte)value;

return Utility.UTF8.GetString( buffer );
}

public string ReadString()
{
StringBuilder sb = new StringBuilder();

int c;

while ( m_Index < m_Size && (c = m_Data[m_Index++]) != 0 )
sb.Append( (char)c );

return sb.ToString();
}

public string ReadStringSafe()
{
StringBuilder sb = new StringBuilder();

int c;

while ( m_Index < m_Size && (c = m_Data[m_Index++]) != 0 )
{
if ( IsSafeChar( c ) )
sb.Append( (char)c );
}

return sb.ToString();
}

public string ReadUnicodeStringSafe( int fixedLength )
{
int bound = m_Index + (fixedLength << 1);
int end = bound;

if ( bound > m_Size )
bound = m_Size;

StringBuilder sb = new StringBuilder();

int c;

while ( (m_Index + 1) < bound && (c = ((m_Data[m_Index++] << 8) | m_Data[m_Index++])) != 0 )
{
if ( IsSafeChar( c ) )
sb.Append( (char)c );
}

m_Index = end;

return sb.ToString();
}

public string ReadUnicodeString( int fixedLength )
{
int bound = m_Index + (fixedLength << 1);
int end = bound;

if ( bound > m_Size )
bound = m_Size;

StringBuilder sb = new StringBuilder();

int c;

while ( (m_Index + 1) < bound && (c = ((m_Data[m_Index++] << 8) | m_Data[m_Index++])) != 0 )
sb.Append( (char)c );

m_Index = end;

return sb.ToString();
}

public string ReadStringSafe( int fixedLength )
{
int bound = m_Index + fixedLength;
int end = bound;

if ( bound > m_Size )
bound = m_Size;

StringBuilder sb = new StringBuilder();

int c;

while ( m_Index < bound && (c = m_Data[m_Index++]) != 0 )
{
if ( IsSafeChar( c ) )
sb.Append( (char)c );
}

m_Index = end;

return sb.ToString();
}

public string ReadString( int fixedLength )
{
int bound = m_Index + fixedLength;
int end = bound;

if ( bound > m_Size )
bound = m_Size;

StringBuilder sb = new StringBuilder();

int c;

while ( m_Index < bound && (c = m_Data[m_Index++]) != 0 )
sb.Append( (char)c );

m_Index = end;

return sb.ToString();
}
}
}


Razor ествественно вылетет сразу же с клиентом, т.к. он получает привязку к окну. За SpyUO почти нечего не слышал.
StaticZ
У меня SpyUO не вылетал памоему, хотя последний вылетал даже при запуске xD... Для дока так же можно использовать uo-ext, достаточно сделать перенаправление вывода в файл. Так же можно использовать любой сниффер общего назначения (я например пользуюсь Intercepter), правда потом придется вручную ковыряться в выводе разбирая пакеты. Так же многие альтернативные клиенты радостно ведут лог пакетов, так же позже прикручу лог пакетов к моему UCS. Что касается сервера то это не очень удобно и оправданно так как он живет своей жизнью, т.е. он может продолжать слать пакеты и после "краша", что делает сложным понять какой именно пакет был последним да и SpyUO любезно парсит все пакеты, ковыряться в RAW данных это примерно тоже самое что и искать ошибку в распечатке дампа памяти....
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Русская версия Invision Power Board © 2001-2024 Invision Power Services, Inc.