def start(self): # Create server self.rpc_server = ThreadedXMLRPCServer((self.host, self.port), requestHandler=RequestHandler, logRequests=False) self.rpc_server.register_introspection_functions() # Register RPC functions. self.rpc_server.register_function(self.forwardMessage) self.rpc_server.register_function(self.registerNewPeer) self.rpc_server.register_function(self.leavePeer) server_thread = threading.Thread(name="server", target=self._server) server_thread.setDaemon(True) # Don't wait for server thread to exit. server_thread.start() queue_thread = threading.Thread(name="queue", target=self._queue_handler) queue_thread.setDaemon(True) # Don't wait for server thread to exit. queue_thread.start()
def start(self): if self.register: s = ServerProxy('http://' + self.routerHost + ':' + str(self.routerPort)) s.registerNewPeer(self.name, self.host, self.port) # Create server self.rpc_server = ThreadedXMLRPCServer((self.host, self.port), requestHandler=RequestHandler, logRequests=False) self.rpc_server.register_introspection_functions() # Register RPC functions. self.rpc_server.register_function(self.ReceiveMsg) server_thread = threading.Thread(name="server", target=self._server) server_thread.setDaemon(True) # Don't wait for server thread to exit. server_thread.start() if not self.manualOverride: out_of_range_check_thread = threading.Thread(name="out_of_range_check_thread", target=self._check_out_of_range) out_of_range_check_thread.setDaemon(True) # Don't wait for server thread to exit. out_of_range_check_thread.start() print("ready") self._main_loop()
class Peer(object): def __init__(self, register, name, host, port, routerHost, routerPort, manualOverride, clockSyncActive): self.name, self.host, self.port = name, host, port self.routerHost, self.routerPort = routerHost, routerPort self.manualOverride, self.clockSyncActive = manualOverride, clockSyncActive self.register = register # [{'song_name': 'Britney Spears - Toxic', 'votes': [{'peer_name': 'P1', 'sig': 'signature_on_song', 'pk': ..., 'pksign': ...}, {'peer_name': 'P2', 'sig': '...', ...}]] self.playlist = [] self.playlistLock = RLock() self.songplaying = None self.firstJoin = True self.progressLock = Lock() self.quitting = False keydist = KeyDistributer() self.key = keydist.getKeyPair() self.msg_count = 0 self.MSG_IDS_SEEN_MAXSIZE = 1000 self.msg_ids_seen = [-1] * self.MSG_IDS_SEEN_MAXSIZE self.msg_ids_seen_nextindex = 0 self.msg_ids_seen_lock = RLock() self.playlist_request_id = None self.playlists_received = 0 self.hasJoined = False self._time_since_last_msg = 0 self._time_since_last_msg_lock = Lock() self._top = [None] * LOCK_TOP # [('song', 42 votes), (...)] self._toplock = RLock() self.clock = Clock(self, sync=self.clockSyncActive) def start(self): if self.register: s = ServerProxy('http://' + self.routerHost + ':' + str(self.routerPort)) s.registerNewPeer(self.name, self.host, self.port) # Create server self.rpc_server = ThreadedXMLRPCServer((self.host, self.port), requestHandler=RequestHandler, logRequests=False) self.rpc_server.register_introspection_functions() # Register RPC functions. self.rpc_server.register_function(self.ReceiveMsg) server_thread = threading.Thread(name="server", target=self._server) server_thread.setDaemon(True) # Don't wait for server thread to exit. server_thread.start() if not self.manualOverride: out_of_range_check_thread = threading.Thread(name="out_of_range_check_thread", target=self._check_out_of_range) out_of_range_check_thread.setDaemon(True) # Don't wait for server thread to exit. out_of_range_check_thread.start() print("ready") self._main_loop() def _check_out_of_range(self): while True: time.sleep(OUT_OF_RANGE_CHECK_INTERVAL) if self.hasJoined: with self._time_since_last_msg_lock: self._time_since_last_msg += OUT_OF_RANGE_CHECK_INTERVAL if self._time_since_last_msg > OUT_OF_RANGE_TIME_LIMIT: self.hasJoined = False self._join() self._time_since_last_msg = 0 def _join(self): if not self.firstJoin: with self._toplock: for topitem in self._top: if topitem: (song_name, _) = topitem self._shout_votes(song_name) self.firstJoin = False self.playlists_received = 0 self.playlist_request_id = self._gen_msg_id() self._send_msg("GETLIST", {'request_id': self.playlist_request_id}) if not self.manualOverride: # Start join timeout join_timeout_thread = threading.Thread(name="join", target=self._join_timeout) join_timeout_thread.setDaemon(True) # Don't wait for thread to exit. join_timeout_thread.start() def _join_timeout(self): time.sleep(PLAYLIST_RECV_TIMEOUT_ON_JOIN) if not self.hasJoined: print("JOIN RETRY") self._join() # Retry def ReceiveMsg(self, msg_id, sender_peer_name, msgtype, argdict): if not self.quitting: recv_handler_thread = threading.Thread(name="recvhandler", target=self._handle_recv_message, args=[msg_id, sender_peer_name, msgtype, argdict]) recv_handler_thread.start() return '' def _handle_recv_message(self, msg_id, sender_peer_name, msgtype, argdict): # For some reason argdict values has turned into lists txt = self.name + ": GOTMSG of type " + msgtype + " from peer " + sender_peer_name + ": " + str(argdict) #logging.debug(txt) if self._shouldDropMsg(msg_id): print("DROPPED MSG") else: print(txt) if msgtype == "VOTE": #logging.debug(self.name + "HANDLE VOTE") self._forward_msg(msg_id, sender_peer_name, msgtype, argdict) # Forward self._handleVote(argdict['song_name'], argdict['vote']) elif msgtype == "VOTES": #logging.debug("GOT VOTESLIST of " + str(argdict['song_name'])) print("GOT VOTESLIST of " + str(argdict['song_name'])) self._handleVotes(str(argdict['song_name']), argdict['votes']) elif msgtype == "GETLIST": self._send_playlist(argdict['request_id']) elif msgtype == "PLAYLIST": print("GOT PLAYLIST") self._handle_playlist(sender_peer_name, argdict['request_id'], argdict['playlist']) elif msgtype == "CLOCKSYNC": self.clock.recv(int(argdict['t']), int(argdict['s']), sender_peer_name) return '' def _play_next(self): with self.playlistLock: with self._toplock: if not self._top[0]: print("NOTHING TO PLAY") else: (nextsong, _) = self._top[0] # Clean up top3songs = [] for i in range(0, LOCK_TOP-1): self._top[i] = self._top[i+1] if self._top[i]: (song, _) = self._top[i] top3songs.append(song) self._top[LOCK_TOP-1] = None # Remove played song for playlistitem in self.playlist: if playlistitem['song_name'] == nextsong: self.playlist.remove(playlistitem) break # Add new song to top maxcnt = 0 maxsong = None for playlistitem in self.playlist: if not playlistitem['song_name'] in top3songs: if self._compare_songs((playlistitem['song_name'], len(playlistitem['votes'])), (maxsong, maxcnt)): maxcnt = len(playlistitem['votes']) maxsong = playlistitem['song_name'] if maxsong: self._flush_top(maxsong, maxcnt) # Tell playtxt = "PLAYING " + nextsong logging.debug(playtxt) self.songplaying = nextsong logging.debug(str(self._top)) print(playtxt) print("TOP " + str(self._top)) def _addMsgId(self, msg_id): with self.msg_ids_seen_lock: self.msg_ids_seen[self.msg_ids_seen_nextindex] = msg_id self.msg_ids_seen_nextindex += 1 if self.msg_ids_seen_nextindex >= self.MSG_IDS_SEEN_MAXSIZE: self.msg_ids_seen_nextindex = 0 def _shouldDropMsg(self, msg_id): with self.msg_ids_seen_lock: if msg_id in self.msg_ids_seen: return True self._addMsgId(msg_id) return False def _shout_votes(self, songName): print("SHOUTING VOTES") for playlistitem in self.playlist: if playlistitem['song_name'] == songName: self._send_msg("VOTES", {'song_name': songName, 'votes': playlistitem['votes']}) break def _send_playlist(self, request_id): params = {'request_id': request_id, 'playlist': self.playlist} self._send_msg("PLAYLIST", params) def _handle_playlist(self, sender_peer_name, request_id, playlist): #TODO: Improve verification of playlist if self.playlist_request_id: if self._verifyPlaylist(playlist): if self.playlist_request_id == request_id: #logging.debug("A") self._updatePlaylist(playlist) #logging.debug("B") self.playlists_received += 1 if self.playlists_received > NR_PLAYLISTS_PREFERRED_ON_JOIN: self.hasJoined = True self.playlist_request_id = None def _handleVote(self, songName, vote): with self.playlistLock: if songName != self.songplaying: # Avoid same song being added immediatly again due to syncing print("##################HANDLING VOTE###############") if self._verifyPK(vote['pk'], vote['pksign']) and self._verifyVote(songName, vote): self._addVote(songName, vote) else: print('VOTE REJECTED') #logging.debug(self.name + "HANDLE VOTE from " + vote['peer_name']) def _handleVotes(self, songName, votes): with self.playlistLock: if songName != self.songplaying: # Avoid same song being added immediatly again due to syncing # Merge votes for vote in votes: self._addVote(songName, vote) def _flush_top(self, updated_song, new_vote_cnt): with self._toplock: inTop = False updated = False for i in range(0, LOCK_TOP): if self._top[i]: (songX, votecntX) = self._top[i] if updated_song == songX: inTop = True self._top[i] = (songX, new_vote_cnt) if new_vote_cnt != votecntX: updated = True break if not inTop: if not self._top[LOCK_TOP-1]: # If not specified yet #Find first empty position for i in range(0,LOCK_TOP): if not self._top[i]: self._top[i] = (updated_song, new_vote_cnt) updated = True break else: lastTopSongDesc = self._top[LOCK_TOP-1] if self._compare_songs((updated_song, new_vote_cnt), lastTopSongDesc): updated = True self._top[LOCK_TOP -1] = (updated_song, new_vote_cnt) # Update internally if updated: for i in range(LOCK_TOP-1, 0, -1): songdescX = self._top[i] songdescY = self._top[i-1] if self._compare_songs(songdescX, songdescY): self._top[i] = songdescY self._top[i-1] = songdescX if updated: # Flush votes for updated or new song in top X (vote sync) self._shout_votes(updated_song) def _compare_songs(self, songdesc1, songdesc2): # Returns true if first song has higher rank if not songdesc2: return True if not songdesc1: return False (song1, votecnt1) = songdesc1 (song2, votecnt2) = songdesc2 if votecnt1 > votecnt2 or (votecnt1 == votecnt2 and song1 < song2): return True return False def _addVote(self, songName, vote): with self.playlistLock: if songName != self.songplaying: # If exists added = False for playlistitem in self.playlist: if playlistitem['song_name'] == songName: if not vote['peer_name'] in [existingVote['peer_name'] for existingVote in playlistitem['votes']]: # The vote is not in the list, add it playlistitem['votes'].append(vote) self._flush_top(songName, len(playlistitem['votes'])) added = True break if not added: self.playlist.append({'song_name': songName, 'votes': [vote]}) self._flush_top(songName, 1) print("VOTE ADDED") def _updatePlaylist(self, recievedPlaylist): for song in recievedPlaylist: # Authenticate votes for vote in song['votes']: self._addVote(song['song_name'], vote) def _sign(self, obj): return self.key.signMessage(obj) def _hashOfPlaylist(self, playlist): result = SHA256.new() for songDescriptor in playlist: result.update(songDescriptor['song_name'].encode()) for vote in songDescriptor['votes']: result.update(vote['peer_name'].encode()) result.update(vote['sig'].encode()) result.update(vote['pk']) result.update(vote['pksign'].encode()) return result.digest() def _verifyPK(self, pk, pksign): return self.key.verifyPublicKey(pk, int(pksign)) def _verifyVote(self, songName, vote): return self.key.verifyMessage(vote['pk'], songName + vote['peer_name'], vote['sig']) and self._verifyPK(vote['pk'], vote['pksign']) def _verifyPlaylist(self, playlist): # Run through all votes for all songs and verify them for songDescripter in playlist: for vote in songDescripter['votes']: if not self._verifyVote(songDescripter['song_name'], vote): return False return True def _createVote(self, songName): """Creates a vote for a specific song""" return {'peer_name': self.name, 'sig': str(self.key.signMessage(songName + self.name)), 'pk': self.key.getPublicKey(), 'pksign': self.key.getPksign()} def _forward_msg(self, msg_id, sender_peer_name, msgtype, argdict): thread = threading.Thread(name="forward", target=self._do_send_msg, args=[msg_id, sender_peer_name, msgtype, argdict]) thread.start() return '' def _gen_msg_id(self): dt = datetime.now() self.msg_count += 1 msg_id = self.name + "_" + str(dt.microsecond) + str(self.msg_count) self._addMsgId(msg_id) return msg_id def _send_msg(self, msgtype, argdict): if not self.quitting: thread = threading.Thread(name="forward", target=self._do_send_msg, args=[self._gen_msg_id(), self.name, msgtype, argdict]) thread.start() return '' def _do_send_msg(self, msg_id, sender_peer_name, msgtype, argdict): s = ServerProxy('http://' + self.routerHost + ':' + str(self.routerPort)) s.forwardMessage(self.name, msg_id, sender_peer_name, msgtype, argdict) def _sendVote(self, songName, vote): params = {'song_name': songName, 'vote': vote} self._send_msg("VOTE", params) def _print_songlist(self, prefix, songlist): songlist_str = prefix + "#####" for songlistitem in songlist: songlist_str += songlistitem['song_name'] + "###" for vote in songlistitem['votes']: first = True for key in vote.keys(): if not first: songlist_str += "#" else: first = False songlist_str += key + "#" + vote[key].replace("\n", "#LINEBREAK#") songlist_str += "@@" songlist_str += "####" print(songlist_str) def _main_loop(self): while True: cmd = sys.stdin.readline().strip() logging.debug(self.name + ": Read command: %s" % cmd) if "q" == cmd: with self.progressLock: self.quitting = True break match = re.match(r'sendmsg (\S+)', cmd) if match: msg = match.group(1) self._send_msg("TXTMSG", {'msg': msg}) continue match = re.match(r'vote (\S+)', cmd) if match: songName = match.group(1) vote = self._createVote(songName) self._addVote(songName, vote) self._sendVote(songName, vote) print("VOTEOK") continue if "join" == cmd: self._join() continue if "play_next" == cmd: self._play_next() continue if "say_quit" == cmd: print("QUITTING") continue if "get_playlist" == cmd: with self.playlistLock: self._print_songlist("PLAYLIST", self.playlist) continue if "get_top3songs" == cmd: with self._toplock: top3str = "TOP3SONGS###" for top3item in self._top: if top3item: (song, votecnt) = top3item top3str += song + "#" + str(votecnt) + "##" print(top3str) continue if "test_create_fake_vote" == cmd: songName = 'Justin Beaver' fakeVote = {'peer_name': self.name, 'sig': str(self.key.signMessage(songName)), 'pk': self.key.getPublicKey(), 'pksign': '0'} self._sendVote(songName, fakeVote) continue if "get_logical_clock" == cmd: logical = self.clock.getLogical() logging.debug(self.name + ' LOGICAL CLOCK ' + str(logical)) print("LOGICALCLOCK#" + str(logical)) continue if "leave" == cmd: s = ServerProxy('http://' + self.routerHost + ':' + str(self.routerPort)) s.leavePeer(self.name) break print("Unknown command:", cmd) def _server(self): logging.debug('Starting peer on: %s:%s' % (self.host, self.port)) try: self.rpc_server.serve_forever() finally: self.rpc_server.close()
class Router: def __init__(self, host, port, peers, peer_controller, useTicks): self.host = host self.port = port self.peer_controller = peer_controller self.peers = peers self.msg_queue = [] self.msg_lock = Lock() self.msg_cond = Condition(self.msg_lock) self.useTicks = useTicks self.peer_can_send = {} self.queue_was_empty = False self.queue_active = False self.statlock = Lock() self.msgshandled = 0 self.msgsize = 0 self.msgtypecnt = {} # Init for ticks for peer in self.peers: self.peer_can_send[peer.name] = 0 def stats(self): msgtypes = "" for (msgtype, cnt) in self.msgtypecnt.items(): msgtypes += msgtype + ": " + str(cnt) + "\n" return "TOTAL MESSAGES: " + str(self.msgshandled) + "\n" + \ "DATA SIZE: " + str(self.msgsize) + "\n" + \ "--MSG TYPES-- \n" + \ msgtypes + "\n------------\n" def get_msgcnt(self): return self.msgshandled def get_msgsize(self): return self.msgsize def get_msgtypecnt(self): return self.msgtypecnt def activate_queue(self): with self.msg_lock: self.queue_active = True self.msg_cond.notify() def tick(self, num_msgs): """Each peer can only send a fixed number of messages each time interval""" with self.msg_lock: for peer in self.peers: self.peer_can_send[peer.name] = num_msgs self.msg_cond.notify() def wait_queue_empty(self): # Check twice with small interval while True: with self.msg_lock: if len(self.msg_queue) > 0: self.queue_was_empty = True else: if self.queue_was_empty: self.queue_was_empty = False break else: self.queue_was_empty = True time.sleep(0.1) def start(self): # Create server self.rpc_server = ThreadedXMLRPCServer((self.host, self.port), requestHandler=RequestHandler, logRequests=False) self.rpc_server.register_introspection_functions() # Register RPC functions. self.rpc_server.register_function(self.forwardMessage) self.rpc_server.register_function(self.registerNewPeer) self.rpc_server.register_function(self.leavePeer) server_thread = threading.Thread(name="server", target=self._server) server_thread.setDaemon(True) # Don't wait for server thread to exit. server_thread.start() queue_thread = threading.Thread(name="queue", target=self._queue_handler) queue_thread.setDaemon(True) # Don't wait for server thread to exit. queue_thread.start() def shutdown(self): self.rpc_server.server_close() def registerNewPeer(self, name, host, port): peer = BasicPeerHandler(name, host, port) peer.setLocation(self.peer_controller.generateNewPeerLocation()) peer.setPeerController(self.peer_controller) self.peer_controller.addPeer(peer) print("Peer " + name + " joined") return '' def leavePeer(self, name): for peer in self.peers: if peer.name == name: self.peer_controller.removePeer(peer) print("Peer " + name + " left") break return '' # Peer name is the origin of the message def forwardMessage(self, immediate_sender, msg_id, peer_name, msgtype, argdict): with self.statlock: self.msgshandled += 1 self.msgsize += sys.getsizeof(argdict) if not msgtype in self.msgtypecnt: self.msgtypecnt[msgtype] = 0 self.msgtypecnt[msgtype] += 1 #Find peer #TODO: IMPROVE immediate_sender_peer = None for peer in self.peers: if peer.name == immediate_sender: immediate_sender_peer = peer break self.msg_lock.acquire() self.msg_queue.append((immediate_sender_peer, msg_id, peer_name, msgtype, argdict)) self.queue_was_empty = False self.msg_cond.notify() self.msg_lock.release() return '' def _server(self): print('Starting router on: %s:%s' % (self.host, self.port)) try: self.rpc_server.serve_forever() except ValueError: # Thrown upon exit :( pass def _queue_handler(self): while True: with self.msg_lock: if not self.queue_active: self.msg_cond.wait() continue if len(self.msg_queue) == 0: self.msg_cond.wait() for i in range(len(self.msg_queue)): (immediate_sender_peer, msg_id, peer_name, msgtype, argdict) = self.msg_queue[i] if not self.useTicks or (self.peer_can_send[immediate_sender_peer.name] and self.peer_can_send[immediate_sender_peer.name] > 0): self.msg_queue.pop(i) if self.useTicks: self.peer_can_send[immediate_sender_peer.name] -= 1 self._do_forward_msg(immediate_sender_peer, msg_id, peer_name, msgtype, argdict) break def _do_forward_msg(self, immediate_sender_peer, msg_id, peer_name, msgtype, argdict): peersInRange = self.peer_controller.findPeersInRange(immediate_sender_peer) for peer in peersInRange: if peer != immediate_sender_peer: peer.sendMessage(immediate_sender_peer, msg_id, peer_name, str(msgtype), argdict) def _main_loop(self): while True: cmd = sys.stdin.readline().strip() if "q" == cmd: break if "setLocation " in cmd: txt = cmd.replace("setLocation ", "").strip() loc = txt.split(" ") for p in self.peers: if p.name == loc[0]: p.setLocation((int(loc[1]), int(loc[2]), int(loc[3]), int(loc[4]))) break continue if "movePeers" == cmd: self.peer_controller.movePeers() continue print("Unknown command:", cmd)
class Router: def __init__(self, host, port, peers, peer_controller, useTicks): self.host = host self.port = port self.peer_controller = peer_controller self.peers = peers self.msg_queue = [] self.msg_lock = Lock() self.msg_cond = Condition(self.msg_lock) self.useTicks = useTicks self.peer_can_send = {} self.queue_was_empty = False self.queue_active = False self.statlock = Lock() self.msgshandled = 0 self.msgsize = 0 self.msgtypecnt = {} # Init for ticks for peer in self.peers: self.peer_can_send[peer.name] = 0 def stats(self): msgtypes = "" for (msgtype, cnt) in self.msgtypecnt.items(): msgtypes += msgtype + ": " + str(cnt) + "\n" return "TOTAL MESSAGES: " + str(self.msgshandled) + "\n" + \ "DATA SIZE: " + str(self.msgsize) + "\n" + \ "--MSG TYPES-- \n" + \ msgtypes + "\n------------\n" def get_msgcnt(self): return self.msgshandled def get_msgsize(self): return self.msgsize def get_msgtypecnt(self): return self.msgtypecnt def activate_queue(self): with self.msg_lock: self.queue_active = True self.msg_cond.notify() def tick(self, num_msgs): """Each peer can only send a fixed number of messages each time interval""" with self.msg_lock: for peer in self.peers: self.peer_can_send[peer.name] = num_msgs self.msg_cond.notify() def wait_queue_empty(self): # Check twice with small interval while True: with self.msg_lock: if len(self.msg_queue) > 0: self.queue_was_empty = True else: if self.queue_was_empty: self.queue_was_empty = False break else: self.queue_was_empty = True time.sleep(0.1) def start(self): # Create server self.rpc_server = ThreadedXMLRPCServer((self.host, self.port), requestHandler=RequestHandler, logRequests=False) self.rpc_server.register_introspection_functions() # Register RPC functions. self.rpc_server.register_function(self.forwardMessage) self.rpc_server.register_function(self.registerNewPeer) self.rpc_server.register_function(self.leavePeer) server_thread = threading.Thread(name="server", target=self._server) server_thread.setDaemon(True) # Don't wait for server thread to exit. server_thread.start() queue_thread = threading.Thread(name="queue", target=self._queue_handler) queue_thread.setDaemon(True) # Don't wait for server thread to exit. queue_thread.start() def shutdown(self): self.rpc_server.server_close() def registerNewPeer(self, name, host, port): peer = BasicPeerHandler(name, host, port) peer.setLocation(self.peer_controller.generateNewPeerLocation()) peer.setPeerController(self.peer_controller) self.peer_controller.addPeer(peer) print("Peer " + name + " joined") return '' def leavePeer(self, name): for peer in self.peers: if peer.name == name: self.peer_controller.removePeer(peer) print("Peer " + name + " left") break return '' # Peer name is the origin of the message def forwardMessage(self, immediate_sender, msg_id, peer_name, msgtype, argdict): with self.statlock: self.msgshandled += 1 self.msgsize += sys.getsizeof(argdict) if not msgtype in self.msgtypecnt: self.msgtypecnt[msgtype] = 0 self.msgtypecnt[msgtype] += 1 #Find peer #TODO: IMPROVE immediate_sender_peer = None for peer in self.peers: if peer.name == immediate_sender: immediate_sender_peer = peer break self.msg_lock.acquire() self.msg_queue.append( (immediate_sender_peer, msg_id, peer_name, msgtype, argdict)) self.queue_was_empty = False self.msg_cond.notify() self.msg_lock.release() return '' def _server(self): print('Starting router on: %s:%s' % (self.host, self.port)) try: self.rpc_server.serve_forever() except ValueError: # Thrown upon exit :( pass def _queue_handler(self): while True: with self.msg_lock: if not self.queue_active: self.msg_cond.wait() continue if len(self.msg_queue) == 0: self.msg_cond.wait() for i in range(len(self.msg_queue)): (immediate_sender_peer, msg_id, peer_name, msgtype, argdict) = self.msg_queue[i] if not self.useTicks or ( self.peer_can_send[immediate_sender_peer.name] and self.peer_can_send[immediate_sender_peer.name] > 0): self.msg_queue.pop(i) if self.useTicks: self.peer_can_send[immediate_sender_peer.name] -= 1 self._do_forward_msg(immediate_sender_peer, msg_id, peer_name, msgtype, argdict) break def _do_forward_msg(self, immediate_sender_peer, msg_id, peer_name, msgtype, argdict): peersInRange = self.peer_controller.findPeersInRange( immediate_sender_peer) for peer in peersInRange: if peer != immediate_sender_peer: peer.sendMessage(immediate_sender_peer, msg_id, peer_name, str(msgtype), argdict) def _main_loop(self): while True: cmd = sys.stdin.readline().strip() if "q" == cmd: break if "setLocation " in cmd: txt = cmd.replace("setLocation ", "").strip() loc = txt.split(" ") for p in self.peers: if p.name == loc[0]: p.setLocation((int(loc[1]), int(loc[2]), int(loc[3]), int(loc[4]))) break continue if "movePeers" == cmd: self.peer_controller.movePeers() continue print("Unknown command:", cmd)