Update of /cvsroot/seq/showeq/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30260/src Modified Files: Tag: pre_5_0_beta category.cpp everquest.h group.cpp group.h interface.cpp main.cpp mapcore.cpp messageshell.cpp packet.cpp packetcapture.cpp packetcapture.h packetformat.cpp packetformat.h packetfragment.cpp packetfragment.h packetinfo.cpp packetlog.cpp packetstream.cpp player.cpp spawnshell.cpp spellshell.cpp spellshell.h xmlpreferences.cpp zonemgr.cpp zonemgr.h zones.h Log Message: Support packet compression, new opcodes, and structures Index: main.cpp =================================================================== RCS file: /cvsroot/seq/showeq/src/main.cpp,v retrieving revision 1.33.6.5 retrieving revision 1.33.6.6 diff -u -d -r1.33.6.5 -r1.33.6.6 --- main.cpp 24 Sep 2004 04:25:53 -0000 1.33.6.5 +++ main.cpp 21 Feb 2005 05:56:14 -0000 1.33.6.6 @@ -4,7 +4,7 @@ * ShowEQ Distributed under GPL * http://seq.sourceforge.net/ * - * Copyright 2000-2004 by the respective ShowEQ Developers + * Copyright 2000-2005 by the respective ShowEQ Developers */ /* main.cpp is the entrypoint to ShowEQ, it parses the commandline @@ -702,7 +702,7 @@ { printf ("ShowEQ %s, released under the GPL.\n", VERSION); printf (" SINS 0.5, released under the GPL.\n"); - printf ("All ShowEQ source code is Copyright (C) 2000-2004 by the respective ShowEQ Developers\n"); + printf ("All ShowEQ source code is Copyright (C) 2000-2005 by the respective ShowEQ Developers\n"); printf ("ShowEQ comes with NO WARRANTY.\n\n"); Index: category.cpp =================================================================== RCS file: /cvsroot/seq/showeq/src/category.cpp,v retrieving revision 1.8.16.2 retrieving revision 1.8.16.3 diff -u -d -r1.8.16.2 -r1.8.16.3 --- category.cpp 7 Nov 2004 23:09:56 -0000 1.8.16.2 +++ category.cpp 21 Feb 2005 05:56:13 -0000 1.8.16.3 @@ -161,6 +161,18 @@ CategoryMgr::~CategoryMgr() { + // Clear the categories list. Since AutoDelete is off. This is manual. + if (m_categories.first()) + { + Category* deleteMe; + + while ((deleteMe = m_categories.current())) + { + m_categories.remove(); + + delete deleteMe; + } + } } const CategoryList CategoryMgr::findCategories(const QString& filterString, @@ -318,9 +330,9 @@ //seqDebug("%d: Got '%s' '%s' '%s'", i, name, filter, color); if (!name.isEmpty() && !filter.isEmpty()) { - Category* newcat = new Category(name, filter, filterout, color); + Category* newcat = new Category(name, filter, filterout, color); - m_categories.append(newcat); + m_categories.append(newcat); } } } Index: group.h =================================================================== RCS file: /cvsroot/seq/showeq/src/group.h,v retrieving revision 1.4.16.2 retrieving revision 1.4.16.3 diff -u -d -r1.4.16.2 -r1.4.16.3 --- group.h 13 Dec 2003 00:49:42 -0000 1.4.16.2 +++ group.h 21 Feb 2005 05:56:13 -0000 1.4.16.3 @@ -28,6 +28,7 @@ GroupMgr(SpawnShell* spawnShell, Player* player, QObject* parent = 0, const char* name = 0); + virtual ~GroupMgr(); const Spawn* memberByID( uint16_t id ); const Spawn* memberByName( const QString& name ); Index: packetstream.cpp =================================================================== RCS file: /cvsroot/seq/showeq/src/packetstream.cpp,v retrieving revision 1.1.6.6 retrieving revision 1.1.6.7 diff -u -d -r1.1.6.6 -r1.1.6.7 --- packetstream.cpp 9 Feb 2005 07:07:38 -0000 1.1.6.6 +++ packetstream.cpp 21 Feb 2005 05:56:14 -0000 1.1.6.7 @@ -14,8 +14,6 @@ #include "packetinfo.h" #include "diagnosticmessages.h" -#include <zlib.h> - #include <stdio.h> //---------------------------------------------------------------------- @@ -23,7 +21,7 @@ // The following defines are used to diagnose packet handling behavior // this define is used to diagnose packet processing (in processPacket mostly) -//#define PACKET_PROCESS_DIAG 3 +//#define PACKET_PROCESS_DIAG 2 // this define is used to diagnose cache handling (in processPacket mostly) //#define PACKET_CACHE_DIAG 3 @@ -31,8 +29,11 @@ // this define is used to debug packet info (in dispatchPacket mostly) //#define PACKET_INFO_DIAG 3 +// this define is used to debug packet decode info (decompression) +//#define PACKET_DECODE_DIAG 3 + // this define is used to debug sessions (request, response, disconnect) -//#define PACKET_SESSION_DIAG 2 +//#define PACKET_SESSION_DIAG 3 // diagnose structure size changes #define PACKET_PAYLOAD_SIZE_DIAG 1 @@ -68,7 +69,9 @@ m_arqSeqGiveUp(arqSeqGiveUp), m_arqSeqFound(false), m_fragment(streamid), + m_sessionId(0), m_sessionKey(0), + m_maxLength(0), m_decodeKey(0), m_validKey(true) { @@ -208,7 +211,9 @@ else { // replacing an existing entry, make sure the new data is valid +#ifdef APPLY_CRC_CHECK if (! packet.hasCRC() || calculateCRC(packet) == packet.crc()) +#endif { #ifdef PACKET_PROCESS_DIAG seqDebug("SEQ: Update arq (%04x) stream %d in cache", serverArqSeq, m_streamid); @@ -216,13 +221,11 @@ *it->second = packet; } - -#ifdef PACKET_PROCESS_DIAG +#if defined(PACKET_PROCESS_DIAG) && defined(APPLY_CRC_CHECK) else seqDebug("SEQ: Not Updating arq (%04x) stream %d into cache, CRC error!", serverArqSeq, m_streamid); #endif - } #ifdef PACKET_CACHE_DIAG @@ -295,45 +298,69 @@ m_arqSeqExp, EQStreamStr[m_streamid], m_cache.size()); #endif -#if defined (PACKET_CACHE_DIAG) && (PACKET_CACHE_DIAG > 2) - // validate the packet against a memory corruption - if (!packet->isValid()) + // validate the packet with a crc check. If the packet is for an old + // session, we probably shouldn't be using it! +#ifdef APPLY_CRC_CHECK + if (packet->hasCRC() && packet->crc() != calculateCRC(*packet)) { +#if defined (PACKET_CACHE_DIAG) // Something's screwed up - seqDebug("SEQ: INVALID PACKET: Bad CRC in packet in stream %s cache with arq %04x!", - EQStreamStr[m_streamid], packet->arqSeq()); - } + seqDebug("SEQ: INVALID PACKET: Bad CRC in packet in stream %s cache with arq %04x! Droping it, but leaving expected seq as %04x", + EQStreamStr[m_streamid], packet->arqSeq(), m_arqSeqExp); #endif - - + + // Need to drop from the cache + eraseIt = it; + + // increment the current position iterator + it++; + + // erase the packet from the cache + m_cache.erase(eraseIt); + emit cacheSize(m_cache.size(), (int)m_streamid); + + #ifdef PACKET_CACHE_DIAG + seqDebug("SEQ: REMOVING arq %04x from stream %s cache, cache count %04d", + packet->arqSeq(), EQStreamStr[m_streamid], m_cache.size()); + #endif + // delete the packet + delete packet; + + // No sense looping some more. + break; + } + else +#endif /* APPLY_CRC_CHECK */ + { #if defined (PACKET_CACHE_DIAG) && (PACKET_CACHE_DIAG > 2) - seqDebug("SEQ: Found next arq in stream %s cache, incrementing arq seq, %04x", - EQStreamStr[m_streamid], packet->arqSeq()); + seqDebug("SEQ: Found next arq in stream %s cache, incrementing arq seq, %04x", + EQStreamStr[m_streamid], packet->arqSeq()); #endif - // Process the packet since it's next in the sequence and was just - // received out of order - processPacket(*packet, packet->isSubpacket()); - - // Need to drop from the cache - eraseIt = it; - - // increment the current position iterator - it++; - - // erase the packet from the cache - m_cache.erase(eraseIt); - emit cacheSize(m_cache.size(), (int)m_streamid); + // Process the packet since it's next in the sequence and was just + // received out of order + processPacket(*packet, packet->isSubpacket()); + + // Need to drop from the cache + eraseIt = it; + + // increment the current position iterator + it++; + + // erase the packet from the cache + m_cache.erase(eraseIt); + emit cacheSize(m_cache.size(), (int)m_streamid); #ifdef PACKET_CACHE_DIAG - seqDebug("SEQ: REMOVING arq %04x from stream %s cache, cache count %04d", - packet->arqSeq(), EQStreamStr[m_streamid], m_cache.size()); + seqDebug("SEQ: REMOVING arq %04x from stream %s cache, cache count %04d", + packet->arqSeq(), EQStreamStr[m_streamid], m_cache.size()); #endif - // delete the packet - delete packet; - - if (m_arqSeqExp == 0) - it = m_cache.begin(); + // delete the packet + delete packet; + + if (m_arqSeqExp == 0) + it = m_cache.begin(); + } } #ifdef PACKET_CACHE_DIAG @@ -446,7 +473,7 @@ packet.getNetOpCode() != OP_SessionResponse && ! m_sessionKey) { -#if (defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)) || defined(PACKET_SESSION_DIAG) +#if (defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)) || (defined(PACKET_SESSION_DIAG) && PACKET_SESSION_DIAG > 1) seqDebug("discarding packet %s:%d ==>%s:%d netopcode=%04x size=%d. Session not initialized. Need to zone to start picking up packets. Session tracking %s.", (const char*)packet.getIPv4SourceA(), packet.getSourcePort(), (const char*)packet.getIPv4DestA(), packet.getDestPort(), @@ -457,7 +484,25 @@ return; } - emit rawPacket(packet.payload(), packet.payloadLength(), m_dir, + // Decode the packet first + if (! packet.decode(m_maxLength)) + { + seqWarn("Packet decode failed for stream %s (%d), op %04x, flags %02x packet dropped.", + EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(), + packet.getFlags()); + return; + } +#ifdef PACKET_DECODE_DIAG + else if (packet.hasFlags()) + { + seqDebug("Successful decode for stream %s (%d), op %04x, flags %02x.", + EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(), + packet.getFlags()); + } +#endif + + // Raw packet + emit rawPacket(packet.rawPayload(), packet.rawPayloadLength(), m_dir, packet.getNetOpCode()); processPacket(packet, false); // false = isn't subpacket @@ -483,7 +528,7 @@ // This is an app-opcode directly on the wire with no wrapping protocol // information. Weird, but whatever gets the stream read, right? dispatchPacket(packet.payload(), packet.payloadLength(), - packet.getNetOpCode(), m_opcodeDB.find(packet.getNetOpCode())); + packet.getNetOpCode(), m_opcodeDB.find(packet.getNetOpCode())); return; } @@ -494,7 +539,7 @@ { #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: found combined packet (net op: %04x, size %d) on stream %s (%d). Unrolling.", - packet.getNetOpCode(), packet.payloadLength(), + packet.getNetOpCode(), packet.payloadLength(), EQStreamStr[m_streamid], m_streamid); #endif @@ -550,7 +595,7 @@ { #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: found appcombined packet (net op: %04x, size %d) on stream %s (%d). Unrolling.", - packet.getNetOpCode(), packet.payloadLength(), + packet.getNetOpCode(), packet.payloadLength(), EQStreamStr[m_streamid], m_streamid); #endif @@ -617,7 +662,7 @@ case OP_Packet: { // Normal unfragmented sequenced packet. - uint16_t seq = eqntohuint16(packet.payload()); + uint16_t seq = packet.arqSeq(); emit seqReceive(seq, (int)m_streamid); if (seq >= m_arqSeqExp) @@ -630,27 +675,27 @@ emit seqExpect(m_arqSeqExp, (int)m_streamid); // OpCode next. Net order for op codes. - uint16_t subOpCode = *(uint16_t*)(&packet.payload()[2]); + uint16_t subOpCode = *(uint16_t*)(packet.payload()); #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1) seqDebug("SEQ: Found next sequence number in data stream %s (%d), incrementing expected seq, %04x (op code %04x, sub opcode %04x)", - EQStreamStr[m_streamid], m_streamid, seq, packet.getNetOpCode(), - subOpCode); + EQStreamStr[m_streamid], m_streamid, seq, + packet.getNetOpCode(), subOpCode); #endif // App opcode or net opcode? if (IS_NET_OPCODE(subOpCode)) { // Net opcode. false = no copy. true = subpacket. - EQProtocolPacket spacket(&packet.payload()[2], - packet.payloadLength()-2, false, true); + EQProtocolPacket spacket(packet.payload(), + packet.payloadLength(), false, true); processPacket(spacket, true); } else { - // App opcode. Dispatch, skipping seq and opcode. - dispatchPacket(&packet.payload()[4], packet.payloadLength()-4, + // App opcode. Dispatch, skipping opcode. + dispatchPacket(&packet.payload()[2], packet.payloadLength()-2, subOpCode, m_opcodeDB.find(subOpCode)); } } @@ -668,8 +713,11 @@ else { // Past packet outside the cut off - seqWarn("SEQ: received sequenced %spacket outside the bounds of reasonableness. Expecting seq=%04x got seq=%04x, reasonableness being %d in the future.", - (isSubpacket ? "sub" : ""), m_arqSeqExp, seq, arqSeqWrapCutoff); + seqWarn("SEQ: received sequenced %spacket outside the bounds of reasonableness on stream %s (%d) netopcode=%04x size=%d. Expecting seq=%04x got seq=%04x, reasonableness being %d in the future.", + (isSubpacket ? "sub" : ""), + EQStreamStr[m_streamid], m_streamid, + packet.getNetOpCode(), packet.payloadLength(), + m_arqSeqExp, seq, arqSeqWrapCutoff); } } else @@ -678,7 +726,7 @@ #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1) seqDebug("discarding %spacket netopcode=%04x seq=%d size=%d on stream %s (%d). Packet is in the past. We've moved on.", (isSubpacket ? "sub" : ""), - packet.getNetOpCode(), seq, packet.payloadLength(), + packet.getNetOpCode(), seq, packet.payloadLength(), EQStreamStr[m_streamid], m_streamid); #endif } @@ -687,23 +735,13 @@ case OP_Oversized: { // Fragmented sequenced data packet. - uint16_t seq = eqntohuint16(packet.payload()); + uint16_t seq = packet.arqSeq(); emit seqReceive(seq, (int)m_streamid); if (seq >= m_arqSeqExp) { // Future packet? - if (seq > m_arqSeqExp) - { - // Yeah, future packet. Push it on the packet cache. -#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1) - seqDebug("SEQ: out of order sequence %04x stream %s (%d) expecting %04x, sending to cache, %04d", - seq, EQStreamStr[m_streamid], m_streamid, - m_arqSeqExp, m_cache.size()); -#endif - setCache(seq, packet); - } - else + if (seq == m_arqSeqExp) { // Expected packet. m_arqSeqExp++; @@ -734,14 +772,34 @@ m_fragment.reset(); } } + else if (seq < (uint32_t(m_arqSeqExp + arqSeqWrapCutoff)) || + seq < (int32_t(m_arqSeqExp - arqSeqWrapCutoff))) + { + // Yeah, future packet. Push it on the packet cache. +#ifdef PACKET_PROCESS_DIAG + seqDebug("SEQ: out of order sequence %04x stream %s (%d) expecting %04x, sending to cache, %04d", + seq, EQStreamStr[m_streamid], m_streamid, + m_arqSeqExp, m_cache.size()); +#endif + setCache(seq, packet); + } + else + { + // Past packet outside the cut off + seqWarn("SEQ: received sequenced %spacket outside the bounds of reasonableness on stream %s (%d) netopcode=%04x size=%d. Expecting seq=%04x got seq=%04x, reasonableness being %d in the future.", + (isSubpacket ? "sub" : ""), + EQStreamStr[m_streamid], m_streamid, + packet.getNetOpCode(), packet.payloadLength(), + m_arqSeqExp, seq, arqSeqWrapCutoff); + } } else { // Spooky packet from the past. Boo! #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1) - seqDebug("discarding packet netopcode=%04x seq=%d size=%d on stream %s (%d). Packet is in the past. We've moved on.", - packet.getNetOpCode(), seq, packet.payloadLength(), - EQStreamStr[m_streamid], m_streamid); + seqDebug("discarding packet netopcode=%04x seq=%04x size=%d on stream %s (%d). Packet is in the past. We've moved on, expecting %04x.", + packet.getNetOpCode(), seq, packet.payloadLength(), + EQStreamStr[m_streamid], m_streamid, m_arqSeqExp); #endif } } @@ -757,25 +815,32 @@ #endif // Pull off session request information - SessionRequestStruct* request = - (SessionRequestStruct*) packet.payload(); + SessionRequestStruct* request = (SessionRequestStruct*) packet.payload(); m_sessionId = eqntohuint32((uint8_t*)&(request->sessionId)); m_maxLength = eqntohuint32((uint8_t*)&(request->maxLength)); #if defined(PACKET_SESSION_DIAG) - seqDebug("EQPacket: SessionRequest sessionId %u maxLength %u, awaiting key for stream %s (%d)", - m_sessionId, - m_maxLength, - EQStreamStr[m_streamid], - m_streamid); + seqDebug("EQPacket: SessionRequest %s:%u->%s:%u, sessionId %u maxLength %u, awaiting key for stream %s (%d)", + ((EQUDPIPPacketFormat&) packet).getIPv4SourceA().ascii(), + ((EQUDPIPPacketFormat&) packet).getSourcePort(), + ((EQUDPIPPacketFormat&) packet).getIPv4DestA().ascii(), + ((EQUDPIPPacketFormat&) packet).getDestPort(), + m_sessionId, m_maxLength, EQStreamStr[m_streamid], m_streamid); #endif #if defined(PACKET_SESSION_DIAG) && (PACKET_SESSION_DIAG > 1) seqDebug("EQPacket: SessionRequest contents: unknown %u, sessionId %u, maxLength %u", - eqntohuint32((uint8_t*)&(request->unknown0000)), - m_sessionId, - m_maxLength); + eqntohuint32((uint8_t*)&(request->unknown0000)), + m_sessionId, m_maxLength); +#endif + +#if defined(PACKET_SESSION_DIAG) && (PACKET_SESSION_DIAG > 2) + seqDebug("EQPacket: Raw SessionRequest: %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x", + packet.payload()[0], packet.payload()[1], packet.payload()[2], + packet.payload()[3], packet.payload()[4], packet.payload()[5], + packet.payload()[6], packet.payload()[7], packet.payload()[8], + packet.payload()[9], packet.payload()[10], packet.payload()[11]); #endif m_arqSeqExp = 0; @@ -786,7 +851,11 @@ { // Session response from server #if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG) - seqDebug("EQPacket: SessionResponse found, resetting expected seq, stream %s (%d) (session tracking %s)", + seqDebug("EQPacket: SessionResponse found %s:%u->%s:%u, resetting expected seq, stream %s (%d) (session tracking %s)", + ((EQUDPIPPacketFormat&) packet).getIPv4SourceA().ascii(), + ((EQUDPIPPacketFormat&) packet).getSourcePort(), + ((EQUDPIPPacketFormat&) packet).getIPv4DestA().ascii(), + ((EQUDPIPPacketFormat&) packet).getDestPort(), EQStreamStr[m_streamid], m_streamid, (m_session_tracking_enabled == 2 ? "locked on" : (m_session_tracking_enabled == 1 ? "enabled" : "disabled"))); @@ -802,23 +871,29 @@ #if defined(PACKET_SESSION_DIAG) seqDebug("EQPacket: SessionResponse sessionId %u maxLength %u, key is %u for stream %s (%d)", - m_sessionId, - m_maxLength, - m_sessionKey, - EQStreamStr[m_streamid], - m_streamid); + m_sessionId, m_maxLength, m_sessionKey, + EQStreamStr[m_streamid], m_streamid); #endif #if defined(PACKET_SESSION_DIAG) && (PACKET_SESSION_DIAG > 1) seqDebug("EQPacket: SessionResponse contents: sessionId %u, key %u, unknown %u, unknown %u, maxLength %u, unknown %u", - m_sessionId, - m_sessionKey, + m_sessionId, m_sessionKey, eqntohuint16((uint8_t*)&(response->unknown0008)), - response->unknown0010, - m_maxLength, + response->unknown0010, m_maxLength, eqntohuint32((uint8_t*) &(response->unknown0015))); #endif +#if defined(PACKET_SESSION_DIAG) && (PACKET_SESSION_DIAG > 2) + seqDebug("EQPacket: Raw SessionResponse: %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x", + packet.payload()[0], packet.payload()[1], packet.payload()[2], + packet.payload()[3], packet.payload()[4], packet.payload()[5], + packet.payload()[6], packet.payload()[7], packet.payload()[8], + packet.payload()[9], packet.payload()[10], packet.payload()[11], + packet.payload()[12], packet.payload()[13], packet.payload()[14], + packet.payload()[15], packet.payload()[16], packet.payload()[17], + packet.payload()[18]); +#endif + // Provide key to corresponding stream from this session/stream emit sessionKey(m_sessionId, m_streamid, m_sessionKey); @@ -854,12 +929,23 @@ case OP_SessionDisconnect: { #if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG) - seqDebug("EQPacket: SessionDisconnect found, resetting expected seq, stream %s (%d) (session tracking %s)", + seqDebug("EQPacket: SessionDisconnect found %s:%u->%s:%u, resetting expected seq, stream %s (%d) (session tracking %s)", + ((EQUDPIPPacketFormat&) packet).getIPv4SourceA().ascii(), + ((EQUDPIPPacketFormat&) packet).getSourcePort(), + ((EQUDPIPPacketFormat&) packet).getIPv4DestA().ascii(), + ((EQUDPIPPacketFormat&) packet).getDestPort(), EQStreamStr[m_streamid], m_streamid, (m_session_tracking_enabled == 2 ? "locked on" : (m_session_tracking_enabled == 1 ? "enabled" : "disabled"))); #endif +#if defined(PACKET_SESSION_DIAG) && (PACKET_SESSION_DIAG > 2) + seqDebug("EQPacket: Raw SessionDisconnect: %02x%02x %02x%02x %02x%02x %02x%02x", + packet.payload()[0], packet.payload()[1], packet.payload()[2], + packet.payload()[3], packet.payload()[4], packet.payload()[5], + packet.payload()[6], packet.payload()[7]); +#endif + m_arqSeqExp = 0; // Clear cache @@ -876,11 +962,12 @@ } break; case OP_Ack: - case OP_Resend: + case OP_AckFuture: + case OP_AckAfterDisconnect: { #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: no-op on for net opcode %04x seq %04x, stream %s (%d)", - packet.getNetOpCode(), eqntohuint16(packet.payload()), + packet.getNetOpCode(), eqntohuint16(packet.payload()), EQStreamStr[m_streamid], m_streamid); #endif } @@ -926,7 +1013,7 @@ uint16_t EQPacketStream::calculateCRC(EQProtocolPacket& packet) { // CRC is at the end of the raw payload, 2 bytes. - return ::calcCRC16(packet.rawPayload(), packet.rawPayloadLength()-2, + return ::calcCRC16(packet.rawPacket(), packet.rawPacketLength()-2, m_sessionKey); } Index: zonemgr.h =================================================================== RCS file: /cvsroot/seq/showeq/src/zonemgr.h,v retrieving revision 1.4.6.2 retrieving revision 1.4.6.3 diff -u -d -r1.4.6.2 -r1.4.6.3 --- zonemgr.h 12 Feb 2004 00:39:28 -0000 1.4.6.2 +++ zonemgr.h 21 Feb 2005 05:56:31 -0000 1.4.6.3 @@ -35,6 +35,7 @@ public: ZoneMgr(QObject* parent = 0, const char* name =0); + virtual ~ZoneMgr(); QString zoneNameFromID(uint16_t zoneId); QString zoneLongNameFromID(uint16_t zoneId); Index: messageshell.cpp =================================================================== RCS file: /cvsroot/seq/showeq/src/Attic/messageshell.cpp,v retrieving revision 1.1.4.6 retrieving revision 1.1.4.7 diff -u -d -r1.1.4.6 -r1.1.4.7 --- messageshell.cpp 9 Feb 2005 07:07:37 -0000 1.1.4.6 +++ messageshell.cpp 21 Feb 2005 05:56:14 -0000 1.1.4.7 @@ -38,12 +38,12 @@ void MessageShell::channelMessage(const uint8_t* data, size_t, uint8_t dir) { - // avoid client chatter and do nothing if not viewing channel messages - // if (dir == DIR_Client) - // return; - const channelMessageStruct* cmsg = (const channelMessageStruct*)data; + // Tells happen twice *shrug* + if (dir == DIR_Client && cmsg->chanNum == MT_Tell) + return; + QString tempStr; bool target = false; @@ -611,11 +611,38 @@ void MessageShell::groupUpdate(const uint8_t* data, size_t size, uint8_t dir) { + if (size != sizeof(groupUpdateStruct)) + { + // Ignore groupFullUpdateStruct + return; + } const groupUpdateStruct* gmem = (const groupUpdateStruct*)data; QString tempStr; - tempStr.sprintf ("Update: action:%d - %s - %s (unknown: %d)", - gmem->action, gmem->yourname, gmem->membername, - gmem->unknown0132); + + switch (gmem->action) + { + case GUA_Joined : + tempStr.sprintf ("Update: %s has joined the group.", gmem->membername); + break; + case GUA_Left : + tempStr.sprintf ("Update: %s has left the group.", gmem->membername); + break; + case GUA_LastLeft : + tempStr.sprintf ("Update: The group has been disbanded when %s left.", + gmem->membername); + break; + case GUA_MakeLeader : + tempStr.sprintf ("Update: %s is now the leader of the group.", + gmem->membername); + break; + case GUA_Started : + tempStr.sprintf ("Update: %s has formed the group.", gmem->membername); + break; + default : + tempStr.sprintf ("Update: Unknown Update action:%d - %s - %s)", + gmem->action, gmem->yourname, gmem->membername); + } + m_messages->addMessage(MT_Group, tempStr); } @@ -623,7 +650,7 @@ { const groupInviteStruct* gmem = (const groupInviteStruct*)data; QString tempStr; - tempStr.sprintf("Invite: %s invites %s", + tempStr.sprintf("Invite: %s invites %s to join the group", gmem->inviter, gmem->invitee); m_messages->addMessage(MT_Group, tempStr); } @@ -650,8 +677,7 @@ { const groupDisbandStruct* gmem = (const groupDisbandStruct*)data; QString tempStr; - tempStr.sprintf ("Disband: %s - %s", - gmem->membername, gmem->yourname); + tempStr.sprintf ("Disband: %s disbands from the group", gmem->membername); m_messages->addMessage(MT_Group, tempStr); } @@ -701,7 +727,7 @@ m_messages->addMessage(MT_Player, message); int buffnumber; - for (buffnumber=0;buffnumber<20;buffnumber++) + for (buffnumber=0;buffnumber<MAX_BUFFS;buffnumber++) { if (player->buffs[buffnumber].spellid && player->buffs[buffnumber].duration) { @@ -799,6 +825,7 @@ switch (con->level) { case 0: + case 20: msg += " (even)"; break; case 2: Index: zonemgr.cpp =================================================================== RCS file: /cvsroot/seq/showeq/src/zonemgr.cpp,v retrieving revision 1.8.6.5 retrieving revision 1.8.6.6 diff -u -d -r1.8.6.5 -r1.8.6.6 --- zonemgr.cpp 7 Nov 2004 23:10:27 -0000 1.8.6.5 +++ zonemgr.cpp 21 Feb 2005 05:56:31 -0000 1.8.6.6 @@ -61,6 +61,12 @@ restoreZoneState(); } +ZoneMgr::~ZoneMgr() +{ + if (m_zonePoints) + delete [] m_zonePoints; +} + struct ZoneNames { const char* shortName; Index: group.cpp =================================================================== RCS file: /cvsroot/seq/showeq/src/group.cpp,v retrieving revision 1.6.16.3 retrieving revision 1.6.16.4 diff -u -d -r1.6.16.3 -r1.6.16.4 --- group.cpp 7 Nov 2004 23:10:03 -0000 1.6.16.3 +++ group.cpp 21 Feb 2005 05:56:13 -0000 1.6.16.4 @@ -33,6 +33,14 @@ m_members[i].m_spawn = 0; } +GroupMgr::~GroupMgr() +{ + if (m_members) + { + delete[] m_members; + } +} + void GroupMgr::player(const uint8_t* data) { const charProfileStruct* player = (const charProfileStruct*)data; Index: xmlpreferences.cpp =================================================================== RCS file: /cvsroot/seq/showeq/src/xmlpreferences.cpp,v retrieving revision 1.3.16.3 retrieving revision 1.3.16.4 diff -u -d -r1.3.16.3 -r1.3.16.4 --- xmlpreferences.cpp 7 Nov 2004 23:10:27 -0000 1.3.16.3 +++ xmlpreferences.cpp 21 Feb 2005 05:56:31 -0000 1.3.16.4 @@ -54,7 +54,8 @@ // automatically delete removed sections m_userSections.setAutoDelete(true); m_defaultsSections.setAutoDelete(true); - + m_commentSections.setAutoDelete(true); + // load the preferences load(); } Index: packetformat.h =================================================================== RCS file: /cvsroot/seq/showeq/src/packetformat.h,v retrieving revision 1.1.6.3 retrieving revision 1.1.6.4 diff -u -d -r1.1.6.3 -r1.1.6.4 --- packetformat.h 9 Feb 2005 07:07:38 -0000 1.1.6.3 +++ packetformat.h 21 Feb 2005 05:56:14 -0000 1.1.6.4 @@ -55,14 +55,23 @@ static const uint16_t OP_SessionStatResponse= 0x0800; static const uint16_t OP_Packet = 0x0900; static const uint16_t OP_Oversized = 0x0d00; -static const uint16_t OP_Resend = 0x1100; +static const uint16_t OP_AckFuture = 0x1100; static const uint16_t OP_Ack = 0x1500; static const uint16_t OP_AppCombined = 0x1900; +static const uint16_t OP_AckAfterDisconnect = 0x1d00; // Detect app opcode vs net opcode by the 2nd byte. 0x00 = net opcode. #define IS_APP_OPCODE(uint16) (((uint16) & 0x00ff) != 0x0000) #define IS_NET_OPCODE(uint16) (((uint16) & 0x00ff) == 0x0000) +// Protocol flag bitmasks. Actually, we just flag straight to compressed +// which is 5a right now. I wonder what the significance of that is. +#define PROTOCOL_FLAG_COMPRESSED 0x5a + +// Should we apply CRC checking. This should be yes, but if for some reason +// it is getting in the way while debugging, can turn it off +#define APPLY_CRC_CHECK + //---------------------------------------------------------------------- // EQProtocolPacket // A wrapper around a byte array which is the wire data for an @@ -77,11 +86,13 @@ EQProtocolPacket() : m_packet(NULL), m_length(0), + m_flags(0), m_payload(NULL), + m_bAllocedPayload(false), + m_bDecoded(false), m_payloadLength(0), m_arqSeq(0), m_ownCopy(false), - m_isValid(false), m_subpacket(false) { } @@ -99,8 +110,33 @@ // operators EQProtocolPacket& operator=(const EQProtocolPacket& packet); + // Decode the packet. This processed compressed packets and readjusts + // alignments if needed. If this returns false, using the packet isn't + // recommended! + bool decode(uint32_t maxPacketLength); + uint16_t getNetOpCode() const { return m_netOp; } + bool hasFlags() const + { + // Subpackets don't have flags, the outer packet does. + if (m_subpacket) return false; + + switch (m_netOp) + { + case OP_SessionStatRequest: + case OP_SessionStatResponse: + case OP_Combined: + case OP_Packet: + case OP_Oversized: + case OP_AppCombined: + return true; + default : + return IS_APP_OPCODE(m_netOp); + } + } + uint8_t getFlags() const { return m_flags; } + bool hasArqSeq() const { return getNetOpCode() == OP_Packet || getNetOpCode() == OP_Oversized; @@ -133,27 +169,40 @@ bool isSubpacket() const { return m_subpacket; } + // Payload is uncompressed (after decode is called) and aligned to the + // beginning of the payload (after net op, flags, seq if applicable) uint8_t* payload() const { return m_payload; } uint16_t payloadLength() const { return m_payloadLength; } - uint8_t* rawPayload() const { return m_packet; } - uint16_t rawPayloadLength() const { return m_length; } + + // Raw Packet is compressed and aligned to the start of the net op. Length + // includes CRC if applicable. + uint8_t* rawPacket() const { return m_packet; } + uint16_t rawPacketLength() const { return m_length; } + + // Raw payload is uncompressed (after decode is called) and aligned to + // the beginning of what was decompressed. This is what is alloced if + // m_bAllocPayload is true. + uint8_t* rawPayload() const { return m_rawPayload; } + uint16_t rawPayloadLength() const { return m_rawPayloadLength; } protected: void init(); void init(uint8_t* packet, uint16_t length, bool copy=false, bool subpacket=false); - QString headerFlags(const QString& prefix, bool brief = false) const; - private: - uint8_t* m_packet; // raw packet - uint16_t m_length; - uint16_t m_netOp; - uint8_t* m_payload; // packet without netop, crc. Mem owned by m_packet. - uint16_t m_payloadLength; + uint8_t* m_packet; // raw packet, untouched starting at net opcode + uint16_t m_length; // raw packet length + uint16_t m_netOp; // protocol opcode + uint8_t m_flags; // protocol flags + uint8_t* m_payload; // packet payload. Aligned and uncompressed if necessary. + bool m_bAllocedPayload; // Whether payload was alloced or not + bool m_bDecoded; // Whether this packet has been decoded + uint16_t m_payloadLength; // length of payload + uint8_t* m_rawPayload; // decompressed but not aligned payload + uint16_t m_rawPayloadLength; // length of raw payload uint16_t m_arqSeq; // local copy to speed up comparisons bool m_ownCopy; - bool m_isValid; bool m_subpacket; }; @@ -215,8 +264,6 @@ // Don't currently support IPv6, so no IPv6 accessors - QString headerFlags(bool brief = false) const; - uint32_t getSessionKey() const { return m_sessionKey; } void setSessionKey(uint32_t sessionKey) { m_sessionKey = sessionKey; } Index: packetfragment.h =================================================================== RCS file: /cvsroot/seq/showeq/src/packetfragment.h,v retrieving revision 1.1.6.1 retrieving revision 1.1.6.2 diff -u -d -r1.1.6.1 -r1.1.6.2 --- packetfragment.h 9 Feb 2005 07:07:38 -0000 1.1.6.1 +++ packetfragment.h 21 Feb 2005 05:56:14 -0000 1.1.6.2 @@ -26,7 +26,7 @@ EQPacketFragmentSequence(EQStreamID streamid); ~EQPacketFragmentSequence(); void reset(); - void addFragment(EQProtocolPacket& pf); + void addFragment(EQProtocolPacket& packet); bool isComplete(); uint8_t* data(); Index: packetcapture.h =================================================================== RCS file: /cvsroot/seq/showeq/src/packetcapture.h,v retrieving revision 1.1.6.1 retrieving revision 1.1.6.2 diff -u -d -r1.1.6.1 -r1.1.6.2 --- packetcapture.h 7 Dec 2003 06:30:44 -0000 1.1.6.1 +++ packetcapture.h 21 Feb 2005 05:56:14 -0000 1.1.6.2 @@ -61,6 +61,7 @@ }; struct packetCache *m_pcache_first; struct packetCache *m_pcache_last; + bool m_pcache_closed; pthread_t m_tid; pthread_mutex_t m_pcache_mutex; Index: zones.h =================================================================== RCS file: /cvsroot/seq/showeq/src/zones.h,v retrieving revision 1.7.16.3 retrieving revision 1.7.16.4 diff -u -d -r1.7.16.3 -r1.7.16.4 --- zones.h 13 Aug 2004 06:25:52 -0000 1.7.16.3 +++ zones.h 21 Feb 2005 05:56:31 -0000 1.7.16.4 @@ -344,3 +344,665 @@ { "riftseekers", "Riftbreakers' Sanctum" }, // 334 { "harbingers", "Harbingers' Spire" }, // 335 { "dranik", "The Ruined City of Dranik" }, // 336 +{ "broodlands", "The Broodlands" }, // 337 +{ "stillmoona", "Stillmoon Temple" }, // 338 +{ "stillmoonb", "The Ascent" }, // 339 +{ "thundercrest", "Thundercrest Isles" }, // 340 +{ "delvea", "Lavaspinner's Lair" }, // 341 +{ "delveb", "Tirranum's Delve"}, // 342 +{ "thenest", "The Accursed Nest" }, // 343 +{ "guildlobby", "Guild Lobby" }, // 344 +{ "guildhall", "Guild Hall" }, // 345 +{ "barter", "Barter Hall" }, // 346 +{ NULL, NULL }, // 347 +{ NULL, NULL }, // 348 +{ NULL, NULL }, // 349 +{ NULL, NULL }, // 350 +{ NULL, NULL }, // 351 +{ NULL, NULL }, // 352 +{ NULL, NULL }, // 353 +{ NULL, NULL }, // 354 +{ NULL, NULL }, // 355 +{ NULL, NULL }, // 356 +{ NULL, NULL }, // 357 +{ NULL, NULL }, // 358 +{ NULL, NULL }, // 359 +{ NULL, NULL }, // 360 +{ NULL, NULL }, // 361 +{ NULL, NULL }, // 362 +{ NULL, NULL }, // 363 +{ NULL, NULL }, // 364 +{ NULL, NULL }, // 365 +{ NULL, NULL }, // 366 +{ NULL, NULL }, // 367 +{ NULL, NULL }, // 368 +{ NULL, NULL }, // 369 +{ NULL, NULL }, // 370 +{ NULL, NULL }, // 371 +{ NULL, NULL }, // 372 +{ NULL, NULL }, // 373 +{ NULL, NULL }, // 374 +{ NULL, NULL }, // 375 +{ NULL, NULL }, // 376 +{ NULL, NULL }, // 377 +{ NULL, NULL }, // 378 +{ NULL, NULL }, // 379 +{ NULL, NULL }, // 380 +{ NULL, NULL }, // 381 +{ NULL, NULL }, // 382 +{ NULL, NULL }, // 383 +{ NULL, NULL }, // 384 +{ NULL, NULL }, // 385 +{ NULL, NULL }, // 386 +{ NULL, NULL }, // 387 +{ NULL, NULL }, // 388 +{ NULL, NULL }, // 389 +{ NULL, NULL }, // 390 +{ NULL, NULL }, // 391 +{ NULL, NULL }, // 392 +{ NULL, NULL }, // 393 +{ NULL, NULL }, // 394 +{ NULL, NULL }, // 395 +{ NULL, NULL }, // 396 +{ NULL, NULL }, // 397 +{ NULL, NULL }, // 398 +{ NULL, NULL }, // 399 +{ NULL, NULL }, // 400 +{ NULL, NULL }, // 401 +{ NULL, NULL }, // 402 +{ NULL, NULL }, // 403 +{ NULL, NULL }, // 404 +{ NULL, NULL }, // 405 +{ NULL, NULL }, // 406 +{ NULL, NULL }, // 407 +{ NULL, NULL }, // 408 +{ NULL, NULL }, // 409 +{ NULL, NULL }, // 410 +{ NULL, NULL }, // 411 +{ NULL, NULL }, // 412 +{ NULL, NULL }, // 413 +{ NULL, NULL }, // 414 +{ NULL, NULL }, // 415 +{ NULL, NULL }, // 416 +{ NULL, NULL }, // 417 +{ NULL, NULL }, // 418 +{ NULL, NULL }, // 419 +{ NULL, NULL }, // 420 +{ NULL, NULL }, // 421 +{ NULL, NULL }, // 422 +{ NULL, NULL }, // 423 +{ NULL, NULL }, // 424 +{ NULL, NULL }, // 425 +{ NULL, NULL }, // 426 +{ NULL, NULL }, // 427 +{ NULL, NULL }, // 428 +{ NULL, NULL }, // 429 +{ NULL, NULL }, // 430 +{ NULL, NULL }, // 431 +{ NULL, NULL }, // 432 +{ NULL, NULL }, // 433 +{ NULL, NULL }, // 434 +{ NULL, NULL }, // 435 +{ NULL, NULL }, // 436 +{ NULL, NULL }, // 437 +{ NULL, NULL }, // 438 +{ NULL, NULL }, // 439 +{ NULL, NULL }, // 440 +{ NULL, NULL }, // 441 +{ NULL, NULL }, // 442 +{ NULL, NULL }, // 443 +{ NULL, NULL }, // 444 +{ NULL, NULL }, // 445 +{ NULL, NULL }, // 446 +{ NULL, NULL }, // 447 +{ NULL, NULL }, // 448 +{ NULL, NULL }, // 449 +{ NULL, NULL }, // 450 +{ NULL, NULL }, // 451 +{ NULL, NULL }, // 452 +{ NULL, NULL }, // 453 +{ NULL, NULL }, // 454 +{ NULL, NULL }, // 455 +{ NULL, NULL }, // 456 +{ NULL, NULL }, // 457 +{ NULL, NULL }, // 458 +{ NULL, NULL }, // 459 +{ NULL, NULL }, // 460 +{ NULL, NULL }, // 461 +{ NULL, NULL }, // 462 +{ NULL, NULL }, // 463 +{ NULL, NULL }, // 464 +{ NULL, NULL }, // 465 +{ NULL, NULL }, // 466 +{ NULL, NULL }, // 467 +{ NULL, NULL }, // 468 +{ NULL, NULL }, // 469 +{ NULL, NULL }, // 470 +{ NULL, NULL }, // 471 +{ NULL, NULL }, // 472 +{ NULL, NULL }, // 473 +{ NULL, NULL }, // 474 +{ NULL, NULL }, // 475 +{ NULL, NULL }, // 476 +{ NULL, NULL }, // 477 +{ NULL, NULL }, // 478 +{ NULL, NULL }, // 479 +{ NULL, NULL }, // 480 +{ NULL, NULL }, // 481 +{ NULL, NULL }, // 482 +{ NULL, NULL }, // 483 +{ NULL, NULL }, // 484 +{ NULL, NULL }, // 485 +{ NULL, NULL }, // 486 +{ NULL, NULL }, // 487 +{ NULL, NULL }, // 488 +{ NULL, NULL }, // 489 +{ NULL, NULL }, // 490 +{ NULL, NULL }, // 491 +{ NULL, NULL }, // 492 +{ NULL, NULL }, // 493 +{ NULL, NULL }, // 494 +{ NULL, NULL }, // 495 +{ NULL, NULL }, // 496 +{ NULL, NULL }, // 497 +{ NULL, NULL }, // 498 +{ NULL, NULL }, // 499 +{ NULL, NULL }, // 500 +{ NULL, NULL }, // 501 +{ NULL, NULL }, // 502 +{ NULL, NULL }, // 503 +{ NULL, NULL }, // 504 +{ NULL, NULL }, // 505 +{ NULL, NULL }, // 506 +{ NULL, NULL }, // 507 +{ NULL, NULL }, // 508 +{ NULL, NULL }, // 509 +{ NULL, NULL }, // 510 +{ NULL, NULL }, // 511 +{ NULL, NULL }, // 512 +{ NULL, NULL }, // 513 +{ NULL, NULL }, // 514 +{ NULL, NULL }, // 515 +{ NULL, NULL }, // 516 +{ NULL, NULL }, // 517 +{ NULL, NULL }, // 518 +{ NULL, NULL }, // 519 +{ NULL, NULL }, // 520 +{ NULL, NULL }, // 521 +{ NULL, NULL }, // 522 +{ NULL, NULL }, // 523 +{ NULL, NULL }, // 524 +{ NULL, NULL }, // 525 +{ NULL, NULL }, // 526 +{ NULL, NULL }, // 527 +{ NULL, NULL }, // 528 +{ NULL, NULL }, // 529 +{ NULL, NULL }, // 530 +{ NULL, NULL }, // 531 +{ NULL, NULL }, // 532 +{ NULL, NULL }, // 533 +{ NULL, NULL }, // 534 +{ NULL, NULL }, // 535 +{ NULL, NULL }, // 536 +{ NULL, NULL }, // 537 +{ NULL, NULL }, // 538 +{ NULL, NULL }, // 539 +{ NULL, NULL }, // 540 +{ NULL, NULL }, // 541 +{ NULL, NULL }, // 542 +{ NULL, NULL }, // 543 +{ NULL, NULL }, // 544 +{ NULL, NULL }, // 545 +{ NULL, NULL }, // 546 +{ NULL, NULL }, // 547 +{ NULL, NULL }, // 548 +{ NULL, NULL }, // 549 +{ NULL, NULL }, // 550 +{ NULL, NULL }, // 551 +{ NULL, NULL }, // 552 +{ NULL, NULL }, // 553 +{ NULL, NULL }, // 554 +{ NULL, NULL }, // 555 +{ NULL, NULL }, // 556 +{ NULL, NULL }, // 557 +{ NULL, NULL }, // 558 +{ NULL, NULL }, // 559 +{ NULL, NULL }, // 560 +{ NULL, NULL }, // 561 +{ NULL, NULL }, // 562 +{ NULL, NULL }, // 563 +{ NULL, NULL }, // 564 +{ NULL, NULL }, // 565 +{ NULL, NULL }, // 566 +{ NULL, NULL }, // 567 +{ NULL, NULL }, // 568 +{ NULL, NULL }, // 569 +{ NULL, NULL }, // 570 +{ NULL, NULL }, // 571 +{ NULL, NULL }, // 572 +{ NULL, NULL }, // 573 +{ NULL, NULL }, // 574 +{ NULL, NULL }, // 575 +{ NULL, NULL }, // 576 +{ NULL, NULL }, // 577 +{ NULL, NULL }, // 578 +{ NULL, NULL }, // 579 +{ NULL, NULL }, // 580 +{ NULL, NULL }, // 581 +{ NULL, NULL }, // 582 +{ NULL, NULL }, // 583 +{ NULL, NULL }, // 584 +{ NULL, NULL }, // 585 +{ NULL, NULL }, // 586 +{ NULL, NULL }, // 587 +{ NULL, NULL }, // 588 +{ NULL, NULL }, // 589 +{ NULL, NULL }, // 590 +{ NULL, NULL }, // 591 +{ NULL, NULL }, // 592 +{ NULL, NULL }, // 593 +{ NULL, NULL }, // 594 +{ NULL, NULL }, // 595 +{ NULL, NULL }, // 596 +{ NULL, NULL }, // 597 +{ NULL, NULL }, // 598 +{ NULL, NULL }, // 599 +{ NULL, NULL }, // 600 +{ NULL, NULL }, // 601 +{ NULL, NULL }, // 602 +{ NULL, NULL }, // 603 +{ NULL, NULL }, // 604 +{ NULL, NULL }, // 605 +{ NULL, NULL }, // 606 +{ NULL, NULL }, // 607 +{ NULL, NULL }, // 608 +{ NULL, NULL }, // 609 +{ NULL, NULL }, // 610 +{ NULL, NULL }, // 611 +{ NULL, NULL }, // 612 +{ NULL, NULL }, // 613 +{ NULL, NULL }, // 614 +{ NULL, NULL }, // 615 +{ NULL, NULL }, // 616 +{ NULL, NULL }, // 617 +{ NULL, NULL }, // 618 +{ NULL, NULL }, // 619 +{ NULL, NULL }, // 620 +{ NULL, NULL }, // 621 +{ NULL, NULL }, // 622 +{ NULL, NULL }, // 623 +{ NULL, NULL }, // 624 +{ NULL, NULL }, // 625 +{ NULL, NULL }, // 626 +{ NULL, NULL }, // 627 +{ NULL, NULL }, // 628 +{ NULL, NULL }, // 629 +{ NULL, NULL }, // 630 +{ NULL, NULL }, // 631 +{ NULL, NULL }, // 632 +{ NULL, NULL }, // 633 +{ NULL, NULL }, // 634 +{ NULL, NULL }, // 635 +{ NULL, NULL }, // 636 +{ NULL, NULL }, // 637 +{ NULL, NULL }, // 638 +{ NULL, NULL }, // 639 +{ NULL, NULL }, // 640 +{ NULL, NULL }, // 641 +{ NULL, NULL }, // 642 +{ NULL, NULL }, // 643 +{ NULL, NULL }, // 644 +{ NULL, NULL }, // 645 +{ NULL, NULL }, // 646 +{ NULL, NULL }, // 647 +{ NULL, NULL }, // 648 +{ NULL, NULL }, // 649 +{ NULL, NULL }, // 650 +{ NULL, NULL }, // 651 +{ NULL, NULL }, // 652 +{ NULL, NULL }, // 653 +{ NULL, NULL }, // 654 +{ NULL, NULL }, // 655 +{ NULL, NULL }, // 656 +{ NULL, NULL }, // 657 +{ NULL, NULL }, // 658 +{ NULL, NULL }, // 659 +{ NULL, NULL }, // 660 +{ NULL, NULL }, // 661 +{ NULL, NULL }, // 662 +{ NULL, NULL }, // 663 +{ NULL, NULL }, // 664 +{ NULL, NULL }, // 665 +{ NULL, NULL }, // 666 +{ NULL, NULL }, // 667 +{ NULL, NULL }, // 668 +{ NULL, NULL }, // 669 +{ NULL, NULL }, // 670 +{ NULL, NULL }, // 671 +{ NULL, NULL }, // 672 +{ NULL, NULL }, // 673 +{ NULL, NULL }, // 674 +{ NULL, NULL }, // 675 +{ NULL, NULL }, // 676 +{ NULL, NULL }, // 677 +{ NULL, NULL }, // 678 +{ NULL, NULL }, // 679 +{ NULL, NULL }, // 680 +{ NULL, NULL }, // 681 +{ NULL, NULL }, // 682 +{ NULL, NULL }, // 683 +{ NULL, NULL }, // 684 +{ NULL, NULL }, // 685 +{ NULL, NULL }, // 686 +{ NULL, NULL }, // 687 +{ NULL, NULL }, // 688 +{ NULL, NULL }, // 689 +{ NULL, NULL }, // 690 +{ NULL, NULL }, // 691 +{ NULL, NULL }, // 692 +{ NULL, NULL }, // 693 +{ NULL, NULL }, // 694 +{ NULL, NULL }, // 695 +{ NULL, NULL }, // 696 +{ NULL, NULL }, // 697 +{ NULL, NULL }, // 698 +{ NULL, NULL }, // 699 +{ NULL, NULL }, // 700 +{ NULL, NULL }, // 701 +{ NULL, NULL }, // 702 +{ NULL, NULL }, // 703 +{ NULL, NULL }, // 704 +{ NULL, NULL }, // 705 +{ NULL, NULL }, // 706 +{ NULL, NULL }, // 707 +{ NULL, NULL }, // 708 +{ NULL, NULL }, // 709 +{ NULL, NULL }, // 710 +{ NULL, NULL }, // 711 +{ NULL, NULL }, // 712 +{ NULL, NULL }, // 713 +{ NULL, NULL }, // 714 +{ NULL, NULL }, // 715 +{ NULL, NULL }, // 716 +{ NULL, NULL }, // 717 +{ NULL, NULL }, // 718 +{ NULL, NULL }, // 719 +{ NULL, NULL }, // 720 +{ NULL, NULL }, // 721 +{ NULL, NULL }, // 722 +{ NULL, NULL }, // 723 +{ NULL, NULL }, // 724 +{ NULL, NULL }, // 725 +{ NULL, NULL }, // 726 +{ NULL, NULL }, // 727 +{ NULL, NULL }, // 728 +{ NULL, NULL }, // 729 +{ NULL, NULL }, // 730 +{ NULL, NULL }, // 731 +{ NULL, NULL }, // 732 +{ NULL, NULL }, // 733 +{ NULL, NULL }, // 734 +{ NULL, NULL }, // 735 +{ NULL, NULL }, // 736 +{ NULL, NULL }, // 737 +{ NULL, NULL }, // 738 +{ NULL, NULL }, // 739 +{ NULL, NULL }, // 740 +{ NULL, NULL }, // 741 +{ NULL, NULL }, // 742 +{ NULL, NULL }, // 743 +{ NULL, NULL }, // 744 +{ NULL, NULL }, // 745 +{ NULL, NULL }, // 746 +{ NULL, NULL }, // 747 +{ NULL, NULL }, // 748 +{ NULL, NULL }, // 749 +{ NULL, NULL }, // 750 +{ NULL, NULL }, // 751 +{ NULL, NULL }, // 752 +{ NULL, NULL }, // 753 +{ NULL, NULL }, // 754 +{ NULL, NULL }, // 755 +{ NULL, NULL }, // 756 +{ NULL, NULL }, // 757 +{ NULL, NULL }, // 758 +{ NULL, NULL }, // 759 +{ NULL, NULL }, // 760 +{ NULL, NULL }, // 761 +{ NULL, NULL }, // 762 +{ NULL, NULL }, // 763 +{ NULL, NULL }, // 764 +{ NULL, NULL }, // 765 +{ NULL, NULL }, // 766 +{ NULL, NULL }, // 767 +{ NULL, NULL }, // 768 +{ NULL, NULL }, // 769 +{ NULL, NULL }, // 770 +{ NULL, NULL }, // 771 +{ NULL, NULL }, // 772 +{ NULL, NULL }, // 773 +{ NULL, NULL }, // 774 +{ NULL, NULL }, // 775 +{ NULL, NULL }, // 776 +{ NULL, NULL }, // 777 +{ NULL, NULL }, // 778 +{ NULL, NULL }, // 779 +{ NULL, NULL }, // 780 +{ NULL, NULL }, // 781 +{ NULL, NULL }, // 782 +{ NULL, NULL }, // 783 +{ NULL, NULL }, // 784 +{ NULL, NULL }, // 785 +{ NULL, NULL }, // 786 +{ NULL, NULL }, // 787 +{ NULL, NULL }, // 788 +{ NULL, NULL }, // 789 +{ NULL, NULL }, // 790 +{ NULL, NULL }, // 791 +{ NULL, NULL }, // 792 +{ NULL, NULL }, // 793 +{ NULL, NULL }, // 794 +{ NULL, NULL }, // 795 +{ NULL, NULL }, // 796 +{ NULL, NULL }, // 797 +{ NULL, NULL }, // 798 +{ NULL, NULL }, // 799 +{ NULL, NULL }, // 800 +{ NULL, NULL }, // 801 +{ NULL, NULL }, // 802 +{ NULL, NULL }, // 803 +{ NULL, NULL }, // 804 +{ NULL, NULL }, // 805 +{ NULL, NULL }, // 806 +{ NULL, NULL }, // 807 +{ NULL, NULL }, // 808 +{ NULL, NULL }, // 809 +{ NULL, NULL }, // 810 +{ NULL, NULL }, // 811 +{ NULL, NULL }, // 812 +{ NULL, NULL }, // 813 +{ NULL, NULL }, // 814 +{ NULL, NULL }, // 815 +{ NULL, NULL }, // 816 +{ NULL, NULL }, // 817 +{ NULL, NULL }, // 818 +{ NULL, NULL }, // 819 +{ NULL, NULL }, // 820 +{ NULL, NULL }, // 821 +{ NULL, NULL }, // 822 +{ NULL, NULL }, // 823 +{ NULL, NULL }, // 824 +{ NULL, NULL }, // 825 +{ NULL, NULL }, // 826 +{ NULL, NULL }, // 827 +{ NULL, NULL }, // 828 +{ NULL, NULL }, // 829 +{ NULL, NULL }, // 830 +{ NULL, NULL }, // 831 +{ NULL, NULL }, // 832 +{ NULL, NULL }, // 833 +{ NULL, NULL }, // 834 +{ NULL, NULL }, // 835 +{ NULL, NULL }, // 836 +{ NULL, NULL }, // 837 +{ NULL, NULL }, // 838 +{ NULL, NULL }, // 839 +{ NULL, NULL }, // 840 +{ NULL, NULL }, // 841 +{ NULL, NULL }, // 842 +{ NULL, NULL }, // 843 +{ NULL, NULL }, // 844 +{ NULL, NULL }, // 845 +{ NULL, NULL }, // 846 +{ NULL, NULL }, // 847 +{ NULL, NULL }, // 848 +{ NULL, NULL }, // 849 +{ NULL, NULL }, // 850 +{ NULL, NULL }, // 851 +{ NULL, NULL }, // 852 +{ NULL, NULL }, // 853 +{ NULL, NULL }, // 854 +{ NULL, NULL }, // 855 +{ NULL, NULL }, // 856 +{ NULL, NULL }, // 857 +{ NULL, NULL }, // 858 +{ NULL, NULL }, // 859 +{ NULL, NULL }, // 860 +{ NULL, NULL }, // 861 +{ NULL, NULL }, // 862 +{ NULL, NULL }, // 863 +{ NULL, NULL }, // 864 +{ NULL, NULL }, // 865 +{ NULL, NULL }, // 866 +{ NULL, NULL }, // 867 +{ NULL, NULL }, // 868 +{ NULL, NULL }, // 869 +{ NULL, NULL }, // 870 +{ NULL, NULL }, // 871 +{ NULL, NULL }, // 872 +{ NULL, NULL }, // 873 +{ NULL, NULL }, // 874 +{ NULL, NULL }, // 875 +{ NULL, NULL }, // 876 +{ NULL, NULL }, // 877 +{ NULL, NULL }, // 878 +{ NULL, NULL }, // 879 +{ NULL, NULL }, // 880 +{ NULL, NULL }, // 881 +{ NULL, NULL }, // 882 +{ NULL, NULL }, // 883 +{ NULL, NULL }, // 884 +{ NULL, NULL }, // 885 +{ NULL, NULL }, // 886 +{ NULL, NULL }, // 887 +{ NULL, NULL }, // 888 +{ NULL, NULL }, // 889 +{ NULL, NULL }, // 890 +{ NULL, NULL }, // 891 +{ NULL, NULL }, // 892 +{ NULL, NULL }, // 893 +{ NULL, NULL }, // 894 +{ NULL, NULL }, // 895 +{ NULL, NULL }, // 896 +{ NULL, NULL }, // 897 +{ NULL, NULL }, // 898 +{ NULL, NULL }, // 899 +{ NULL, NULL }, // 900 +{ NULL, NULL }, // 901 +{ NULL, NULL }, // 902 +{ NULL, NULL }, // 903 +{ NULL, NULL }, // 904 +{ NULL, NULL }, // 905 +{ NULL, NULL }, // 906 +{ NULL, NULL }, // 907 +{ NULL, NULL }, // 908 +{ NULL, NULL }, // 909 +{ NULL, NULL }, // 910 +{ NULL, NULL }, // 911 +{ NULL, NULL }, // 912 +{ NULL, NULL }, // 913 +{ NULL, NULL }, // 914 +{ NULL, NULL }, // 915 +{ NULL, NULL }, // 916 +{ NULL, NULL }, // 917 +{ NULL, NULL }, // 918 +{ NULL, NULL }, // 919 +{ NULL, NULL }, // 920 +{ NULL, NULL }, // 921 +{ NULL, NULL }, // 922 +{ NULL, NULL }, // 923 +{ NULL, NULL }, // 924 +{ NULL, NULL }, // 925 +{ NULL, NULL }, // 926 +{ NULL, NULL }, // 927 +{ NULL, NULL }, // 928 +{ NULL, NULL }, // 929 +{ NULL, NULL }, // 930 +{ NULL, NULL }, // 931 +{ NULL, NULL }, // 932 +{ NULL, NULL }, // 933 +{ NULL, NULL }, // 934 +{ NULL, NULL }, // 935 +{ NULL, NULL }, // 936 +{ NULL, NULL }, // 937 +{ NULL, NULL }, // 938 +{ NULL, NULL }, // 939 +{ NULL, NULL }, // 940 +{ NULL, NULL }, // 941 +{ NULL, NULL }, // 942 +{ NULL, NULL }, // 943 +{ NULL, NULL }, // 944 +{ NULL, NULL }, // 945 +{ NULL, NULL }, // 946 +{ NULL, NULL }, // 947 +{ NULL, NULL }, // 948 +{ NULL, NULL }, // 949 +{ NULL, NULL }, // 950 +{ NULL, NULL }, // 951 +{ NULL, NULL }, // 952 +{ NULL, NULL }, // 953 +{ NULL, NULL }, // 954 +{ NULL, NULL }, // 955 +{ NULL, NULL }, // 956 +{ NULL, NULL }, // 957 +{ NULL, NULL }, // 958 +{ NULL, NULL }, // 959 +{ NULL, NULL }, // 960 +{ NULL, NULL }, // 961 +{ NULL, NULL }, // 962 +{ NULL, NULL }, // 963 +{ NULL, NULL }, // 964 +{ NULL, NULL }, // 965 +{ NULL, NULL }, // 966 +{ NULL, NULL }, // 967 +{ NULL, NULL }, // 968 +{ NULL, NULL }, // 969 +{ NULL, NULL }, // 970 +{ NULL, NULL }, // 971 +{ NULL, NULL }, // 972 +{ NULL, NULL }, // 973 +{ NULL, NULL }, // 974 +{ NULL, NULL }, // 975 +{ NULL, NULL }, // 976 +{ NULL, NULL }, // 977 +{ NULL, NULL }, // 978 +{ NULL, NULL }, // 979 +{ NULL, NULL }, // 980 +{ NULL, NULL }, // 981 +{ NULL, NULL }, // 982 +{ NULL, NULL }, // 983 +{ NULL, NULL }, // 984 +{ NULL, NULL }, // 985 +{ NULL, NULL }, // 986 +{ NULL, NULL }, // 987 +{ NULL, NULL }, // 988 +{ NULL, NULL }, // 989 +{ NULL, NULL }, // 990 +{ NULL, NULL }, // 991 +{ NULL, NULL }, // 992 +{ NULL, NULL }, // 993 +{ NULL, NULL }, // 994 +{ NULL, NULL }, // 995 +{ NULL, NULL }, // 996 +{ NULL, NULL }, // 997 +{ "fhalls", "The Forgotten Halls" }, // 998 Index: mapcore.cpp =================================================================== RCS file: /cvsroot/seq/showeq/src/mapcore.cpp,v retrieving revision 1.5.16.2 retrieving revision 1.5.16.3 diff -u -d -r1.5.16.2 -r1.5.16.3 --- mapcore.cpp 13 Dec 2003 00:49:42 -0000 1.5.16.2 +++ mapcore.cpp 21 Feb 2005 05:56:14 -0000 1.5.16.3 @@ -66,6 +66,7 @@ m_showLines = true; m_showGridLines = true; m_showGridTicks = true; + m_optimization = tMap_NormalOptim; reset(); } Index: everquest.h =================================================================== RCS file: /cvsroot/seq/showeq/src/everquest.h,v retrieving revision 1.74.6.18 retrieving revision 1.74.6.19 diff -u -d -r1.74.6.18 -r1.74.6.19 --- everquest.h 9 Feb 2005 07:07:35 -0000 1.74.6.18 +++ everquest.h 21 Feb 2005 05:56:13 -0000 1.74.6.19 @@ -105,6 +105,7 @@ #define MAX_KNOWN_LANGS 25 #define MAX_SPELLBOOK_SLOTS 400 #define MAX_GROUP_MEMBERS 6 +#define MAX_BUFFS 25 //Item Flags #define ITEM_NORMAL 0x0000 @@ -247,14 +248,15 @@ }; /* -** Guild Update actions +** Group Update actions */ -enum GuildUpdateAction +enum GroupUpdateAction { GUA_Joined = 0, GUA_Left = 1, GUA_LastLeft = 6, GUA_FullGroupInfo = 7, + GUA_MakeLeader = 8, GUA_Started = 9, }; @@ -520,7 +522,7 @@ /* ** Player Profile -** Length: 18288 Octets +** Length: 18496 Octets ** OpCode: CharProfileCode */ struct charProfileStruct @@ -608,7 +610,7 @@ /*4132*/ uint8_t unknown4132[408]; // *** Placeholder /*4540*/ uint32_t zoneId; // see zones.h /*4544 uint32_t zoneInstance; // Used to be here... */ -/*4544*/ spellBuff buffs[20]; // Buffs currently on the player +/*4544*/ spellBuff buffs[MAX_BUFFS]; // Buffs currently on the player /*4864*/ char groupMembers[MAX_GROUP_MEMBERS][64];// all the members in group, including self /*5248*/ uint8_t unknown5248[668]; // *** Placeholder /*5916*/ uint32_t ldon_guk_points; // Earned GUK points @@ -624,7 +626,7 @@ /*6652*/ uint8_t unknown6652[4888]; // *** Placeholder /*11540*/ uint16_t altexp; // Total aaxp points /*11542*/ uint8_t unknown11542[6874]; // *** Placeholder -}; /* 18416 */ +}; /* 18496 */ #if 1 struct playerAAStruct { @@ -1181,23 +1183,23 @@ /* ** Grouping Infromation -** Length: 136 Octets +** Length: 452 Octets ** OpCode: OP_GroupUpdate */ struct groupUpdateStruct { -/*0000*/ int32_t action; -/*0004*/ char yourname[64]; // Player Name -/*0068*/ char membername[64]; // Goup Member Name -/*0132*/ uint32_t unknown0132; // ***Placeholder -/*0136*/ +/*0000*/ int32_t action; // Group update action +/*0004*/ char yourname[64]; // Group Member Names +/*0068*/ char membername[64]; // Group leader name +/*0132*/ uint8_t unknown0132[320]; // ***Placeholder +/*452*/ }; /* ** Grouping Infromation -** Length: 452 Octets +** Length: 768 Octets ** OpCode: OP_GroupUpdate */ @@ -1205,8 +1207,9 @@ { /*0000*/ int32_t action; /*0004*/ char membernames[MAX_GROUP_MEMBERS][64]; // Group Member Names -/*0388*/ char leader[64]; // Goup Member Name -/*0452*/ +/*0388*/ char leader[64]; // Group leader Name +/*0452*/ char unknown0452[316]; // ***Placeholder +/*0768*/ }; /* @@ -1676,7 +1679,7 @@ /* ** Random Number Request -** Length: 10 Octets +** Length: 8 Octets ** OpCode: RandomCode */ struct randomReqStruct @@ -1687,7 +1690,7 @@ /* ** Random Number Result -** Length: 78 Octets +** Length: 76 Octets ** OpCode: RandomCode */ struct randomStruct @@ -1722,7 +1725,7 @@ /* ** Self Position Update -** Length: 32 Octets +** Length: 30 Octets ** OpCode: PlayerPosCode */ Index: packetinfo.cpp =================================================================== RCS file: /cvsroot/seq/showeq/src/Attic/packetinfo.cpp,v retrieving revision 1.1.4.3 retrieving revision 1.1.4.4 diff -u -d -r1.1.4.3 -r1.1.4.4 --- packetinfo.cpp 7 Nov 2004 23:10:23 -0000 1.1.4.3 +++ packetinfo.cpp 21 Feb 2005 05:56:14 -0000 1.1.4.4 @@ -64,6 +64,8 @@ EQPacketTypeDB::EQPacketTypeDB() : m_typeSizeDict(127) // increase this number if we ever get >= 97 types { + m_typeSizeDict.setAutoDelete(true); + // define the convenience macro used in the generated file #define AddStruct(typeName) addStruct(#typeName, sizeof(typeName)) Index: packet.cpp =================================================================== RCS file: /cvsroot/seq/showeq/src/packet.cpp,v retrieving revision 1.62.6.5 retrieving revision 1.62.6.6 diff -u -d -r1.62.6.5 -r1.62.6.6 --- packet.cpp 9 Feb 2005 07:07:37 -0000 1.62.6.5 +++ packet.cpp 21 Feb 2005 05:56:14 -0000 1.62.6.6 @@ -61,6 +61,7 @@ const in_port_t WorldServerGeneralPort = 9000; const in_port_t WorldServerChatPort = 9876; +const in_port_t WorldServerChat2Port = 9875; //%%% what is this? const in_port_t LoginServerMinPort = 15900; const in_port_t LoginServerMaxPort = 15910; const in_port_t ChatServerPort = 5998; @@ -423,6 +424,7 @@ // Destructor EQPacket::~EQPacket() { + if (m_packetCapture != NULL) { // stop any packet capture @@ -457,6 +459,19 @@ delete m_world2ClientStream; delete m_client2ZoneStream; delete m_zone2ClientStream; + + if (m_packetTypeDB) + { + delete m_packetTypeDB; + } + if (m_zoneOPCodeDB) + { + delete m_zoneOPCodeDB; + } + if (m_worldOPCodeDB) + { + delete m_worldOPCodeDB; + } } /* Start the timer to process packets */ @@ -621,8 +636,8 @@ emit clientChanged(m_client_addr); seqInfo("Client Detected: %s", (const char*)m_ip); } - /* end client detection */ + /* Find the stream we are sending this to */ EQPacketStream* stream; @@ -635,6 +650,10 @@ (packet.getSourcePort() == WorldServerChatPort)) return; + if ((packet.getDestPort() == WorldServerChat2Port) || + (packet.getSourcePort() == WorldServerChat2Port)) + return; + if (((packet.getDestPort() >= LoginServerMinPort) && (packet.getDestPort() <= LoginServerMaxPort)) || (packet.getSourcePort() >= LoginServerMinPort) && @@ -665,10 +684,7 @@ // the stream the packet came from. packet.setSessionKey(stream->getSessionKey()); -#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1) - seqDebug("%s", (const char*)packet.headerFlags((PACKET_PROCESS_DIAG < 3))); -#endif - +#ifdef APPLY_CRC_CHECK // Check CRC. Have to ask the stream to do it, since the packet doesn't know // it's sessionKey yet. if (packet.hasCRC()) @@ -687,12 +703,14 @@ return; } } +#endif /* APPLY_CRC_CHECK */ /* discard pure ack/req packets */ if (packet.getNetOpCode() == OP_KeepAlive || packet.getNetOpCode() == OP_SessionStatRequest || packet.getNetOpCode() == OP_SessionStatResponse || - packet.getNetOpCode() == OP_Resend || + packet.getNetOpCode() == OP_AckFuture || + packet.getNetOpCode() == OP_AckAfterDisconnect || packet.getNetOpCode() == OP_Ack) { #if defined(PACKET_PROCESS_DIAG) Index: packetcapture.cpp =================================================================== RCS file: /cvsroot/seq/showeq/src/packetcapture.cpp,v retrieving revision 1.2.4.1 retrieving revision 1.2.4.2 diff -u -d -r1.2.4.1 -r1.2.4.2 --- packetcapture.cpp 7 Dec 2003 06:30:44 -0000 1.2.4.1 +++ packetcapture.cpp 21 Feb 2005 05:56:14 -0000 1.2.4.2 @@ -26,6 +26,25 @@ PacketCaptureThread::~PacketCaptureThread() { + // Drop the packets we have lying around + pthread_mutex_lock (&m_pcache_mutex); + + struct packetCache *pc = m_pcache_first; + struct packetCache* freeMe = NULL; + + while (pc) + { + freeMe = pc; + pc = pc->next; + + free(freeMe); + } + + m_pcache_first = NULL; + m_pcache_last = NULL; + m_pcache_closed = true; + + pthread_mutex_unlock (&m_pcache_mutex); } void PacketCaptureThread::start(const char *device, const char *host, bool realtime, uint8_t address_type) @@ -37,6 +56,7 @@ struct sched_param sp; seqInfo("Initializing Packet Capture Thread: "); + m_pcache_closed = false; // create pcap style filter expressions if (address_type == IP_ADDRESS_TYPE) @@ -156,14 +176,21 @@ pc->next = NULL; pthread_mutex_lock (&myThis->m_pcache_mutex); - - if (myThis->m_pcache_last) + + if (! myThis->m_pcache_closed) + { + if (myThis->m_pcache_last) myThis->m_pcache_last->next = pc; - myThis->m_pcache_last = pc; + myThis->m_pcache_last = pc; - if (!myThis->m_pcache_first) + if (!myThis->m_pcache_first) myThis->m_pcache_first = pc; + } + else + { + free(pc); + } pthread_mutex_unlock (&myThis->m_pcache_mutex); } Index: packetlog.cpp =================================================================== RCS file: /cvsroot/seq/showeq/src/packetlog.cpp,v retrieving revision 1.1.6.6 retrieving revision 1.1.6.7 diff -u -d -r1.1.6.6 -r1.1.6.7 --- packetlog.cpp 9 Feb 2005 07:07:38 -0000 1.1.6.6 +++ packetlog.cpp 21 Fe... [truncated message content] |