def handle_MSG(self, data): sid, msg = data.split(" ", 1) if "NI" in self.inf: sid = self.inf["NI"] log.msg("%% <%s> %r" % (sid, unescape(msg)))
def test_unescape_ordering(self): i = "\\\\s" o = "\\s" self.assertEqual(unescape(i), o)
def test_unescape_space(self): i = "test\\sunescape" o = "test unescape" self.assertEqual(unescape(i), o)
def handle_QUI(self, data): log.msg("%% %s quit: %r" % (self.sid, unescape(data))) self.transport.loseConnection()
def handle_STA(self, data): code, description = data.split(" ", 1) log.msg("%% STA %% %r" % (code, unescape(description)))
def lineReceived(self, line): # Some clients occasionally send bare newlines as a form of keepalive. # Discard them immediately without logging; this is not a problem but # there is nothing that needs to be done. if not line: return log.msg("%s > %r" % (self.sid, line)) try: where, what, rest = split_line(line) except IndexError: log.msg("! Bad line %r" % line) return # Dispatch and update our internal state first. attr = getattr(self, "handle_%s" % what, None) if attr is None: log.msg("! Can't handle %s" % what) else: attr(rest) if where == "B": # Rebroadcast to everybody, as long as this client's acutally # authenticated. if self.state != "NORMAL": return if what == "INF": # INF needs to be rebuilt. inf = self.build_inf() self.factory.broadcast("INF", inf) elif what == "MSG": # It's chat; broadcast it using the chat interface. sender, message = rest.split(" ", 1) self.factory.chat(sender, unescape(message)) else: self.factory.broadcast(what, rest) elif where == "D": # Send to just one specific SID. sender, receiver, chaff = rest.split(" ", 2) if not self.factory.direct(receiver, what, rest): # Couldn't send the message. Let's the sender know that the # receiver doesn't exist. # This particular trick is due to the curious way that DC++ # and relatives have chosen to architect their list of peers. # DC++ insists that a peer is valid based on its CID, and will # ignore updates to that CID made under a new SID. So, if DC++ # ever believes that a CID is already connected to the hub # under an old SID, it will *ignore* any other clients with # that same CID. Frustrating. # The only place in the DC++ code that we can get a user # removed from the peer list is in the handler for QUI, which # will discard a user if DI is set. This is definitely # overkill, and rude, but there's not much else we can do. self.sendLine("IQUI %s DI1" % receiver) elif where == "E": # Send it to a specific SID, and also echo it back to the sender. sender, receiver, chaff = rest.split(" ", 2) if self.factory.direct(receiver, what, rest): # Echo. self.sendLine(line) else: # See comment above. self.sendLine("IQUI %s DI1" % receiver)