X-Git-Url: https://code.delx.au/pymsnt/blobdiff_plain/e06e8d57d0f3f6e5213288c51183c0acd84e0ecf..d4fbf2fdb81b1189654ea83c3faf005ed5f59f0e:/src/tlib/msn/msn.py diff --git a/src/tlib/msn/msn.py b/src/tlib/msn/msn.py index 23464de..1ad7cfd 100644 --- a/src/tlib/msn/msn.py +++ b/src/tlib/msn/msn.py @@ -99,7 +99,7 @@ import msnp11chl # Twisted imports from twisted.internet import reactor, task from twisted.internet.defer import Deferred -from twisted.internet.protocol import ClientFactory +from twisted.internet.protocol import ReconnectingClientFactory, ClientFactory try: from twisted.internet.ssl import ClientContextFactory except ImportError: @@ -847,9 +847,8 @@ class MSNEventBase(LineReceiver): self.setLineMode(extra) return except Exception, e: - log.msg("Traceback - ERROR in checkMessage: " + str(e)) self.setLineMode(extra) - return + raise self.gotMessage(m) self.setLineMode(extra) @@ -974,6 +973,7 @@ class NotificationClient(MSNEventBase): MSNEventBase.connectionMade(self) self._setState('CONNECTED') self.sendLine("VER %s %s" % (self._nextTransactionID(), MSN_PROTOCOL_VERSION)) + self.factory.resetDelay() def connectionLost(self, reason): self._setState('DISCONNECTED') @@ -1387,6 +1387,7 @@ class NotificationClient(MSNEventBase): def handle_OUT(self, params): checkParamLen(len(params), 1, 'OUT') + self.factory.stopTrying() if params[0] == "OTH": self.multipleLogin() elif params[0] == "SSD": self.serverGoingDown() else: raise MSNProtocolError, "Invalid Parameters received for OUT" # debug @@ -1992,10 +1993,11 @@ class NotificationClient(MSNEventBase): if self.pingCheckTask: self.pingCheckTask.stop() self.pingCheckTask = None + self.factory.stopTrying() self.sendLine("OUT") self.transport.loseConnection() -class NotificationFactory(ClientFactory): +class NotificationFactory(ReconnectingClientFactory): """ Factory for the NotificationClient protocol. This is basically responsible for keeping @@ -2018,6 +2020,8 @@ class NotificationFactory(ClientFactory): (the whole URL is required) @ivar status: The status of the client -- this is generally kept up to date by the default command handlers + @ivar maxRetries: The number of times the factory will reconnect + if the connection dies because of a network error. """ contacts = None @@ -2027,6 +2031,7 @@ class NotificationFactory(ClientFactory): passportServer = 'https://nexus.passport.com/rdr/pprdr.asp' status = 'FLN' protocol = NotificationClient + maxRetries = 5 class SwitchboardClient(MSNEventBase): @@ -2117,14 +2122,16 @@ class SwitchboardClient(MSNEventBase): if not message.getHeader("P2P-Dest") == self.userHandle: return packet = message.message binaryFields = BinaryFields(packet=packet) - if binaryFields[0] != 0: + if binaryFields[5] == BinaryFields.BYEGOT: + pass # Ignore the ACKs to SLP messages + elif binaryFields[0] != 0: slpLink = self.slpLinks.get(binaryFields[0]) if not slpLink: # Link has been killed. Ignore return if slpLink.remoteUser == message.userHandle: slpLink.handlePacket(packet) - if binaryFields[5] == BinaryFields.ACK or binaryFields[5] == BinaryFields.BYEGOT: + elif binaryFields[5] == BinaryFields.ACK: pass # Ignore the ACKs to SLP messages else: slpMessage = MSNSLPMessage(packet) @@ -2366,6 +2373,7 @@ class SwitchboardClient(MSNEventBase): def bufferClosed(data): d.callback((data,)) buffer = StringBuffer(bufferClosed) + buffer.error = lambda: None slpLink = SLPLink_AvatarReceive(remoteUser=msnContact.userHandle, switchboard=self, consumer=buffer, context=msnContact.msnobj.text) self.slpLinks[slpLink.sessionID] = slpLink return d @@ -2719,7 +2727,9 @@ class SLPLink: self.seqID = SeqID() def killLink(self): + if MSNP2PDEBUG: log.msg("killLink") def kill(): + if MSNP2PDEBUG: log.msg("killLink - kill()") if not self.switchboard: return del self.switchboard.slpLinks[self.sessionID] self.switchboard = None @@ -2862,7 +2872,7 @@ class SLPLink_FileSend(SLPLink_Send): else: if slpMessage.status == "603": self.acceptDeferred.callback((False,)) - # SLPLink is over due to decline, error or BYE + if MSNP2PDEBUG: log.msg("SLPLink is over due to decline, error or BYE") self.killLink() def wait_data_ack(self, packet): @@ -2891,7 +2901,8 @@ class SLPLink_AvatarSend(SLPLink_Send): self.handlePacket = lambda packet: None def handleSLPMessage(self, slpMessage): - self.killLink() # BYE or error + if MSNP2PDEBUG: log.msg("BYE or error") + self.killLink() def close(self): SLPLink_Send.close(self) @@ -2980,6 +2991,7 @@ class SLPLink_FileReceive(SLPLink_Receive, FileReceive): FileReceive.accept(self, consumer) if not self.switchboard: return self.sendSLPMessage("200", "application/x-msnmsgr-sessionreqbody", {"SessionID":self.sessionID}, branch=self.initialBranch) + self.handlePacket = self.wait_data # Moved here because sometimes the second INVITE seems to be skipped def handleSLPMessage(self, slpMessage): if slpMessage.method == "INVITE": # The second invite @@ -2987,9 +2999,10 @@ class SLPLink_FileReceive(SLPLink_Receive, FileReceive): "Listening" : "false",\ "Hashed-Nonce": "{00000000-0000-0000-0000-000000000000}"} self.sendSLPMessage("200", "application/x-msnmsgr-transrespbody", data, branch=slpMessage.branch) - self.handlePacket = self.wait_data +# self.handlePacket = self.wait_data # Moved up else: - self.killLink() # It's either a BYE or an error + if MSNP2PDEBUG: log.msg("It's either a BYE or an error") + self.killLink() # FIXME, do some error handling if it was an error def doFinished(self): @@ -3007,12 +3020,14 @@ class SLPLink_AvatarReceive(SLPLink_Receive): "AppID" : 1,\ "Context" : context} self.sendSLPMessage("INVITE", "application/x-msnmsgr-sessionreqbody", data) + self.handlePacket = self.wait_dataprep def handleSLPMessage(self, slpMessage): if slpMessage.status == "200": - self.handlePacket = self.wait_dataprep + pass + #self.handlePacket = self.wait_dataprep # Moved upwards else: - # SLPLink is over due to error or BYE + if MSNP2PDEBUG: log.msg("SLPLink is over due to error or BYE") self.killLink() def doFinished(self):