def _onmessage(self, event):
        if event.addr not in self.clients:
            self.clients[event.addr] = 0
            self.onclientjoin(obj(addr=event.addr))
        else:
            self.clients[event.addr] = 0

        header = bitm.Byte(bitm.ord(event.msg[0]))
        msg = event.msg[1:]

        if header.get(0) == NO_DATA:
            if header.get(1, 7) == CONNECT:
                res_header = bitm.Byte()
                res_header.set(0, NO_DATA)
                res_header.set(1, 7, CONNECT)
                self.socket.send(
                    header.chr() +
                    str(self.serverport + UNIQUE_BROADCAST_PORT), event.addr)

        elif header.get(0) == DATA:
            if header.get(1, 2) == NORMAL_MESSAGE:
                new_event = obj(header=header, msg=msg, addr=event.addr)
                self.onmessage(new_event)
            elif header.get(1, 2) == RELIABLE_MESSAGE:
                msgid_chr = msg[0]
                msgid = ord(msgid_chr)
                new_msg = msg[1:]

                res_header = bitm.Byte()
                res_header.set(0, DATA)
                res_header.set(1, 2, MESSAGE_RECEIVED)

                self.socket.send(res_header.chr() + msgid_chr, event.addr)

                tup = (event.addr, msgid)

                if tup not in self.received_reliable_messages or self.received_reliable_messages[
                        tup][1] != new_msg:
                    #                                   prev: 3*5+2
                    self.received_reliable_messages[tup] = [100, new_msg]

                    new_event = obj(header=header,
                                    msg=new_msg,
                                    addr=event.addr)
                    self.onmessage(new_event)
            elif header.get(1, 2) == MESSAGE_RECEIVED:
                self.sent_reliable_messages.pop((event.addr, ord(msg[0])),
                                                None)
    def sendr(self, msg):
        msgid = self.nextID()

        header = bitm.Byte()
        header.set(0, DATA)
        header.set(1, 2, RELIABLE_MESSAGE)
        message = header.chr() + chr(msgid) + msg
        # [ms * 10 to wait till retry, retry attempts left, message]
        self.sent_reliable_messages[msgid] = [1, 5, message]
        self._send(message)
    def _onmessage(self, event):
        header = bitm.Byte(bitm.ord(event.msg[0]))
        msg = event.msg[1:]

        if header.get(0) == NO_DATA:
            if header.get(1, 7) == CONNECT:
                port = int(msg)
                self.broadcastListener = Listener(BROADCAST, port)
                self.broadcastListener.onmessage = self._onmessage
                self.onconnect()
            elif header.get(1, 7) == DISCONNECT_WARNING:
                header = bitm.Byte()
                header.set(0, NO_DATA)
                header.set(1, 7, EMPTY)
                self._send(header.chr())

        elif header.get(0) == DATA:
            if header.get(1, 2) == MESSAGE_RECEIVED:
                self.sent_reliable_messages.pop(ord(msg[0]), None)
            elif header.get(1, 2) == RELIABLE_MESSAGE:
                msgid_chr = msg[0]
                msgid = ord(msgid_chr)
                new_msg = msg[1:]

                res_header = bitm.Byte()
                res_header.set(0, DATA)
                res_header.set(1, 2, MESSAGE_RECEIVED)

                self._send(res_header.chr() + msgid_chr)

                if msgid not in self.received_reliable_messages or self.received_reliable_messages[
                        msgid][1] != new_msg:
                    #                                     prev: 3 * 5 + 2
                    self.received_reliable_messages[msgid] = [100, new_msg]

                    new_event = obj(header=header, msg=new_msg)
                    self.onmessage(new_event)
            elif header.get(1, 2) == NORMAL_MESSAGE:
                new_event = obj(header=header, msg=msg, addr=event.addr)
                self.onmessage(new_event)
    def __init__(self, serverip, serverport):
        self.serveraddr = (serverip, serverport)
        self.socket = SLSocket()
        self.socket.onmessage = self._onmessage

        self.lastID = -1
        self.sent_reliable_messages = {}
        self.received_reliable_messages = {}

        header = bitm.Byte()
        header.set(0, NO_DATA)
        header.set(1, 7, CONNECT)
        self._send(header.chr())

        self.intervalId = intervals.add(10, self.every_ten_milliseconds)
    def dc_timer(self):
        to_delete = []

        for client in self.clients:
            self.clients[client] += 0.4
            if self.clients[client] >= int(self.dct):
                to_delete.append(client)
            elif self.clients[client] >= int(self.dcw):
                header = bitm.Byte()
                header.set(0, NO_DATA)
                header.set(1, 7, DISCONNECT_WARNING)
                self.socket.send(header.chr(), client)

        for client in to_delete:
            del self.clients[client]
            self.onclientleave(obj(addr=client))
 def send(self, msg):
     header = bitm.Byte()
     header.set(0, DATA)
     self._send(header.chr() + msg)
 def _send(self, msg, addr):
     header = bitm.Byte()
     header.set(0, DATA)
     self.socket.send(header.chr() + msg, addr)