//////////////////////////////////////////////////// // stream reset void EQPacketStream::reset() { resetCache(); m_fragment.reset(); m_arqSeqExp = 0; m_arqSeqFound = false; }
void KisSelectionBasedLayer::setY(qint32 y) { if (m_d->selection) { m_d->selection->setY(y); resetCache(); } }
void Cache::initialize() { Filter::initialize(); resetCache(); return; }
void KisSelectionBasedLayer::setX(qint32 x) { if (m_d->selection) { m_d->selection->setX(x); resetCache(); } }
//////////////////////////////////////////////////// // stream reset void EQPacketStream::reset() { resetCache(); m_fragment.reset(); m_arqSeqExp = 0; m_arqSeqFound = false; m_sessionClientPort = 0; m_sessionId = 0; m_sessionKey = 0; }
void Outline::selectRoots() //------------------------- { OutlineRootSelect sel( this, _sentinel ); if( sel.process() ) { scrollToSelected(); resetCache(); reset(); } }
void Outline::resetOutline() //-------------------------- // reset to initial state { delete _sentinel; // kill all elements _sentinel = new OutlineElement; resetCache(); if( _findStack ) { _findStack->clear(); } }
void BaseSynthEvent::calculateBuffers() { if ( _locked ) { _updateAfterUnlock = true; return; } int oldLength; if ( isSequenced ) { _cancel = true; oldLength = _sampleLength; _sampleLength = ( int )( length * ( float ) AudioEngine::bytes_per_tick ); _sampleStart = position * AudioEngine::bytes_per_tick; _sampleEnd = _sampleStart + _sampleLength; } else { // quick releases of a noteOn-instruction should ring for at least a 64th note _minLength = AudioEngine::bytes_per_bar / 64; _sampleLength = AudioEngine::bytes_per_bar; // important for amplitude swell in oldLength = AudioEngineProps::BUFFER_SIZE; // buffer is as long as the engine's buffer size _hasMinLength = false; // keeping track if the min length has been rendered } _adsr->setBufferLength( _sampleLength ); // sample length changed (f.i. tempo change) or buffer not yet created ? // create buffer for (new) sample length if ( _sampleLength != oldLength || _buffer == 0 ) { // note that when event caching is enabled, the buffer is as large as // the total event length requires if ( AudioEngineProps::EVENT_CACHING && isSequenced ) { destroyBuffer(); // clear previous buffer contents _buffer = new AudioBuffer( AudioEngineProps::OUTPUT_CHANNELS, _sampleLength ); } else _buffer = new AudioBuffer( AudioEngineProps::OUTPUT_CHANNELS, AudioEngineProps::BUFFER_SIZE ); } if ( AudioEngineProps::EVENT_CACHING && isSequenced ) { resetCache(); // yes here, not in cache()-invocation as cancels might otherwise remain permanent (see BulkCacher) if ( _autoCache && !_caching ) // re-cache cache( false ); } }
void FalseColorModel::setMultiImg(representation::t type, SharedMultiImgPtr shared_img) { // in the future, we might be interested in the other ones as well. // currently, we don't process other types, so "warn" the caller assert(type == representation::IMG || type == representation::GRAD); if (type == representation::IMG) this->shared_img = shared_img; else if (type == representation::GRAD) this->shared_grad = shared_img; resetCache(); }
void Outline::toggleExpand( WWindow * ) //------------------------------------- { OutlineElement * elm; elm = element( selected() ); REQUIRE( elm != NULL, "Outline::toggleExpand" ); if( elm->state() != OutlineElement::ESLeaf ) { elm->toggleExpand(); resetCache(); reset(); // paranoia } }
void Outline::findNext() //---------------------- { BusyNotice busy( "Searching..." ); OutlineElement * elm; int i; elm = _findStack->removeLast(); while( elm != NULL ) { _findStack->append( elm ); if( elm->_child ) { elm = elm->_child; } else { elm = _findStack->removeLast(); // remove self from stack -- done while( elm->_lastSib ) { // remove finished parents elm = _findStack->removeLast(); } elm = elm->_sibling; } if( elm && _findFilter->matches( elm->symbol() ) ) { _findStack->append( elm ); break; } } if( !elm ) { errMessage( "Not Found" ); // FIXME -- not an error, don't use errMessage _findStack->clear(); menuManager()->enableMenu( MIMenuID(MMLocate,LMFindNext), false ); } else { // expand all the parent nodes of this one (they are stored // in the find stack), but don't expand this node itself for( i = _findStack->entries() - 1; i > 0; i -= 1 ) { (*_findStack)[ i - 1 ]->expand( false ); } for( i = 0; i < count(); i += 1 ) { if( elm == element( i ) ) { select( i ); } } resetCache(); reset(); scrollToSelected(); menuManager()->enableMenu( MIMenuID(MMLocate,LMFindNext), true ); } }
OutlineElement * Outline::element( int index ) //-------------------------------------------- { if( _cacheIndex > index ) { resetCache(); } while( (_cacheIndex < index) && (_cacheElement != NULL) ) { _cacheElement = _cacheElement->next(); _cacheIndex += 1; } if( _cacheIndex == index ) { return _cacheElement; } else { return NULL; } }
Outline::Outline( const char * text ) : HotWindowList( text ) , GlobalViewTree( menuManager() ) , _findStack( NULL ) //---------------------------------------------------------------- { _sentinel = new OutlineElement; _queryConfig = new QueryConfig( this, "Find" ); _findFilter = new KeySymbol; _loadFilter = new KeySymbol( WBRWinBase::optManager()->getQueryFilt() ); onHotPress( this, (cbw) &Outline::toggleExpand ); onDblClick( this, (cbw) &Outline::detailView ); onChanged( this, (cbw) &Outline::changed ); menuManager()->trackPopup( this, MMTree ); viewManager()->registerForEvents( this ); resetCache(); }
FalseColorModel::FalseColorModel(QObject *parent ) : QObject(parent) { int type = QMetaType::type("FalseColoring"); if (type == 0 || !QMetaType::isRegistered(type)) qRegisterMetaType<FalseColoring::Type>("FalseColoring"); type = QMetaType::type("std::map<std::string, boost::any>"); if (type == 0 || !QMetaType::isRegistered(type)) qRegisterMetaType< std::map<std::string, boost::any> >( "std::map<std::string, boost::any>"); foreach(FalseColoring::Type c, FalseColoring::all()) { pendingRequests[c] = false; } foreach(representation::t type, representation::all()) { representationInit[type] = false; } resetCache(); }
void Outline::treeViewEvent( TreeViewEvent event ) //------------------------------------------------ { OutlineElement * elm; elm = element( selected() ); switch( event ) { case ShowDetail: if( elm && elm->_symbol ) { popDetail( elm->_symbol ); } break; case ShowDefinition: if( elm && elm->_symbol ) { browseTop->showSource( elm->_symbol ); } break; case ShowReferences: if( elm && elm->_symbol ) { viewManager()->showDetailView( elm->_symbol, DetailView::ViewSourceRefs ); } break; case ShowUsers: if( elm && elm->_symbol ) { viewManager()->showDetailView( elm->_symbol, DetailView::ViewSymbolRefs ); } break; case ScrollToSelected: scrollToSelected(); break; case SelectRoots: selectRoots(); break; case ExpandOne: elm->expand( false ); resetCache(); reset(); // paranoia break; case ExpandBranch: elm->expand( true ); resetCache(); reset(); // paranoia break; case ExpandAll: for( elm = _sentinel->next(); elm != NULL; elm = elm->visibleSib() ) { elm->expand( true ); } resetCache(); reset(); // paranoia break; case CollapseBranch: if( elm->state() == OutlineElement::ESExpanded ) { elm->collapse( false ); resetCache(); reset(); // paranoia } break; case CollapseAll: for( elm = _sentinel->next(); elm != NULL; elm = elm->visibleSib() ) { elm->collapse( true ); } resetCache(); reset(); // paranoia break; default: NODEFAULT; } }
void CQBaseDataModel::setDataModel(CCopasiDataModel * pDataModel) { mpDataModel = pDataModel; resetCache(); }
bool CQBaseDataModel::clear() { resetCache(); return removeRows(0, rowCount() - 1); }
void SynthEvent::calculateBuffers() { if ( _locked ) { _updateAfterUnlock = true; return; } int oldLength; if ( isSequenced ) { if ( _caching ) _cancel = true; oldLength = _sampleLength; _sampleLength = ( int )( length * ( float ) AudioEngine::bytes_per_tick ); _sampleStart = position * AudioEngine::bytes_per_tick; _sampleEnd = _sampleStart + _sampleLength; } else { // quick releases of the key should at least ring for a 32nd note _minLength = AudioEngine::bytes_per_bar / 32; _sampleLength = AudioEngine::bytes_per_bar; // important for amplitude swell in oldLength = AudioEngineProps::BUFFER_SIZE; // buffer is as long as the engine's buffer size _hasMinLength = false; // keeping track if the min length has been rendered } _adsr->setBufferLength( _sampleLength ); // sample length changed (f.i. tempo change) or buffer not yet created ? // create buffer for (new) sample length if ( _sampleLength != oldLength || _buffer == 0 ) { destroyBuffer(); // clear previous buffer contents // OSC2 generates no buffer (writes into parent buffer, saves memory) if ( !hasParent ) { // note that when event caching is enabled, the buffer is as large as // the total event length requires if ( AudioEngineProps::EVENT_CACHING && isSequenced ) _buffer = new AudioBuffer( AudioEngineProps::OUTPUT_CHANNELS, _sampleLength ); else _buffer = new AudioBuffer( AudioEngineProps::OUTPUT_CHANNELS, AudioEngineProps::BUFFER_SIZE ); } } if ( isSequenced ) { if ( _type == WaveForms::KARPLUS_STRONG ) initKarplusStrong(); if ( AudioEngineProps::EVENT_CACHING ) { resetCache(); // yes here, not in cache()-invocation as cancels might otherwise remain permanent (see BulkCacher) // (re)cache (unless this event is OSC2 as only the parent event can invoke the render) if ( _autoCache && !hasParent ) { if ( !_caching ) cache( false ); else _cancel = true; } } } }
void Cache::resetCache(boost::uint32_t maxCacheBlocks, boost::uint32_t cacheBlockSize) { m_maxCacheBlocks = maxCacheBlocks; m_cacheBlockSize = cacheBlockSize; resetCache(); }
void SynthEvent::calculateBuffers() { // we override the entire function body as we need some // oscillator 2-specific operations in here if ( _locked ) { _updateAfterUnlock = true; return; } int oldLength; if ( isSequenced ) { _cancel = true; oldLength = _sampleLength; _sampleLength = ( int )( length * ( float ) AudioEngine::bytes_per_tick ); _sampleStart = position * AudioEngine::bytes_per_tick; _sampleEnd = _sampleStart + _sampleLength; } else { // quick releases of a noteOn-instruction should ring for at least a 64th note _minLength = AudioEngine::bytes_per_bar / 64; _sampleLength = AudioEngine::bytes_per_bar; // important for amplitude swell in oldLength = AudioEngineProps::BUFFER_SIZE; // buffer is as long as the engine's buffer size _hasMinLength = false; // keeping track if the min length has been rendered } _adsr->setBufferLength( _sampleLength ); // sample length changed (f.i. tempo change) or buffer not yet created ? create buffer for (new) length if ( _sampleLength != oldLength ) { if ( !hasParent ) // OSC2 generates no buffer (writes into parent buffer, saves memory) { // note that when event caching is enabled, the buffer is as large as // the total event length requires if ( AudioEngineProps::EVENT_CACHING && isSequenced ) { destroyBuffer(); // clear previous buffer contents _buffer = new AudioBuffer( AudioEngineProps::OUTPUT_CHANNELS, _sampleLength ); } else _buffer = new AudioBuffer( AudioEngineProps::OUTPUT_CHANNELS, AudioEngineProps::BUFFER_SIZE ); // though this event manages its child oscillator, the render method needs these properties if ( _osc2 != 0 ) { _osc2->_sampleLength = _sampleLength; _osc2->_sampleStart = _sampleStart; _osc2->_sampleEnd = _sampleEnd; } } } if ( isSequenced ) { if ( _type == WaveForms::KARPLUS_STRONG ) initKarplusStrong(); if ( AudioEngineProps::EVENT_CACHING ) { resetCache(); // yes here, not in cache()-invocation as cancels might otherwise remain permanent (see BulkCacher) if ( _autoCache && !_caching ) // re-cache cache( false ); } } }
int main() { resetCache(); __int64 allSolutions = findOutSolutions(20,20); printf("There are %I64d solutions\n", allSolutions); }
///////////////////////////////////////////////////// // Handle a protocol level packet. This could be either a top-level // EQUDPIPPacket or a subpacket that is just an EQProtocolPacket. Either way // we use net opcodes here. void EQPacketStream::processPacket(EQProtocolPacket& packet, bool /*isSubpacket*/) { #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("-->EQPacketStream::processPacket, subpacket=%s on stream %s (%d)", (isSubpacket ? "true" : "false"), EQStreamStr[m_streamid], m_streamid); #endif if (IS_APP_OPCODE(packet.getNetOpCode())) { // 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())); return; } // Process the net opcode switch (packet.getNetOpCode()) { case OP_Combined: { #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(), EQStreamStr[m_streamid], m_streamid); #endif // Rolled up multiple packets inside this packet. Need to unroll them // and process them individually. subpacket starts after the net opcode. uint8_t* subpacket = packet.payload(); while (subpacket < packet.payload() + packet.payloadLength()) { // Length specified first on the wire. uint8_t subpacketLength = subpacket[0]; // Move past the length subpacket++; // OpCode (in net order) uint16_t subOpCode = *(uint16_t*)subpacket; #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: unrolling length %d bytes from combined packet on stream %s (%d). Opcode %04x", subpacketLength, EQStreamStr[m_streamid], m_streamid, subOpCode); #endif // Opcode is next. Net opcode or app opcode? if (subOpCode == 0) { // App opcode < 0x00ff. Skip the first byte and dispatch the app // opcode appropriately subpacket++; subOpCode = *(uint16_t*)subpacket; #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: processing unrolled special app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", subpacketLength-3, EQStreamStr[m_streamid], m_streamid, subOpCode); #endif // App opcode. Dispatch it, skipping opcode. dispatchPacket(&subpacket[2], subpacketLength-2, subOpCode, m_opcodeDB.find(subOpCode)); } else if (IS_NET_OPCODE(subOpCode)) { #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: processing unrolled net opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", subpacketLength, EQStreamStr[m_streamid], m_streamid, subOpCode); #endif // Net opcode. false = copy. true = subpacket EQProtocolPacket spacket(subpacket, subpacketLength, false, true); processPacket(spacket, true); } else { #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: processing unrolled app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", subpacketLength-2, EQStreamStr[m_streamid], m_streamid, subOpCode); #endif // App opcode. Dispatch it, skipping opcode. dispatchPacket(&subpacket[2], subpacketLength-2, subOpCode, m_opcodeDB.find(subOpCode)); } subpacket += subpacketLength; } } break; case OP_AppCombined: { #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(), EQStreamStr[m_streamid], m_streamid); #endif // Multiple app op codes in the same packet. Need to unroll and dispatch // them. uint8_t* subpacket = packet.payload(); while (subpacket < packet.payload() + packet.payloadLength()) { // Length specified first on the wire. uint8_t subpacketLength = subpacket[0]; // Move past the length subpacket++; if (subpacketLength != 0xff) { // Dispatch app op code using given packet length. Net order! uint16_t subOpCode = *(uint16_t*)(subpacket); // Handle 3 byte opcodes properly if (subOpCode == 0) { // 3 byte opcode. Drop the first byte, opcode is byte 2 and 3 subpacket++; subpacketLength--; subOpCode = *(uint16_t*)(subpacket); } #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: unrolling length %d bytes from combined packet on stream %s (%d). Opcode %04x", subpacketLength, EQStreamStr[m_streamid], m_streamid, subOpCode); seqDebug("EQPacket: processing unrolled app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", subpacketLength-2, EQStreamStr[m_streamid], m_streamid, subOpCode); #endif // Dispatch, skipping op code. dispatchPacket(&subpacket[2], subpacketLength-2, subOpCode, m_opcodeDB.find(subOpCode)); // Move ahead subpacket += subpacketLength; } else { // If original length is 0xff, it means it is a long one. The length // is 2 bytes and next. uint16_t longOne = eqntohuint16(subpacket); // Move past the 2 byte length subpacket += 2; // OpCode next. Net order for op codes. uint16_t subOpCode = *(uint16_t*)subpacket; // Handle 3 byte opcodes properly if (subOpCode == 0) { // 3 byte opcode. Drop the first byte, opcode is byte 2 and 3 subpacket++; longOne--; subOpCode = *(uint16_t*)(subpacket); } #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: unrolling length %d bytes from combined packet on stream %s (%d). Opcode %04x", longOne, EQStreamStr[m_streamid], m_streamid, subOpCode); seqDebug("EQPacket: processing unrolled app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", longOne-2, EQStreamStr[m_streamid], m_streamid, subOpCode); #endif // Dispatch, skipping op code. dispatchPacket(&subpacket[2], longOne-2, subOpCode, m_opcodeDB.find(subOpCode)); // Move ahead subpacket += longOne; } } } break; case OP_Packet: { // Normal unfragmented sequenced packet. uint16_t seq = packet.arqSeq(); emit seqReceive(seq, (int)m_streamid); // Future packet? if (seq == m_arqSeqExp) { // Expected packet. m_arqSeqExp++; emit seqExpect(m_arqSeqExp, (int)m_streamid); // OpCode next. Net order for op codes. 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); #endif // Opcode is next. Net opcode or app opcode? if (subOpCode == 0) { // App opcode < 0x00ff. Skip the first byte and dispatch the app // opcode appropriately subOpCode = *(uint16_t*)&packet.payload()[1]; #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1) seqDebug("EQPacket: special app opcode extracted for opcode 0000 on stream %s (%d). Opcode %04x", EQStreamStr[m_streamid], m_streamid, subOpCode); #endif // App opcode. Dispatch it, skipping opcode. dispatchPacket(&packet.payload()[3], packet.payloadLength()-3, subOpCode, m_opcodeDB.find(subOpCode)); } else if (IS_NET_OPCODE(subOpCode)) { // Net opcode. false = no copy. true = subpacket. EQProtocolPacket spacket(packet.payload(), packet.payloadLength(), false, true); processPacket(spacket, true); } else { // App opcode. Dispatch, skipping opcode. dispatchPacket(&packet.payload()[2], packet.payloadLength()-2, subOpCode, m_opcodeDB.find(subOpCode)); } } else if ((seq > m_arqSeqExp && 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 { #ifdef PACKET_PROCESS_DIAG // Past packet outside the cut off seqWarn("SEQ: received sequenced %spacket outside expected window on stream %s (%d) netopcode=%04x size=%d. Expecting seq=%04x got seq=%04x, window size %d, dropping packet as in the past.", (isSubpacket ? "sub" : ""), EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(), packet.payloadLength(), m_arqSeqExp, seq, arqSeqWrapCutoff); #endif } } break; case OP_Oversized: { // Fragmented sequenced data packet. uint16_t seq = packet.arqSeq(); emit seqReceive(seq, (int)m_streamid); // Future packet? if (seq == m_arqSeqExp) { // Expected packet. m_arqSeqExp++; emit seqExpect(m_arqSeqExp, (int)m_streamid); #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)", EQStreamStr[m_streamid], m_streamid, seq, packet.getNetOpCode()); #endif // Push the fragment on. m_fragment.addFragment(packet); if (m_fragment.isComplete()) { // OpCode from fragment. In network order. uint16_t fragOpCode = *(uint16_t*)(m_fragment.data()); #ifdef PACKET_PROCESS_DIAG seqDebug("SEQ: Completed oversized app packet on stream %s with seq %04x, total size %d opcode %04x", EQStreamStr[m_streamid], seq, m_fragment.size()-2, fragOpCode); #endif // dispatch fragment. Skip opcode. if (fragOpCode == 0) { // Special app opcode. Skip first byte and op is byte 2 and 3. fragOpCode = *(uint16_t*)(&m_fragment.data()[1]); #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1) seqDebug("EQPacket: special app opcode on completed fragment for opcode 0000 on stream %s (%d). Opcode %04x", EQStreamStr[m_streamid], m_streamid, fragOpCode); #endif dispatchPacket(&m_fragment.data()[3], m_fragment.size()-3, fragOpCode, m_opcodeDB.find(fragOpCode)); } else { dispatchPacket(&m_fragment.data()[2], m_fragment.size()-2, fragOpCode, m_opcodeDB.find(fragOpCode)); } m_fragment.reset(); } } else if ((seq > m_arqSeqExp && 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 { #ifdef PACKET_PROCESS_DIAG // Past packet outside the cut off seqWarn("SEQ: received sequenced %spacket outside expected window on stream %s (%d) netopcode=%04x size=%d. Expecting seq=%04x got seq=%04x, window size %d, dropping packet as in the past.", (isSubpacket ? "sub" : ""), EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(), packet.payloadLength(), m_arqSeqExp, seq, arqSeqWrapCutoff); #endif } } break; case OP_SessionRequest: { // Session request from client to server. // // Sanity check the size. Don't assume any packet we see is an EQ // session request, since we're gonna cause a huge freakin' malloc // on the maxlength of the session which for some reason some people // won't enjoy! if (packet.payloadLength() != sizeof(SessionRequestStruct)) { // Either SessionRequestStruct changed or this isn't a session // request. #if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG) seqDebug("EQPacket: Ignoring SessionRequest %s:%u->%s:%u with invalid size %d.", ((EQUDPIPPacketFormat&) packet).getIPv4SourceA().ascii(), ((EQUDPIPPacketFormat&) packet).getSourcePort(), ((EQUDPIPPacketFormat&) packet).getIPv4DestA().ascii(), ((EQUDPIPPacketFormat&) packet).getDestPort(), packet.payloadLength()); #endif break; } // Pull off session request information SessionRequestStruct* request = (SessionRequestStruct*) packet.payload(); m_sessionId = eqntohuint32((uint8_t*)&(request->sessionId)); m_maxLength = eqntohuint32((uint8_t*)&(request->maxLength)); // Sanity check the max length requested if (m_maxLength > maxPacketSize) { seqWarn("EQPacket: SessionRequest wanted a max packet size of %d which is above our sane max packet size of %d. Using our max", m_maxLength, maxPacketSize); m_maxLength = maxPacketSize; } emit maxLength((int) m_maxLength, (int) m_streamid); #if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG) seqDebug("EQPacket: SessionRequest found, resetting expected seq, stream %s (%d) (session tracking %s)", 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) 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); #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; m_arqSeqFound = true; if (m_session_tracking_enabled) { // Save off client port for the stream so we can match against it // later. SessionRequest should always be an outer protocol packet // so we can cast it to EQUDPIPPacketFormat to get the ip headers. m_sessionClientPort = ((EQUDPIPPacketFormat&) packet).getSourcePort(); } } break; case OP_SessionResponse: { // Session response from server // Sanity check the size. Don't assume any packet we see is an EQ // session response, since we're gonna cause a huge freakin' malloc // on the maxlength of the session which for some reason some people // won't enjoy! if (packet.payloadLength() != sizeof(SessionResponseStruct)) { // Either SessionResponseStruct changed or this isn't a session // response. #if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG) seqDebug("EQPacket: Ignoring SessionResponse %s:%u->%s:%u with invalid size %d.", ((EQUDPIPPacketFormat&) packet).getIPv4SourceA().ascii(), ((EQUDPIPPacketFormat&) packet).getSourcePort(), ((EQUDPIPPacketFormat&) packet).getIPv4DestA().ascii(), ((EQUDPIPPacketFormat&) packet).getDestPort(), packet.payloadLength()); #endif break; } // Pull off session response information SessionResponseStruct* response = (SessionResponseStruct*) packet.payload(); m_maxLength = eqntohuint32((uint8_t*)&(response->maxLength)); m_sessionKey = eqntohuint32((uint8_t*)&(response->key)); m_sessionId = eqntohuint32((uint8_t*)&(response->sessionId)); // Sanity check the max length requested if (m_maxLength > maxPacketSize) { seqWarn("EQPacket: SessionResponse wanted a max packet size of %d which is above our sane max packet size of %d. Using our max", m_maxLength, maxPacketSize); m_maxLength = maxPacketSize; } emit maxLength((int) m_maxLength, (int) m_streamid); #if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG) 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"))); #endif #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); #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, eqntohuint16((uint8_t*)&(response->unknown0008)), 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); m_arqSeqExp = 0; m_arqSeqFound = true; // Session tracking if (m_session_tracking_enabled) { // Save off client port for the stream so we can match against it // later. SessionRequest should always be an outer protocol packet // so we can cast it to EQUDPIPPacketFormat to get the ip headers. m_sessionClientPort = ((EQUDPIPPacketFormat&) packet).getDestPort(); // If this is the world server talking to us, reset session tracking if // it is on so we unlatch the client in case of getting kicked. if (m_streamid == world2client) { m_session_tracking_enabled = 1; emit sessionTrackingChanged(m_session_tracking_enabled); } // If this is the zone server talking to us, close the latch and lock else if (m_streamid == zone2client) { // SessionResponse should always be an outer protocol packet, so // the EQProtocolPacket passed in can be cast back to // EQUDPIPPacketFormat, which we need to go to get access to the IP // headers! m_session_tracking_enabled = 2; emit lockOnClient(((EQUDPIPPacketFormat&) packet).getSourcePort(), ((EQUDPIPPacketFormat&) packet).getDestPort()); emit sessionTrackingChanged(m_session_tracking_enabled); } } } break; case OP_SessionDisconnect: { #if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG) 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 resetCache(); // Signal closing. Unlatch session tracking if it is on. if (m_session_tracking_enabled) { m_session_tracking_enabled = 1; emit sessionTrackingChanged(m_session_tracking_enabled); m_sessionClientPort = 0; } emit closing(m_sessionId, m_streamid); } break; case OP_Ack: case OP_AckFuture: case OP_AckAfterDisconnect: { #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: no-op on ACK for net opcode %04x seq %04x, stream %s (%d)", packet.getNetOpCode(), eqntohuint16(packet.payload()), EQStreamStr[m_streamid], m_streamid); #endif } break; case OP_KeepAlive: case OP_SessionStatRequest: case OP_SessionStatResponse: { #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: no-op on stats for net opcode %04x, stream %s (%d)", packet.getNetOpCode(), EQStreamStr[m_streamid], m_streamid); #endif } break; default : { seqWarn("EQPacket: Unhandled net opcode %04x, stream %s, size %d", packet.getNetOpCode(), EQStreamStr[m_streamid], packet.payloadLength()); } } }
///////////////////////////////////////////////////// // Handle a protocol level packet. This could be either a top-level // EQUDPIPPacket or a subpacket that is just an EQProtocolPacket. Either way // we use net opcodes here. void EQPacketStream::processPacket(EQProtocolPacket& packet, bool isSubpacket) { #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("-->EQPacketStream::processPacket, subpacket=%s on stream %s (%d)", (isSubpacket ? "true" : "false"), EQStreamStr[m_streamid], m_streamid); #endif if (IS_APP_OPCODE(packet.getNetOpCode())) { // 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())); return; } // Process the net opcode switch (packet.getNetOpCode()) { case OP_Combined: { #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(), EQStreamStr[m_streamid], m_streamid); #endif // Rolled up multiple packets inside this packet. Need to unroll them // and process them individually. subpacket starts after the net opcode. uint8_t* subpacket = packet.payload(); while (subpacket < packet.payload() + packet.payloadLength()) { // Length specified first on the wire. uint8_t subpacketLength = subpacket[0]; // Move past the length subpacket++; // OpCode (in net order) uint16_t subOpCode = *(uint16_t*)subpacket; #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: unrolling length %d bytes from combined packet on stream %s (%d). Opcode %04x", subpacketLength, EQStreamStr[m_streamid], m_streamid, subOpCode); #endif // Opcode is next. Net opcode or app opcode? if (IS_NET_OPCODE(subOpCode)) { #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: processing unrolled net opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", subpacketLength, EQStreamStr[m_streamid], m_streamid, subOpCode); #endif // Net opcode. false = copy. true = subpacket EQProtocolPacket spacket(subpacket, subpacketLength, false, true); processPacket(spacket, true); } else { #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: processing unrolled app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", subpacketLength-2, EQStreamStr[m_streamid], m_streamid, subOpCode); #endif // App opcode. Dispatch it, skipping opcode. dispatchPacket(&subpacket[2], subpacketLength-2, subOpCode, m_opcodeDB.find(subOpCode)); } subpacket += subpacketLength; } } break; case OP_AppCombined: { #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(), EQStreamStr[m_streamid], m_streamid); #endif // Multiple app op codes in the same packet. Need to unroll and dispatch // them. uint8_t* subpacket = packet.payload(); while (subpacket < packet.payload() + packet.payloadLength()) { // Length specified first on the wire. uint8_t subpacketLength = subpacket[0]; // Move past the length subpacket++; if (subpacketLength != 0xff) { // Dispatch app op code using given packet length. Net order! uint16_t subOpCode = *(uint16_t*)(subpacket); #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: unrolling length %d bytes from combined packet on stream %s (%d). Opcode %04x", subpacketLength, EQStreamStr[m_streamid], m_streamid, subOpCode); seqDebug("EQPacket: processing unrolled app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", subpacketLength-2, EQStreamStr[m_streamid], m_streamid, subOpCode); #endif // Dispatch, skipping op code. dispatchPacket(&subpacket[2], subpacketLength-2, subOpCode, m_opcodeDB.find(subOpCode)); // Move ahead subpacket += subpacketLength; } else { // If original length is 0xff, it means it is a long one. The length // is 2 bytes and next. uint16_t longOne = eqntohuint16(subpacket); // Move past the 2 byte length subpacket += 2; // OpCode next. Net order for op codes. uint16_t subOpCode = *(uint16_t*)subpacket; #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: unrolling length %d bytes from combined packet on stream %s (%d). Opcode %04x", longOne, EQStreamStr[m_streamid], m_streamid, subOpCode); seqDebug("EQPacket: processing unrolled app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", longOne-2, EQStreamStr[m_streamid], m_streamid, subOpCode); #endif // Dispatch, skipping op code. dispatchPacket(&subpacket[2], longOne-2, subOpCode, m_opcodeDB.find(subOpCode)); // Move ahead subpacket += longOne; } } } break; case OP_Packet: { // Normal unfragmented sequenced packet. uint16_t seq = eqntohuint16(packet.payload()); emit seqReceive(seq, (int)m_streamid); if (seq >= m_arqSeqExp) { // Future packet? if (seq == m_arqSeqExp) { // Expected packet. m_arqSeqExp++; emit seqExpect(m_arqSeqExp, (int)m_streamid); // OpCode next. Net order for op codes. uint16_t subOpCode = *(uint16_t*)(&packet.payload()[2]); #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); #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); processPacket(spacket, true); } else { // App opcode. Dispatch, skipping seq and opcode. dispatchPacket(&packet.payload()[4], packet.payloadLength()-4, subOpCode, m_opcodeDB.find(subOpCode)); } } 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. Expecting seq=%04x got seq=%04x, reasonableness being %d in the future.", (isSubpacket ? "sub" : ""), m_arqSeqExp, seq, arqSeqWrapCutoff); } } else { // Spooky packet from the past. Boo! #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(), EQStreamStr[m_streamid], m_streamid); #endif } } break; case OP_Oversized: { // Fragmented sequenced data packet. uint16_t seq = eqntohuint16(packet.payload()); 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 { // Expected packet. m_arqSeqExp++; emit seqExpect(m_arqSeqExp, (int)m_streamid); #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)", EQStreamStr[m_streamid], m_streamid, seq, packet.getNetOpCode()); #endif // Push the fragment on. m_fragment.addFragment(packet); if (m_fragment.isComplete()) { // OpCode from fragment. In network order. uint16_t fragOpCode = *(uint16_t*)(m_fragment.data()); #ifdef PACKET_PROCESS_DIAG seqDebug("SEQ: Completed oversized app packet on stream %s with seq %04x, total size %d opcode %04x", EQStreamStr[m_streamid], seq, m_fragment.size()-2, fragOpCode); #endif // dispatch fragment. Skip opcode. dispatchPacket(&m_fragment.data()[2], m_fragment.size()-2, fragOpCode, m_opcodeDB.find(fragOpCode)); m_fragment.reset(); } } } 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); #endif } } break; case OP_SessionRequest: { // Session request from client to server. #if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG) seqDebug("EQPacket: SessionRequest found, resetting expected seq, stream %s (%d) (session tracking %s)", EQStreamStr[m_streamid], m_streamid, (m_session_tracking_enabled == 2 ? "locked on" : (m_session_tracking_enabled == 1 ? "enabled" : "disabled"))); #endif // Pull off session request information 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); #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); #endif m_arqSeqExp = 0; m_arqSeqFound = true; } break; case OP_SessionResponse: { // 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)", EQStreamStr[m_streamid], m_streamid, (m_session_tracking_enabled == 2 ? "locked on" : (m_session_tracking_enabled == 1 ? "enabled" : "disabled"))); #endif // Pull off session response information SessionResponseStruct* response = (SessionResponseStruct*) packet.payload(); m_maxLength = eqntohuint32((uint8_t*)&(response->maxLength)); m_sessionKey = eqntohuint32((uint8_t*)&(response->key)); m_sessionId = eqntohuint32((uint8_t*)&(response->sessionId)); #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); #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, eqntohuint16((uint8_t*)&(response->unknown0008)), response->unknown0010, m_maxLength, eqntohuint32((uint8_t*) &(response->unknown0015))); #endif // Provide key to corresponding stream from this session/stream emit sessionKey(m_sessionId, m_streamid, m_sessionKey); m_arqSeqExp = 0; m_arqSeqFound = true; // Session tracking if (m_session_tracking_enabled) { // If this is the world server talking to us, reset session tracking if // it is on so we unlatch the client in case of getting kicked. if (m_streamid == world2client) { m_session_tracking_enabled = 1; emit sessionTrackingChanged(m_session_tracking_enabled); } // If this is the zone server talking to us, close the latch and lock else if (m_streamid == zone2client) { // SessionResponse should always be an outer protocol packet, so // the EQProtocolPacket passed in can be cast back to // EQUDPIPPacketFormat, which we need to go to get access to the IP // headers! m_session_tracking_enabled = 2; emit lockOnClient(((EQUDPIPPacketFormat&) packet).getSourcePort(), ((EQUDPIPPacketFormat&) packet).getDestPort()); emit sessionTrackingChanged(m_session_tracking_enabled); } } } break; 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)", EQStreamStr[m_streamid], m_streamid, (m_session_tracking_enabled == 2 ? "locked on" : (m_session_tracking_enabled == 1 ? "enabled" : "disabled"))); #endif m_arqSeqExp = 0; // Clear cache resetCache(); // Signal closing. Unlatch session tracking if it is on. if (m_session_tracking_enabled) { m_session_tracking_enabled = 1; emit sessionTrackingChanged(m_session_tracking_enabled); } emit closing(); } break; case OP_Ack: case OP_Resend: { #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()), EQStreamStr[m_streamid], m_streamid); #endif } break; case OP_KeepAlive: case OP_SessionStatRequest: case OP_SessionStatResponse: { #if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2) seqDebug("EQPacket: no-op on for net opcode %04x, stream %s (%d)", packet.getNetOpCode(), EQStreamStr[m_streamid], m_streamid); #endif } break; default : { seqWarn("EQPacket: Unhandled net opcode %04x, stream %s, size %d", packet.getNetOpCode(), EQStreamStr[m_streamid], packet.payloadLength()); } } }