#!/usr/bin/python3 # -*- coding: utf-8 -*- # # module CImpulseDecoder # # Copyright (C) 2019 AleaJactaEst # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import copy from tools import CActionFactory LOGGER='CImpulseDecoder' class CImpulseDecoder: ''' see : khanat-opennel-code/code/ryzom/client/src/impulse_decoder.cpp ''' def __init__(self, world): self.world = world self.reset() self._CActionFactory = CActionFactory.CActionFactory(world) def removeCAction(self, action): self._CActionFactory.RegisteredAction[action.Code].append(action) def decode(self, msgin, receivedPacket, receivedAck, nextSentPacket): ''' khanat-opennel-code/code/ryzom/client/src/impulse_decoder.cpp:38 void CImpulseDecoder::decode(CBitMemStream &inbox, TPacketNumber receivedPacket, TPacketNumber receivedAck, TPacketNumber nextSentPacket, vector &actions) ''' logging.getLogger(LOGGER).debug("*" * 80) logging.getLogger(LOGGER).debug("receivedPacket:%d receivedAck:%d nextSentPacket:%d" %(receivedPacket, receivedAck, nextSentPacket)) actions = [] for level in range(0, 3): logging.getLogger(LOGGER).debug("*" * 60) if level == 0: lAck = self._LastAck0 channel = 0 elif level == 1: lAck = self._LastAck1 channel = receivedPacket & 1 elif level == 2: lAck = self._LastAck2 channel = receivedPacket & 3 keep = True checkOnce = False num = 0 logging.getLogger(LOGGER).debug("level:%d channel:%d lAck:%s" %(level, channel, ':'.join([str(x) for x in lAck]))) # lastAck = lAck[channel] while True: logging.getLogger(LOGGER).debug("*" * 40) logging.getLogger(LOGGER).debug("[decoded] %s" % msgin.showAllData()) next = msgin.readBool('next:' + str(level) + ':' + str(channel)) if not next: break if not checkOnce: checkOnce = True keep = receivedAck >= lAck[channel] logging.getLogger(LOGGER).debug("keep:%s [%d => %d]" % (str(keep), receivedAck, lAck[channel])) if keep: lAck[channel] = nextSentPacket logging.getLogger(LOGGER).debug("lAck:%s" % ':'.join([str(x) for x in lAck])) num += 1 action = self._CActionFactory.unpack(msgin) if keep: logging.getLogger(LOGGER).debug("keep : %s" % str(action)) actions.append(copy.copy(action)) elif action: logging.getLogger(LOGGER).debug("append : %s" % str(action)) self.removeCAction(copy.copy(action)) logging.getLogger(LOGGER).debug('actions: ' +','.join( [ str(x) for x in actions] ) ) logging.getLogger(LOGGER).debug("*" * 80) return actions def reset(self): self._LastAck0 = [-1] self._LastAck1 = [-1, -1] self._LastAck2 = [-1, -1, -1, -1]