def main(): # initialize app = QApplication([]) # create connection to the server client = Client(address=('127.0.0.1', 8888), debug=True) client.client_connect() # create a main window window = MainWindow(window_width=400, window_height=600) window.setWindowTitle("Python chat") # waiting for messages global client_worker, network_thread # TODO: refactor this network_thread = QThread() network_thread.setTerminationEnabled(True) client_worker = ClientWorker(client_socket=client.client()) client_worker.recieved_message.connect(window.recieved_message_handler) client_worker.moveToThread(network_thread) network_thread.started.connect(client_worker.start) network_thread.start() window.show() return app.exec_()
def __init__(self, host: str, port: int, username: str): """Sets up the client, connects and logs into the server""" Client.__init__(self, host, port) self.location_queue = Queue() self.health_queue = Queue() self.connect() self.login(username) self._user = username
def main(): """ main test function """ client = Client(IP, PORT) server = TcpServer(IP, PORT) main_thread = threading.Thread(target=server.run) main_thread.start() client.send_to_peer(IP, PORT, {"data" : "hello world"})
def __init__(self): self.map_size = 5 self.game_status = 0 self.me = Player() self.ia = IA(self.me, self) self.enemies = [] self.energy_cells = [] self.networking = Client(sys.argv[1], sys.argv[2], sys.argv[3], self.me) self.gui = GUI("Softwar client", (1024, 1024), self.networking)
def start_replication(self): """Starts replication.""" # HACK ALERT! # if self.__find_local_server(): # Found a local server running -> connect to it self.__client = Client(("localhost", 54879)) self.__client.connect("Player2") else: # No local server running -> run one self.__server = Server() self.__server.start()
def setUpClass(self): try: self.client = Client(constants.MODE_CLIENT, ('127.0.0.1', constants.DEFAULT_PORT)) self.server = Server() self.server.start(constants.DEFAULT_PORT) # Run the test server thread self.testsServerThread = TestsServerThread(self.server) self.testsServerThread.start() except Exception as e: print "Failed to start server: " + str(e) raise e
def __connectToServer(self): # Create the client object to use for the connection self.client = Client(constants.MODE_CLIENT, (self.host, self.port), crypto=self.crypto) # Start the connect thread self.connectThread = qtThreads.QtServerConnectThread(self.client, self.__postConnect, self.__connectFailure) self.connectThread.start() # Show the waiting dialog self.waitingDialog = QWaitingDialog(self.chatWindow, "Connecting to server...", self.isLightTheme, self.__userClosedWaitingDialog) self.waitingDialog.show()
def __init__( self, interactive_remote, broadcast_remote, logger, encryption_scheme, *args, **kwargs, ): """ RPC host for connecting to Composte Servers. Connects to a server listening at interactive_remote and broadcasting on broadcast_remote. Logs are directed to logger, and messages are transparently encrypted and encrypted with encryption_scheme.encrypt() and decrypted with encryption_scheme.decrypt(). Broadcasts are handled with broadcast_handler. """ super(ComposteClient, self).__init__(*args, **kwargs) self.__client = NetworkClient(interactive_remote, broadcast_remote, logger, encryption_scheme) self.__client.info("Connecting to {} and {}".format( interactive_remote, broadcast_remote)) self.__version_handshake() self.__project = None self.__editor = None self.__tts = False espeak = subprocess.check_output( # nosec "which espeak | cat -", stderr=subprocess.DEVNULL, shell=True) say = subprocess.check_output( # nosec "which say | cat -", stderr=subprocess.DEVNULL, shell=True) if espeak.decode() != "": self.__ttsCommand = "espeak " elif say.decode() != "": self.__ttsCommand = "say " else: self.__ttsCommand = None # If this happens too early, a failed version handshake prevents this # thread from ever being joined, and the application will never exit self.__client.start_background(self.__handle)
def send(destination, data, datatype): """ Sends data to a specific destination. For valid datatyp-strings, check requesthandler.py """ print "Trying to send" client = Client(destination) client.clientStart() msg = pickle.dumps(data) + "<>" + datatype + "<>" + str(SETTINGS.employee_id) print str(SETTINGS.employee_id) client.send(msg) client.close()
def __init__(self, address, port, name, role, list, logincallback, insertcallback, disconnectcallback): """ :param address: address of the network :param port: port of the network :param name: username for the login :param role: role for the login ("master" or "client") :param list: StrategiesList object from the StrategiesFrame (for updating its database) :param logincallback: Callback to call when login succeeds :param insertcallback: Callback to call when a command is received :param disconnectcallback: Callback to call when disconnect occurs """ Client.__init__(self, address, port) # Queue to send True to if exit is requested self.logged_in = False self.name = name # Role may be Master or Client instead of master or client self.role = role.lower() self.list = list self.exit = False self.login_callback = logincallback self.insert_callback = insertcallback self.disconnect_callback = disconnectcallback
def __find_local_server(cls): """Tries to connect to a local server. Returns True if successful, False otherwise.""" client = Client(("localhost", 54879)) client.connect("Player2") found_server = False try: client.tick() found_server = True except BrokenPipeError: pass finally: client.stop() return found_server
class NetworkDaemon(Daemon): def __init__(self, port: int): self.client = Client() self.controller = RemoteClient(port) self.handler = Core(self.controller, self.client) async def start(self): await self.client.initialize() await self.controller.initialize() await asyncio.gather(self.handle_commands_from_user(), self.handle_messages_from_network()) def stop(self): asyncio.create_task(self.client.stop()) asyncio.create_task(self.controller.close()) async def handle_commands_from_user(self): async for command in self.client.poll(): self.handler.process_command(command) async def handle_messages_from_network(self): async for message in self.controller.poll(): self.handler.process_message(message)
def request(server: Server, client: Client, request: str): from nltk2qo.converter import nltk_to_query_objects client.send('debug', 'received') set_client(client) ast = convert([request]) client.send('ast', str(ast[0])) qo = nltk_to_query_objects(ast) for sentence in qo: qb = QueryBuilder(sentence) qb.build() set_client(False) client.close()
def send(destination, data, datatype): """ Sends data to a specific destination. For valid datatyp-strings, check requesthandler.py """ msg = pickle.dumps(data) + "<>" + datatype lock.acquire() client = Client(destination) try: client.clientStart() client.send(msg) print "Client sent" client.close() lock.release() except: lock.release() raise
def _connect(self): """ Connect to the Guide server """ input_data = self.get_input_data() connected = False while not connected: try: client = Client(input_data.get('ip')) connected = True except socket_error as e: connected = False if e.errno != errno.ECONNREFUSED: raise e sleep(0.5) screen = self._screen del self GameBlind(screen, client) BlindMenu.stop_client(client)
def connectToServer(self): try: dialogWindow = CursesDialog(self.screen, "Connecting to server...", "", False) dialogWindow.show() self.client = Client(constants.MODE_CLIENT, (self.host, self.port), crypto=self.crypto) self.client.connect() except exceptions.GenericError as ge: CursesDialog(self.screen, str(ge), errors.FAILED_TO_CONNECT, isError=True).show() # Do the handshake with the server try: self.client.doHandshake() dialogWindow.hide() except exceptions.NetworkError as ne: self.client.disconnect() dialogWindow.hide() CursesDialog(self.screen, str(ne), errors.TITLE_NETWORK_ERROR, isError=True).show() except exceptions.CryptoError as ce: self.client.disconnect() dialogWindow.hide() CursesDialog(self.screen, str(ce), errors.TITLE_CRYPTO_ERROR, isError=True).show()
def close(self): """Logout and close""" self.send("logout") Client.close(self)
class ComposteClient(QtCore.QObject): _updateGUI = QtCore.pyqtSignal(float, float, name='_updateGUI') _chatToGUI = QtCore.pyqtSignal(str, name='_chatToGUI') def __init__(self, interactive_remote, broadcast_remote, logger, encryption_scheme, *args, **kwargs): """ RPC host for connecting to Composte Servers. Connects to a server listening at interactive_remote and broadcasting on on broadcast_remote. Logs are directed to logger, and messages are transparently encrypted and encrypted with encryption_scheme.encrypt() and decrypted with encryption_scheme.decrypt(). Broadcasts are handled with broadcast_handler """ super(ComposteClient, self).__init__(*args, **kwargs) self.__client = NetworkClient(interactive_remote, broadcast_remote, logger, encryption_scheme) self.__client.info("Connecting to {} and {}".format( interactive_remote, broadcast_remote)) self.__version_handshake() self.__project = None self.__editor = None self.__tts = False espeak = subprocess.check_output("which espeak | cat -", stderr=subprocess.DEVNULL, shell=True) say = subprocess.check_output("which say | cat -", stderr=subprocess.DEVNULL, shell=True) if espeak.decode() != "": self.__ttsCommand = "espeak " elif say.decode() != "": self.__ttsCommand = "say " else: self.__ttsCommand = None # If this happens too early, a failed version handshake prevents this # thread from ever being joined, and the application will never exit self.__client.start_background(self.__handle) def project(self): return self.__project def pause_updates(self): """ Prevent incoming updates from being applied, queuing them up. Blocks until all updates currently being processed have completed. """ self.__client.pause_background() def resume_update(self): """ Apply queued updates and resume applying updates as they come in. """ self.__client.resume_background() def closeEditor(self): """ To be run when the editor exits, to do cleanup that will allow it to be relaunched later. """ self.__editor = None def __updateGui(self, startOffset, endOffset): """ Tell the GUI to update the section of the score between startOffset and endOffset. """ if self.__editor is not None: self._updateGUI.emit(startOffset, endOffset) def __handle(self, _, rpc): def fail(*args): return ("fail", "I don't know what you want me to do") def unimplemented(*args): return ("?", "?") rpc_funs = { "update": self.__do_update, } rpc = client.deserialize(rpc) if self.__project is None or \ str(self.__project.projectID) != rpc["args"][0]: return f = rpc["fName"] if rpc["args"][1] == "chat": rpc["args"][2] = json.loads(rpc["args"][2]) printedStr = rpc["args"][2][0] + ": " + rpc["args"][2][1] spokenStr = shlex.quote(rpc["args"][2][0] + " says " + rpc["args"][2][1]) print(printedStr) self._chatToGUI.emit(printedStr) if self.__tts and (self.__ttsCommand is not None): subprocess.call(str(self.__ttsCommand) + spokenStr, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True) return do_rpc = rpc_funs.get(f, fail) try: (status, other) = do_rpc(*rpc['args']) if status == 'ok': startOffset, endOffset = other self.__updateGui(startOffset, endOffset) except Exception as e: print(e) def __do_update(self, *args): project = lambda x: self.__project try: return util.musicWrapper.performMusicFun(*args, fetchProject=project) except: print(traceback.format_exc()) return ('fail', 'error') def __version_handshake(self): """ Perform a version handshake with the remote Composte server """ msg = client.serialize("handshake", misc.get_version()) reply = self.__client.send(msg) if DEBUG: print(reply) reply = server.deserialize(reply) if reply[0] == "fail": status, reason = reply version = reason[0] raise GenericError(version) def register(self, uname, pword, email): """ register username password email Attempt to register a new user """ msg = client.serialize("register", uname, pword, email) reply = self.__client.send(msg) if DEBUG: print(reply) return server.deserialize(reply) # We probably need cookies for login too, otherwise people can request # project listings (and thus projects) and subscribe to projects they # shouldn't be able to. This isn't an issue for the minimum deliverable # for the course, but it is an issue in the long run def login(self, uname, pword): """ login username password Attempt to login as a user """ msg = client.serialize("login", uname, pword) reply = self.__client.send(msg) # status, reason = reply if DEBUG: print(reply) return server.deserialize(reply) def create_project(self, uname, pname, metadata): """ create-project username project-name metadata Attempt to create a project. Metdata must have the form of a json object, eg "{ "owner": username }" """ if type(metadata) == str: metadata = json.loads(metadata) metadata["owner"] = uname metadata["name"] = pname metadata = json.dumps(metadata) msg = client.serialize("create_project", uname, pname, metadata) reply = self.__client.send(msg) if DEBUG: print(reply) try: return server.deserialize(reply) except: print(reply) return ("fail", "Mangled reply") def share(self, pid, new_contributor): """ share project-id new-contributor Allow another person to contribute to your project """ msg = client.serialize("share", pid, new_contributor) reply = self.__client.send(msg) if DEBUG: print(reply) return server.deserialize(reply) def retrieve_project_listings_for(self, uname): """ list-projects username Get a list of all projects this user is a collaborator on """ msg = client.serialize("list_projects", uname) reply = self.__client.send(msg) return server.deserialize(reply) def get_project(self, pid): """ get-project project-id Given a uuid, get the project to work on """ msg = client.serialize("get_project", pid) reply = server.deserialize(self.__client.send(msg)) if DEBUG: print(reply) status, ret = reply if status == 'ok': print(type(ret)) realProj = json.loads(ret[0]) self.__project = util.composteProject.deserializeProject(realProj) return reply # Realistically, we send a login cookie and the server determines the user # from that, but we don't have that yet def subscribe(self, uname, pid): """ subscribe username project-id Subscribe to updates to a project """ msg = client.serialize("subscribe", uname, pid) reply = self.__client.send(msg) # print(reply) j = json.loads(reply) if DEBUG: print(j[1][0]) return server.deserialize(reply) def unsubscribe(self, cookie): """ Unsubscribe to updates to a project """ msg = client.serialize("unsubscribe", cookie) reply = self.__client.send(msg) if DEBUG: print(reply) return server.deserialize(reply) # There's nothing here yet b/c we don't know what anything look like def update(self, pid, fname, args, partIndex=None, offset=None): """ update project-id update-type args partIndex = None offset = None Send a music related update for the remote backend to process. args is a tuple of arguments """ args = json.dumps(args) msg = client.serialize("update", pid, fname, args, partIndex, offset) reply = self.__client.send(msg) if DEBUG: print(reply) return server.deserialize(reply) def chat(self, pid, from_, *message_parts): """ chat project-id sender [message-parts] """ return self.update(pid, "chat", (from_, " ".join(message_parts))) def toggleTTS(self): """ toggle-tts If text-to-speech is turned on, toggle-tts turns it off. If text-to-speech is turned off, toggle-tts turns it on. Text-to-speech will only work if it is availible. """ self.__tts = not self.__tts def ttsOn(self): """ tts-on Turns text-to-speech on if it is availible. """ self.__tts = True def ttsOff(self): """ tts-off Turns text-to-speech off. """ self.__tts = False def changeKeySignature(self, pid, offset, partIndex, newSigSharps): """ change-key-signature project-id offset partIndex newSigSharps Change the key signature """ return self.update(pid, "changeKeySignature", (offset, partIndex, newSigSharps), partIndex, offset) def insertNote(self, pid, offset, partIndex, pitch, duration): """ insert-note project-id offset partIndex pitch duration Insert a note into the score """ return self.update(pid, "insertNote", (offset, partIndex, pitch, duration), partIndex, offset) def removeNote(self, pid, offset, partIndex, removedNoteName): """ remove-note project-id offset partIndex removedNoteName Remove a note from the score """ return self.update(pid, "removeNote", (offset, partIndex, removedNoteName), partIndex, offset) def insertMetronomeMark(self, pid, offset, bpm): """ insert-metronome-mark project-id offset bpm pulseDuration Insert a metronome mark """ return self.update(pid, "insertMetronomeMark", (offset, bpm), None, offset) def removeMetronomeMark(self, pid, offset): """ remove-metronome-mark project-id offset Remove a metronome mark """ return self.update(pid, "removeMetronomeMark", (offset, ), None, offset) def transpose(self, pid, partIndex, semitones): """ transpose project-id partIndex semitones """ return self.update(pid, "transpose", (partIndex, semitones), partIndex, None) def insertClef(self, pid, offset, partIndex, clefStr): """ insert-clef project-id offset partIndex clefStr Insert a clef """ return self.update(pid, "insertClef", (offset, partIndex, clefStr), partIndex, offset) def removeClef(self, pid, offset, partIndex): """ remove-clef project-id offset partIndex Remove a clef """ return self.update(pid, "removeClef", (offset, partIndex), partIndex, offset) def insertMeasures(self, pid, insertionOffset, partIndex, insertedQLs): """ insert-measures project-id insertionOffset partIndex insertedQLs Insert measures into the score """ return self.update(pid, "insertMeasures", (insertionOffset, partIndex, insertedQLs), partIndex, insertionOffset) def addInstrument(self, pid, offset, partIndex, instrumentStr): """ add-instrumnet project-id offset partIndex instrumentStr """ return self.update(pid, "addInstrument", (offset, partIndex, instrumentStr), partIndex, offset) def removeInstrument(self, pid, offset, partIndex): """ remove-instrument project-id offset partIndex """ return self.update(pid, "removeInstrument", (offset, partIndex), partIndex, offset) def addDynamic(self, pid, offset, partIndex, dynamicStr): """ add-dynamic project-id offset partIndex dynamicStr """ return self.update(pid, "addDynamic", (offset, partIndex, dynamicStr), partIndex, offset) def removeDynamic(self, pid, offset, partIndex): """ remove-dynamic project-id offset partIndex """ return self.update(pid, "removeDynamic", (offset, partIndex), partIndex, offset) def addLyric(self, pid, offset, partIndex, lyric): """ add-lyric project-id offset partIndex lyric Attach a lyric to the score """ return self.update(pid, "addLyric", (offset, partIndex, lyric), partIndex, offset) def startEditor(self): """ start-editor Launch the editor GUI. """ if self.__project is not None: if self.__editor is None: self.__editor = editor.Editor(self) self.__editor.showMaximized() else: return 'Load a project before launching the editor.' def playback(self, partIndex): """ playback partIndex Playback the project set by get-project. """ self.pause_updates() util.musicFuns.playback(self.__project.parts[int(partIndex)]) self.resume_update() def stop(self): """ Stop the client elegantly """ self.__client.stop()
def broadcast(self, trans): self.pool.insert(trans) ###### NOT THE SAME POOL AS THE SERVER !!! client = Client() client.prop_trans(trans) client.close()
import pygame from infra.Board import Board from infra.Player import Player from network.client import Client import random import time if __name__ == '__main__': p = None p2 = None client = Client() player_chosen = client.getPlayer() board = Board(player=player_chosen) if player_chosen == 0: p = Player() p2 = Player(x=170, y=480) elif player_chosen == 1: p2 = Player() p = Player(x=170, y=480) running = True count = 0 counter = 0 time.sleep(10) while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: p.playerX_change = -0.1 if event.key == pygame.K_RIGHT:
class TestClient(unittest.TestCase): @classmethod def setUpClass(self): try: self.client = Client(constants.MODE_CLIENT, ('127.0.0.1', constants.DEFAULT_PORT)) self.server = Server() self.server.start(constants.DEFAULT_PORT) # Run the test server thread self.testsServerThread = TestsServerThread(self.server) self.testsServerThread.start() except Exception as e: print "Failed to start server: " + str(e) raise e @classmethod def tearDownClass(self): try: self.server.stop() except Exception as e: self.fail("Failed to stop server: " + str(e)) raise 3 def testConncecToServer(self): try: self.client.connect() except Exception as e: print "Failed to connect to server: " + str(e) raise e def testCheckHostname(self): self.assertEqual(self.client.getHostname(), "127.0.0.1") def testHandshake(self): try: self.client.doHandshake() except Exception as e: self.fail(str(e)) def checkEncryptType(self): # Confirm AES is being used self.assertEqual(self.client.sock.encryptType, self.client.sock.AES) def testSendMessageToServer(self): self.client.sendMessage(constants.COMMAND_MSG, CLIENT_TEST_MESSAGE_1) def testReceiveMessageFromServer(self): message = self.client.receiveMessage(constants.COMMAND_MSG) self.assertEqual(message, SERVER_TEST_MESSAGE_1) message = self.client.receiveMessage(constants.COMMAND_MSG) self.assertEqual(message, SERVER_TEST_MESSAGE_2) message = self.client.receiveMessage(constants.COMMAND_MSG) self.assertEqual(message, SERVER_TEST_MESSAGE_3) def testSendUnexpectCommandToServer(self): self.client.sendMessage(constants.COMMAND_REDY) # Server should respond with error command self.client.receiveMessage(constants.COMMAND_ERR) def testDisconnect(self): self.client.disconnect()
import pygame from infra.Board import Board from infra.Board import Player from network.client import Client import random import time if __name__ == '__main__': p = None p2 = None client = Client() player_chosen = client.getPlayer() board = Board(player=player_chosen) if player_chosen == 0: p = Player() p2 = Player(x=170, y=480) elif player_chosen == 1: p2 = Player() p = Player(x=170, y=480) running = True count = 0 counter = 0 time.sleep(10) while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: p.playerX_change = -0.1 if event.key == pygame.K_RIGHT:
def __init__(self): self.pool = TransactionPool() self.client = Client()
if not any(info): sys.exit() is_hosting_server, ip, port = info receive_queue = Queue() server = None client = None if is_hosting_server: player = Players.P1 server = Server('127.0.0.1', 65432) server.run() client = Client('127.0.0.1', 65432, receive_queue) time.sleep(1) if client.connect() is not True: sys.exit() client.listen() wait_dialog = ServerWaitingDialog('127.0.0.1', 65432, server.get_number_of_players) wait_dialog.run() else: player = Players.P2 client = Client(ip, port, receive_queue) if client.connect() is not True: sys.exit() client.listen()
class ServerSync(object): def __init__(self, exec_path, nodeid, bind_ip, webuiport, comport, masterip=None, masterport=None): self.ismaster = True self.exec_path = exec_path self.nodeid = nodeid self.bindip = bind_ip self.webuiport = webuiport self.comport = comport self.masterip = masterip self.masterport = masterport self.user_appdata_directory = None self.started_at = time.time() self.last_tick_at = self.started_at self.uptime = 0 self.public_ip = "Not yet known" if platform.system() == "Darwin": self.user_appdata_directory = os.path.expanduser("~/Library/ServerSync/%s" % (self.nodeid)) elif platform.system() == "Linux": self.user_appdata_directory = os.path.expanduser("~/.config/ServerSync/%s" % (self.nodeid)) # inspired by Google Chrome location elif platform.system() == "Windows": self.user_appdata_directory = os.path.expanduser("~\\AppData\\Local\\ServerSync\\%s" % (self.nodeid)) else: raise("Platform not supported") if masterip is None: self.print("Setting up node %s as master\n" % (nodeid)) else : self.ismaster = False self.print("Setting up node %s.\n" % (nodeid)) self.print(" will ask peer list to node at %s:%s\n" % (masterip, masterport)) self.print("Control panel is on port %s\n" % (webuiport)) self.print("Listen for other nodes on port %s\n" % (comport)) # create a directory for the application if not aready exists if not os.path.exists(self.user_appdata_directory): os.makedirs(self.user_appdata_directory) self.updater = Updater() #m = multiprocessing.Manager() self.q_peerstore_in = multiprocessing.Queue() #m.Queue() #for networked multiprocessing self.q_peerstore_out = multiprocessing.Queue() self.q_comwebserver_in = multiprocessing.Queue() #m.Queue() #for networked multiprocessing self.q_comwebserver_out = multiprocessing.Queue() self.q_client_in = multiprocessing.Queue() self.q_client_out = multiprocessing.Queue() self.q_uiwebserver_in = multiprocessing.Queue() self.q_uiwebserver_out = multiprocessing.Queue() self.q_logger_in = multiprocessing.Queue() self.q_logger_out = multiprocessing.Queue() self.q_console_out = multiprocessing.Queue() self.peerstore = PeerStore(THREAD_SLEEP_TIME, self.q_peerstore_in, self.q_peerstore_out, "PeerStore", self.user_appdata_directory, self.comport, self.nodeid, self.masterip, self.masterport) self.uiwebserver = UIWebServer(THREAD_SLEEP_TIME, self.exec_path, self.bindip, self.q_uiwebserver_in, self.q_uiwebserver_out, self.webuiport, self.nodeid, "UIWebServer") self.logger = Logger(THREAD_SLEEP_TIME, self.q_logger_in, self.q_logger_out, self.nodeid, "Logger") self.comwebserver = ComWebServer(THREAD_SLEEP_TIME, self.exec_path, self.bindip, self.q_comwebserver_in, self.q_comwebserver_out, self.comport, self.nodeid, "ComWebServer") self.client = Client(THREAD_SLEEP_TIME, self.exec_path, self.bindip, self.q_client_in, self.q_client_out, self.nodeid, "Client") self.console = Console(self.q_console_out, sys.stdin, sys.stdout, self.nodeid, "Console") self.running = False self.should_restart = False def start(self): # we will fork the subprocesses now so we disable the signal handling for them # we will enable it later signal.signal(signal.SIGINT, signal.SIG_IGN) # start process self.comwebserver.start() self.uiwebserver.start() self.client.start() self.logger.start() self.peerstore.start() # catch CTRL+C signal.signal(signal.SIGINT, self.signal_handler) # start threads self.console.start() self.running = True self.q_logger_in.put(Message("System", "Logger", "register", ["System"])) while(self.running): time.sleep(MAIN_SLEEP_TIME) m = self.process_queues() # each second we send a tick to some of the processes telling them since how manytime we run if int(time.time() - self.last_tick_at) >= 1: self.last_tick_at = time.time() self.uptime = int(time.time() - self.started_at) self.q_peerstore_in.put(Message(self.nodeid, "PeerStore", "tick", [self.uptime])) self.q_comwebserver_in.put(Message(self.nodeid, "ComWebServer", "tick", [self.uptime])) self.q_uiwebserver_in.put(Message(self.nodeid, "UIWebServer", "tick", [self.uptime])) self.q_logger_in.put(Message(self.nodeid, "Logger", "tick", [self.uptime])) # We send poison pill to threads only if they are not configured to loop based on a sleep time (blocking queues) if THREAD_SLEEP_TIME is 0: self.poison_pill_queues() self.print("Shutdown client and server processes...\n") # ask the client and server process to shut down, except if we received a kill signal self.print("Wait for gracefull stop\n") self.q_client_in.put(Message(self.nodeid, "Client", "kill", [])) self.q_comwebserver_in.put(Message(self.nodeid, "ComWebServer", "kill", [])) self.q_uiwebserver_in.put(Message(self.nodeid, "UIWebServer", "kill", [])) self.q_logger_in.put(Message(self.nodeid, "Logger", "kill", [])) self.q_peerstore_in.put(Message(self.nodeid, "PeerStore", "kill", [])) time.sleep(1) # read what remains in the queues self.process_queues() # Wait for the worker to finish self.comwebserver.join() self.print("ComWebServer joined\n") self.uiwebserver.join() self.print("UIWebServer joined\n") self.logger.join() self.print("Logger joined\n") self.client.join() self.print("Client joined\n") self.peerstore.join() self.print("PeerStore joined\n") self.console.cancel() self.print("Console joined\n") self.print("Stopped\n") return self.should_restart def poison_pill_queues(self): self.q_comwebserver_in.put(Message(self.nodeid, "ComWebServer", "pill", [])) self.q_uiwebserver_in.put(Message(self.nodeid, "UIWebServer", "pill", [])) self.q_logger_in.put(Message(self.nodeid, "Logger", "pill", [])) self.q_peerstore_in.put(Message(self.nodeid, "PeerStore", "pill", [])) def process_queues(self): q_comwebserver_out_empty = False q_client_out_empty = False q_uiwebserver_out_empty = False q_logger_out_empty = False q_peerstore_out_empty = False q_console_out_empty = False while (not q_comwebserver_out_empty) or (not q_client_out_empty) or (not q_uiwebserver_out_empty) or (not q_logger_out_empty) or (not q_peerstore_out_empty) or (not q_console_out_empty): try: m = self.q_console_out.get(False) self.dispatch_message(m) except Exception as e: q_console_out_empty = True try: m = self.q_uiwebserver_out.get(False) self.dispatch_message(m) except Exception as e: q_uiwebserver_out_empty = True try: m = self.q_logger_out.get(False) self.dispatch_message(m) except Exception as e: q_logger_out_empty = True try: m = self.q_comwebserver_out.get(False) self.dispatch_message(m) except Exception as e: q_comwebserver_out_empty = True try: m = self.q_peerstore_out.get(False) self.dispatch_message(m) except Exception as e: q_peerstore_out_empty = True try: m = self.q_client_out.get(False) self.dispatch_message(m) except Exception as e: q_client_out_empty = True def dispatch_message(self, message): try: # # intercept message like exit/quit/restart # if message.destination == "System": if message.command == "halt" or message.command == "stop": self.running = False elif message.command == "restart": self.running = False self.should_restart = True elif message.command == "PublicIpDiscovered": self.public_ip = message.arguments[0] elif message.command == "GetVersion": self.print("\n\nreceived Get Version FROM %s\n\n" % (message.sender_id)) m = Message("System", message.sender_id, "GetVersion_ret", [{ "current_version": self.updater.current_version, "new_version": self.updater.new_version_available }], communication_id=message.communication_id) self.q_uiwebserver_in.put(m) elif message.command == "increment": message.destination = "UIWebServer" # useless step ? the message wil not be dispatched anymore, no nee to change its dest self.q_uiwebserver_in.put(message) elif message.command == "uptime": m = Message("System", "Logger", "print", ["Running since %s (hh:mm:ss)\n" % (time.strftime('%H:%M:%S', time.gmtime(self.uptime)))]) self.q_logger_in.put(m) elif message.command == "print": self.print("%s %s %s\n"%(message.sender_id, message.command, message.arguments)) elif message.command == "exception": self.print("%s Catched exception: %s \n"%(message.sender_id, [message.arguments[0]])) elif message.command == "NodeInfo": m = Message("System", message.sender_id, "NodeInfo_ret", [{"ismaster": self.ismaster, "nodeid": self.nodeid, "webuiport": self.webuiport, "comport": self.comport, "masterip": self.masterip, "masterport": self.masterport, "user_appdata_directory": self.user_appdata_directory, "started_at": self.started_at, "uptime": self.uptime, "public_ip": self.public_ip, "version": self.updater.current_version }], communication_id=message.communication_id) self.q_uiwebserver_in.put(m) # # we also intercept print comands # elif message.destination == "Logger": if self.running: self.q_logger_in.put(message) else: # if no logger running we fallback to the system print self.print("%s %s %s\n"%(message.sender_id, message.command, message.arguments)) elif message.destination == "PeerStore": self.q_peerstore_in.put(message) elif message.destination == "UIWebServer": self.q_uiwebserver_in.put(message) elif message.destination == "ComWebServer": self.q_comwebserver_in.put(message) elif message.destination == "Client": self.q_client_in.put(message) # # dispatch other messages # else : self.print("Message dispatcher received a msg for the unknown destination '%s'\n" % (message.destination)) except Exception as e: self.print("Exception while dispatching message '%s'\n" % ([e])) def print(self, message): sys.stdout.write("%s => %s" % (datetime.datetime.utcnow().strftime("%Y %b %d %H:%M:%S %Z "), message)) sys.stdout.flush() def signal_handler(self, sig, frame): if sig == signal.SIGINT: self.print("Please type 'halt' or 'stop' to close the program or 'restart' to full restart\n")
def __init__(self, exec_path, nodeid, bind_ip, webuiport, comport, masterip=None, masterport=None): self.ismaster = True self.exec_path = exec_path self.nodeid = nodeid self.bindip = bind_ip self.webuiport = webuiport self.comport = comport self.masterip = masterip self.masterport = masterport self.user_appdata_directory = None self.started_at = time.time() self.last_tick_at = self.started_at self.uptime = 0 self.public_ip = "Not yet known" if platform.system() == "Darwin": self.user_appdata_directory = os.path.expanduser("~/Library/ServerSync/%s" % (self.nodeid)) elif platform.system() == "Linux": self.user_appdata_directory = os.path.expanduser("~/.config/ServerSync/%s" % (self.nodeid)) # inspired by Google Chrome location elif platform.system() == "Windows": self.user_appdata_directory = os.path.expanduser("~\\AppData\\Local\\ServerSync\\%s" % (self.nodeid)) else: raise("Platform not supported") if masterip is None: self.print("Setting up node %s as master\n" % (nodeid)) else : self.ismaster = False self.print("Setting up node %s.\n" % (nodeid)) self.print(" will ask peer list to node at %s:%s\n" % (masterip, masterport)) self.print("Control panel is on port %s\n" % (webuiport)) self.print("Listen for other nodes on port %s\n" % (comport)) # create a directory for the application if not aready exists if not os.path.exists(self.user_appdata_directory): os.makedirs(self.user_appdata_directory) self.updater = Updater() #m = multiprocessing.Manager() self.q_peerstore_in = multiprocessing.Queue() #m.Queue() #for networked multiprocessing self.q_peerstore_out = multiprocessing.Queue() self.q_comwebserver_in = multiprocessing.Queue() #m.Queue() #for networked multiprocessing self.q_comwebserver_out = multiprocessing.Queue() self.q_client_in = multiprocessing.Queue() self.q_client_out = multiprocessing.Queue() self.q_uiwebserver_in = multiprocessing.Queue() self.q_uiwebserver_out = multiprocessing.Queue() self.q_logger_in = multiprocessing.Queue() self.q_logger_out = multiprocessing.Queue() self.q_console_out = multiprocessing.Queue() self.peerstore = PeerStore(THREAD_SLEEP_TIME, self.q_peerstore_in, self.q_peerstore_out, "PeerStore", self.user_appdata_directory, self.comport, self.nodeid, self.masterip, self.masterport) self.uiwebserver = UIWebServer(THREAD_SLEEP_TIME, self.exec_path, self.bindip, self.q_uiwebserver_in, self.q_uiwebserver_out, self.webuiport, self.nodeid, "UIWebServer") self.logger = Logger(THREAD_SLEEP_TIME, self.q_logger_in, self.q_logger_out, self.nodeid, "Logger") self.comwebserver = ComWebServer(THREAD_SLEEP_TIME, self.exec_path, self.bindip, self.q_comwebserver_in, self.q_comwebserver_out, self.comport, self.nodeid, "ComWebServer") self.client = Client(THREAD_SLEEP_TIME, self.exec_path, self.bindip, self.q_client_in, self.q_client_out, self.nodeid, "Client") self.console = Console(self.q_console_out, sys.stdin, sys.stdout, self.nodeid, "Console") self.running = False self.should_restart = False
class QtUI(QApplication): def __init__(self, argv, mode, port, host): QApplication.__init__(self, argv) self.mode = mode self.port = port self.host = host self.isEventLoopRunning = False self.connectedToClient = False self.isLightTheme = qtUtils.isLightTheme(self.palette().color(QPalette.Window)) self.aboutToQuit.connect(self.stop) def start(self): self.timer = QTimer() self.timer.start(500) self.timer.timeout.connect(lambda: None) # Show mode dialog if a mode wasn't given if self.mode is None: self.mode = QModeDialog.getMode(self.isLightTheme) # If the user closed the mode dialog by not selected a mode, stop the app if self.mode is None: qtUtils.exitApp() # Show the chat window self.chatWindow = QChatWindow(None, None, self.isLightTheme) self.chatWindow.show() self.__loadOrGenerateKepair() if self.mode == constants.MODE_SERVER: self.__startServer() self.__waitForClient() elif self.mode == constants.MODE_CLIENT: # Get the host if not given if self.host is None: self.host, ok = QInputDialog.getText(self.chatWindow, "Hostname", "Host:") if not ok: self.__restart() return self.__connectToServer() if not self.isEventLoopRunning: self.isEventLoopRunning = True self.exec_() def stop(self): self.__endConnections() self.quit() def __restart(self): self.__endConnections() self.__restartHelper() self.start() def __endConnections(self): if hasattr(self, 'acceptThread'): self.acceptThread.quit() elif hasattr(self, 'connectThread'): self.connectThread.quit() if hasattr(self, 'sendThread'): self.sendThread.quit() if hasattr(self, 'recvThread'): self.recvThread.quit() # If a client is connected, try to end the connection gracefully if hasattr(self, 'client'): self.client.disconnect() if hasattr(self, 'server'): self.server.stop() def __restartHelper(self): self.mode = None self.host = None self.closeAllWindows() if hasattr(self, 'waitingDialog'): del self.waitingDialog if hasattr(self, 'chatWindow'): del self.chatWindow def __loadOrGenerateKepair(self): self.crypto = Crypto() if utils.doesSavedKeypairExist(): while(True): passphrase = qtUtils.getKeypairPassphrase(self.isLightTheme) # Restart the application if the user did not provide a passphrase if passphrase is None: self.__restart() return try: utils.loadKeypair(self.crypto, passphrase) break except exceptions.CryptoError: QMessageBox.warning(self.chatWindow, errors.BAD_PASSPHRASE, errors.BAD_PASSPHRASE_VERBOSE) # We still need to generate an AES key self.crypto.generateAESKey() else: self.crypto.generateKeys() def __startServer(self): try: self.server = Server() self.server.start(int(self.port)) except exceptions.NetworkError as ne: QMessageBox.critical(self.chatWindow, errors.FAILED_TO_START_SERVER, errors.FAILED_TO_START_SERVER + ": " + str(ne)) self.__restart() def __waitForClient(self): # Start the accept thread self.acceptThread = qtThreads.QtServerAcceptThread(self.server, self.crypto, self.__postAccept) self.acceptThread.start() # Show the waiting dialog self.waitingDialog = QWaitingDialog(self.chatWindow, "Waiting for connection...", self.isLightTheme, self.__userClosedWaitingDialog, showIP=True) self.waitingDialog.show() def __connectToServer(self): # Create the client object to use for the connection self.client = Client(constants.MODE_CLIENT, (self.host, self.port), crypto=self.crypto) # Start the connect thread self.connectThread = qtThreads.QtServerConnectThread(self.client, self.__postConnect, self.__connectFailure) self.connectThread.start() # Show the waiting dialog self.waitingDialog = QWaitingDialog(self.chatWindow, "Connecting to server...", self.isLightTheme, self.__userClosedWaitingDialog) self.waitingDialog.show() @pyqtSlot(Client) def __postAccept(self, client): self.connectedToClient = True self.client = client self.waitingDialog.close() # Show the accept dialog accept = QAcceptDialog.getAnswer(self.chatWindow, self.client.getHostname()) # If not accepted, disconnect and wait for a client again if not accept: self.client.disconnect() self.__waitForClient() return # Do the handshake with the client try: client.doHandshake() except exceptions.NetworkError as ne: self.client.disconnect() self.__waitForClient() self.__startChat() @pyqtSlot() def __postConnect(self): self.connectedToClient = True self.waitingDialog.close() self.__startChat() @pyqtSlot(str) def __connectFailure(self, errorMessage): QMessageBox.critical(self.chatWindow, errors.FAILED_TO_CONNECT, errorMessage) self.__restart() @pyqtSlot() def __userClosedWaitingDialog(self): self.waitingDialog.hide() # If the waiting dialog was closed before we connected to the client, # it means that the user closed the dialog and we should restart the app if not self.connectedToClient: self.__restart() def __startChat(self): # Start the sending and receiving thread self.recvThread = qtThreads.QtRecvThread(self.client, self.chatWindow.appendMessage, self.__threadError) self.recvThread.start() self.sendThread = qtThreads.QtSendThread(self.client, self.__threadError) self.sendThread.start() self.chatWindow.client = self.client self.chatWindow.messageQueue = self.sendThread.messageQueue self.chatWindow.showNowChattingMessage() @pyqtSlot(str, str) def __threadError(self, title, message): QMessageBox.critical(self.chatWindow, title, message) self.__restart()
class Server(): """ Server should only respond to requests/data from client - listen for new transactions - listen for new blocks - provide most recent blocks (after some specified block #) - every block recieved is confirmed and all transactions are added to UTXO (database of unspent transactions) - if several blocks have to be recieved CHECK IN ORDER - provide IP addresses for node connections """ PORT = 5050 #SERVER = socket.gethostbyname(socket.gethostname()) SERVER = "192.168.0.22" #SERVER = "127.0.0.1" ADDR = (SERVER, PORT) DISCONNECT_MESSAGE = "DISCONNECT" logging.basicConfig(filename="server.log", format='%(asctime)s - %(message)s', level=logging.DEBUG) def __init__(self): self.pool = TransactionPool() self.client = Client() def listen(self): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # IPv4, TCP server.bind(self.ADDR) server.listen() logging.debug("Server started") while True: conn, addr = server.accept() ## ADD ADDRESS TO NODE IPS FILE self.client.connect_to_ip(addr[0]) logging.debug(f"Server connected to: {addr[0]}") thread = threading.Thread(target=self.route_request, args=(conn, )) thread.start() def route_request(self, conn): try: req = conn.recv(1024).decode() while req != self.DISCONNECT_MESSAGE: if req == "NEW_TRANS": print(req) self.get_data(conn) elif req == "NEW_BLOCK": print(req) self.get_data(conn, trans=False) elif req == "GET_CHAIN_LEN": print(req) self.get_chain_len(conn) elif req == "GET_BLOCKS": print(req) self.get_block(conn) elif req == "GET_NODES": print(req) self.get_nodes(conn) else: msg = "FAILED_REQUEST".encode() conn.send(msg) req = conn.recv(1024).decode() except Exception as e: print("Exception occured with peer: ", e) finally: conn.close() # when this function returns the thread will be closed def get_data(self, conn, trans=True): # request the size of file to be received conn.send("GET_SIZE".encode()) size = int(conn.recv(1024).decode()) # get the file conn.send("SEND_DATA".encode()) data = conn.recv(1024) total_recv = len(data) while total_recv < size: data += conn.recv(1024) total_recv += len(data) # deseralize the data data = data.decode() # convert from JSON to Python dictionary data = json.loads(data) if trans: self.new_trans(conn, data) else: self.new_block(conn, data) def verify(self, data_type, data): """ data_type : str 'trans' or 'block' data : dict the transaction or block return : boolean True if verfied, False otherwise """ ver = Verify(self.pool) if data_type == "trans": return ver.verify_trans(data) else: return ver.verify_block(data) def new_trans(self, conn, trans): # check if in transaction pool if self.pool.check_in_pool(trans['txid']): return None if not self.verify("trans", trans): return None logging.debug(f"New transaction verified {trans['txid']}") # add transaction to pool self.pool.insert(trans) # propogate transaction self.client.prop_trans(trans) def new_block(self, conn, block): utxo = UTXO() blockdb = Blockdb() # check if block is already in the local chain exists = blockdb.get_block_by_hash(sha(block)) if exists != None: return None # ensure the block is valid if not self.verify("block", block): return None logging.debug("New block verified") # remove all transaction in the block from unconfirmed pool self.pool.check_new_block(sha(block)) # add all transaction outputs to utxo utxo.add_trans(block['transactions'], sha(json.dumps(block))) # remove all inputs from utxo utxo.remove_trans(block['transactions']) # save block in Blockdb blockdb.add_block(block) # propogate block self.client.prop_block(json.dumps(block).encode()) def get_chain_len(self, conn): blockdb = Blockdb() latest = blockdb.get_latest() conn.send(str(latest).encode()) def get_block(self, conn): blockdb = Blockdb() primary_key = int(conn.recv(1024).decode()) blocks = blockdb.get_from(primary_key) conn.send(str(len(blocks)).encode()) if len(blocks) == 0: return None path = os.path.dirname(os.getcwd()) for filename in blocks[3]: # WHAT IF RETURNS NONE file = path + "/core/" + filename + ".json" size = str(os.path.getsize(file)) conn.send(size.encode()) with open(os.getcwd() + "/addr.json") as file: data = json.load(file) data = json.dumps(data) conn.sendall(data.encode()) def get_nodes(self, conn): with open(os.getcwd() + "/addr.json") as file: data = json.load(file) data = json.dumps(data) conn.send(str(sys.getsizeof(data)).encode()) conn.sendall(data.encode()) ## WONT WORK NEEDS TO BE A JSON OBJECT
class NcursesUI(object): def __init__(self, mode, port, host): self.mode = mode self.port = port self.host = host def start(self): curses.wrapper(self.run) def stop(self): # If a client is connected, try to end the connection gracefully if hasattr(self, 'client'): self.client.disconnect() if hasattr(self, 'server'): self.server.stop() def run(self, screen): self.screen = screen (self.height, self.width) = self.screen.getmaxyx() # Change the colors, clear the screen and set the overall border self.setColors() self.screen.clear() self.screen.border(0) # Create the status and chat input windows self.makeChatWindow() self.makeStatusWindow() self.makeChatInputWindow() self.screen.refresh() # Try to load a keypair if one was saved or generate a new keypair self.loadOrGenerateKepair() # Show the options menu self.showOptionsMenuWindow(showStartOption=True) # Get the server/client mode if not given if self.mode == None: self.showOptionsWindow() if self.mode == constants.MODE_SERVER: self.startServer() self.waitForClient() elif self.mode == constants.MODE_CLIENT: # Get the host if not given if self.host == None: self.getHost() self.connectToServer() self.handleNewConnection() def waitForClient(self): while True: # Show the waiting for connections dialog dialogWindow = CursesDialog(self.screen, "Waiting for connection...") dialogWindow.show() self.client = self.server.accept(self.crypto) dialogWindow.hide() # Show the accept dialog if self.showAcceptWindow() == ACCEPT: break else: self.client.disconnect() # Do the handshake with the client try: self.client.doHandshake() except exceptions.NetworkError as ne: CursesDialog(self.screen, str(ne), errors.TITLE_NETWORK_ERROR, isError=True).show() self.client.disconnect() except exceptions.CryptoError as ce: CursesDialog(self.screen, str(ce), errors.TITLE_CRYPTO_ERROR, isError=True).show() self.client.disconnect() def connectToServer(self): try: dialogWindow = CursesDialog(self.screen, "Connecting to server...", "", False) dialogWindow.show() self.client = Client(constants.MODE_CLIENT, (self.host, self.port), crypto=self.crypto) self.client.connect() except exceptions.GenericError as ge: CursesDialog(self.screen, str(ge), errors.FAILED_TO_CONNECT, isError=True).show() # Do the handshake with the server try: self.client.doHandshake() dialogWindow.hide() except exceptions.NetworkError as ne: self.client.disconnect() dialogWindow.hide() CursesDialog(self.screen, str(ne), errors.TITLE_NETWORK_ERROR, isError=True).show() except exceptions.CryptoError as ce: self.client.disconnect() dialogWindow.hide() CursesDialog(self.screen, str(ce), errors.TITLE_CRYPTO_ERROR, isError=True).show() def handleNewConnection(self): # Set the hostname of who we're connected to in the status window self.setStatusWindow() # Add a hint on how to display the options menu self.screen.addstr(0, 5, "Ctrl+U for options") self.screen.refresh() # Start the sending and receiving threads self.startThreads() # Keep the main thread alive so the daemon threads don't die while True: time.sleep(10) def startThreads(self): ncursesThreads.CursesSendThread(self).start() ncursesThreads.CursesRecvThread(self).start() def setColors(self): if curses.has_colors(): curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK) curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK) curses.init_pair(3, curses.COLOR_CYAN, curses.COLOR_BLACK) curses.init_pair(4, curses.COLOR_BLACK, curses.COLOR_GREEN) self.screen.bkgd(curses.color_pair(1)) def showOptionsWindow(self): optionsWindow = self.screen.subwin(6, 11, self.height/2 - 3, self.width/2 - 6) optionsWindow.border(0) # Enable arrow key detection for this window optionsWindow.keypad(True) # Disable the cursor curses.curs_set(0) optionsWindow.addstr(1, 1, "Run as:") pos = constants.MODE_SERVER while True: if pos == constants.MODE_SERVER: optionsWindow.addstr(3, 2, "Server", curses.color_pair(4)) optionsWindow.addstr(4, 2, "Client") else: optionsWindow.addstr(3, 2, "Server") optionsWindow.addstr(4, 2, "Client", curses.color_pair(4)) self.screen.refresh() key = optionsWindow.getch() # Enter key if key == ord('\n'): break elif pos == constants.MODE_SERVER: pos = constants.MODE_CLIENT elif pos == constants.MODE_CLIENT: pos = constants.MODE_SERVER # Re-enable the cursor curses.curs_set(2) # Get rid of the options window optionsWindow.clear() optionsWindow.refresh() self.mode = pos def showAcceptWindow(self): dialogWidth = 23 + len(self.client.getHostname()); acceptWindow = self.screen.subwin(6, dialogWidth, self.height/2 - 3, self.width/2 - int(dialogWidth/2)) acceptWindow.border(0) # Enable arrow key detection for this window acceptWindow.keypad(True) # Disable the cursor curses.curs_set(0) acceptWindow.addstr(1, 1, "Got connection from %s" % self.client.getHostname()) pos = ACCEPT while True: if pos == ACCEPT: acceptWindow.addstr(3, 2, "Accept", curses.color_pair(4)) acceptWindow.addstr(4, 2, "Reject") else: acceptWindow.addstr(3, 2, "Accept") acceptWindow.addstr(4, 2, "Reject", curses.color_pair(4)) self.screen.refresh() key = acceptWindow.getch() # Enter key if key == ord('\n'): break elif pos == ACCEPT: pos = REJECT elif pos == REJECT: pos = ACCEPT # Re-enable the cursor curses.curs_set(2) # Get rid of the accept window acceptWindow.clear() acceptWindow.refresh() return pos def makeChatWindow(self): self.chatWindow = self.screen.subwin(self.height-4, self.width-2, 1, 1) self.chatWindow.scrollok(True) def makeStatusWindow(self): self.statusWindow = self.screen.subwin(self.height-3, self.width-23) self.statusWindow.border(0) self.statusWindow.addstr(1, 1, "Disconnected") def makeChatInputWindow(self): self.textboxWindow = self.screen.subwin(1, self.width-25, self.height-2, 1) self.textbox = curses.textpad.Textbox(self.textboxWindow, insert_mode=True) curses.textpad.rectangle(self.screen, self.height-3, 0, self.height-1, self.width-24) self.textboxWindow.move(0, 0) def getHost(self): self.hostWindow = self.screen.subwin(3, 26, self.height/2 - 1, self.width/2 - 13) self.hostWindow.border(0) self.hostWindow.addstr(1, 1, "Host: ") self.hostWindow.refresh() # Turn on echo and wait for enter key to read buffer curses.echo() curses.nocbreak() self.host = self.hostWindow.getstr(1, 7) # Turn off echo and disable buffering curses.cbreak() curses.noecho() # Get rid of the host window self.hostWindow.clear() self.screen.refresh() def setStatusWindow(self): self.statusWindow.clear() self.statusWindow.border(0) self.statusWindow.addstr(1, 1, self.client.getHostname()) self.statusWindow.refresh() def startServer(self): try: self.server = Server() self.server.start(int(self.port)) except exceptions.NetworkError as ne: CursesDialog(screen, errors.FAILED_TO_START_SERVER, str(ne), isError=True).show() def showOptionsMenuWindow(self, showStartOption=False): menuWindow = self.screen.subwin((9 if showStartOption else 8), 40, 3, self.width/2 - 20) menuWindow.border(0) # Enable arrow key detection for this window menuWindow.keypad(True) pos = 1 while True: # Disable the cursor curses.curs_set(0) while True: menuItem = 1 if showStartOption: menuWindow.addstr(menuItem, 1, str(menuItem) + ".| Start chat", curses.color_pair(4) if pos == menuItem else curses.color_pair(1)) menuItem += 1 menuWindow.addstr(menuItem, 1, str(menuItem) + ".| Show public key fingerprints", curses.color_pair(4) if pos == menuItem else curses.color_pair(1)) menuItem += 1 menuWindow.addstr(menuItem, 1, str(menuItem) + ".| Save current keypair", curses.color_pair(4) if pos == menuItem else curses.color_pair(1)) menuItem += 1 menuWindow.addstr(menuItem, 1, str(menuItem) + ".| Clear saved keypair", curses.color_pair(4) if pos == menuItem else curses.color_pair(1)) menuItem += 1 menuWindow.addstr(menuItem, 1, str(menuItem) + ".| Show help", curses.color_pair(4) if pos == menuItem else curses.color_pair(1)) menuItem += 1 menuWindow.addstr(menuItem, 1, str(menuItem) + ".| Close menu", curses.color_pair(4) if pos == menuItem else curses.color_pair(1)) menuItem += 1 menuWindow.addstr(menuItem, 1, str(menuItem) + ".| Quit application", curses.color_pair(4) if pos == menuItem else curses.color_pair(1)) menuWindow.refresh() key = menuWindow.getch() if key == curses.KEY_DOWN and pos < (7 if showStartOption else 6): pos += 1 elif key == curses.KEY_UP and pos > 1: pos -= 1 # Wrap around from top of menu elif key == curses.KEY_UP and pos == 1: pos = (7 if showStartOption else 6) # Wrap around from bottom of menu elif key == curses.KEY_DOWN and pos == (7 if showStartOption else 6): pos = 1 # Enter key elif key == ord('\n'): break # Move the selected item by 1 to adjust for the lack of a start option if not showStartOption: pos += 1 # Process the selected option if pos == 1: break if pos == 2: try: CursesFingerprintDialog(self.screen, self.crypto.getLocalFingerprint(), self.crypto.getRemoteFingerprint()).show() except exceptions.CryptoError: CursesDialog(self.screen, "Public key(s) not generated/received yet.", isBlocking=True).show() elif pos == 3: passphrase = self.getKeypairPassphrase(True) utils.saveKeypair(self.crypto, passphrase) CursesDialog(self.screen, "This keypair will be used for all subsequent chats", "Keypair Saved", isBlocking=True).show() elif pos == 4: utils.clearKeypair() CursesDialog(self.screen, "Keypair cleared", isBlocking=True).show() elif pos == 5: CursesDialog(self.screen, "Read the docs at https://cryptully.readthedocs.org/en/latest/", isBlocking=True).show() elif pos == 6: break elif pos == 7: os.kill(os.getpid(), signal.SIGINT) # Shift the selected item position back if not showStartOption: pos -= 1 # Re-enable the cursor curses.curs_set(2) # Get rid of the accept window menuWindow.clear() menuWindow.refresh() def getKeypairPassphrase(self, verify=False): passphraseWindow = self.screen.subwin(3, 36, self.height/2 - 1, self.width/2 - 18) # Turn on echo and wait for enter key to read buffer curses.echo() curses.nocbreak() while True: passphraseWindow.border(0) passphraseWindow.addstr(1, 1, "Passphrase: ") passphraseWindow.refresh() passphrase = getpass('') if not verify: break passphraseWindow.clear() passphraseWindow.border(0) passphraseWindow.addstr(1, 1, "Verify: ") passphraseWindow.refresh() verifyPassphrase = getpass('') if passphrase == verifyPassphrase: break else: curses.cbreak() CursesDialog(self.screen, errors.VERIFY_PASSPHRASE_FAILED, '', isBlocking=True).show() curses.nocbreak() # Turn off echo and disable buffering curses.cbreak() curses.noecho() # Get rid of the passphrase window passphraseWindow.clear() passphraseWindow.refresh() return passphrase def loadOrGenerateKepair(self): self.crypto = Crypto() if utils.doesSavedKeypairExist(): while(True): passphrase = self.getKeypairPassphrase() try: utils.loadKeypair(self.crypto, passphrase) break except exceptions.CryptoError: CursesDialog(self.screen, errors.BAD_PASSPHRASE, '', isBlocking=True).show() # We still need to generate an AES key self.crypto.generateAESKey() else: self.crypto.generateKeys()
settings_group.add_argument('-n', '--hostname', dest='hostname', help='Server hostname for the client to connect to.') settings_group.add_argument('-P', '--port', type=int, dest='port', help='Server port for the client to connect to.') args = vars(parser.parse_args()) config_structure = {'Todo' : ['hostname', 'port']} config = todo_config.get_config(args, config_structure) # Connect to the server if 'hostname' not in config: print 'input error: Specify a hostname in the CLI or config file.' sys.exit(1) if 'port' not in config: config['port'] = Client.DEFAULT_PORT client = Client() client.connect(**config) # Create and send the request to the server message = [] for operation in Client.OPERATIONS: if args[operation]: value = args[operation] if isinstance(args[operation], list) \ else [args[operation]] message.append([Client.OPERATIONS.index(operation), value]) if not message: # Show all tasks if no operation flags specified message.append([Client.OPERATIONS.index('show'), []]) client.send(json.dumps(message)) # Parse the response response = json.loads(client.receive())
class ReplicationManager(GameObjectBase): """ Manages GameObjects that are marked for replication. """ def __init__(self): super().__init__() self.__replicators = {} self.__client = None self.__server = None def add_object(self, replication_id, gob): """Adds a GameObject to be replicated from server to connected clients.""" self.__replicators[replication_id] = gob # DEBUG # logging.debug(f"Added {gob}") logging.debug(self.__replicators) for rep_id, gob in self.__replicators.items(): logging.debug(rep_id) for prop in gob.get_replicated_props(): logging.debug(prop) # DEBUG # def __get_replication_data(self): """ Compiles and returns the dictionary with the data for all the register replicators. The server calls this function after all the game objects have been updated. The compiled data is sent by the server to all the connected clients. """ replication_data = {} for rep_id, gob in self.__replicators.items(): replication_data[rep_id] = {} for prop in gob.get_replicated_props(): replication_data[rep_id][prop] = getattr(gob, prop) return replication_data def __apply_replication_data(self): """ Applies the data received by the client to the registered game objects. The client calls this function at the end of each game update to ensure that all the replicated game objects are in sync with their primary replicas existing on the server. """ pass def start_replication(self): """Starts replication.""" # HACK ALERT! # if self.__find_local_server(): # Found a local server running -> connect to it self.__client = Client(("localhost", 54879)) self.__client.connect("Player2") else: # No local server running -> run one self.__server = Server() self.__server.start() # HACK ALERT! # def update(self, delta): if self.__client: self.__client.tick() @classmethod def __find_local_server(cls): """Tries to connect to a local server. Returns True if successful, False otherwise.""" client = Client(("localhost", 54879)) client.connect("Player2") found_server = False try: client.tick() found_server = True except BrokenPipeError: pass finally: client.stop() return found_server
class ReplicationManager(GameObjectBase): """ Manages GameObjects that are marked for replication. """ def __init__(self): super().__init__() self.__replicators = {} self.__client = None self.__server = None def add_object(self, replication_id, gob): """Adds a GameObject to be replicated from server to connected clients.""" self.__replicators[replication_id] = gob def __compile_replication_data(self): """ Compiles and returns the dictionary with the data for all the register replicators. The server calls this function after all the game objects have been updated. The compiled data is sent by the server to all the connected clients. """ replication_data = {} for rep_id, gob in self.__replicators.items(): replication_data[rep_id] = {} for rep_prop in gob.get_replicated_props(): replication_data[rep_id][rep_prop.name] = rep_prop.packer.pack( getattr(gob, rep_prop.getter)) return replication_data def __apply_replication_data(self, game_state): """ Applies the data received by the client to the registered game objects. The client calls this function at the end of each game update to ensure that all the replicated game objects are in sync with their primary replicas existing on the server. """ for replication_id, replication_data in game_state.items(): gob = self.__replicators.get(replication_id) if gob: for rep_prop in gob.get_replicated_props(): new_value = replication_data.get(rep_prop.name) if new_value: setattr(gob, rep_prop.setter, rep_prop.packer.unpack(new_value)) def start_replication(self): """Starts replication.""" # HACK ALERT! # if self.__find_local_server(): # Found a local server running -> connect to it self.__client = Client(("localhost", 54879)) self.__client.connect("Player2") logging.debug("Started client") else: # No local server running -> run one self.__server = Server() self.__server.start() logging.debug("Started server") # HACK ALERT! # def update(self, delta): """Updates the replication manager.""" if self.__client: if self.__client.tick(): if self.__client.state == ClientState.PLAYING: self.__apply_replication_data( self.__client.get_game_state()) self.__client.reset_game_state() else: self.__client = None elif self.__server: self.__server.propagate_game_state( self.__compile_replication_data()) self.__server.tick() def propagate_input(self, inputs): """Sets the list of input actions collected by the game in the current frame. These are sent to the server.""" if self.__client: self.__client.set_inputs(inputs) @classmethod def __find_local_server(cls): """Tries to connect to a local server. Returns True if successful, False otherwise.""" client = Client(("localhost", 54879)) client.connect("Player2") found_server = False try: client.tick() found_server = True except BrokenPipeError: pass finally: client.stop() return found_server
class Softwar(): def __init__(self): self.map_size = 5 self.game_status = 0 self.me = Player() self.ia = IA(self.me, self) self.enemies = [] self.energy_cells = [] self.networking = Client(sys.argv[1], sys.argv[2], sys.argv[3], self.me) self.gui = GUI("Softwar client", (1024, 1024), self.networking) def update_game_from_notification(self, notification): print("[NOTIFIACTION] RECIEVE : \n", json.dumps(notification, indent=4, sort_keys=True)) if notification["notification_type"] == 0: data = notification["data"] for player in data["players"]: self.update_player_from_game_status(player) self.energy_cells = [] for energy_cell in data["energy_cells"]: self.update_energy_cell_from_game_status(energy_cell) self.map_size = data["map_size"] self.game_status = data["game_status"] if self.me.energy > 0 and self.game_status == 1: self.ia.main_ia() elif notification["notification_type"] == 2: print("[GAME] FIN DE LA PARTIE") self.game_status = 2 # pygame.quit() # sys.exit(0) elif notification["notification_type"] == 3: self.game_status = 2 elif notification["notification_type"] == 4: self.game_status = 2 elif notification["notification_type"] == 5: print("[GAME] NOUVEAU JOUEUR CONNECTÉ") data = notification["data"] self.map_size = data["map_size"] self.add_new_connected_player(data["players"]) def add_new_connected_player(self, players): self.enemies = [] # print("HANDLING NEW PLAYERS NOTIFIACTION : ", players) for player in players: # print("HANDLING JSON PLAYER : %s" % (player)) player["name"] = bytes(player["name"], encoding="ascii") if player["name"] == self.me.name: self.me.update_from_json(player) else: self.enemies.append(Player()) self.enemies[-1].update_from_json(player) self.gui.init_players(self) # print("ENEMIES : ", self.enemies) def update_player_from_game_status(self, player): if not player: return player_to_update = None player["name"] = bytes(player["name"], encoding="ascii") if player["name"] == self.me.name: player_to_update = self.me else: # If game not started, if it's the first game_status notification if self.game_status == 0: # select a enemi in self.enemies that havn't been initialized # print("self.enemies : %s" % (self.enemies)) # player_to_update = [enemi for enemi in self.enemies if not enemi.name][0] player_to_update = self.enemies[-1] else: # select the enemi with the same name player_to_update = [ enemi for enemi in self.enemies if enemi.name == player["name"] ][0] player_to_update.update_from_json(player) def update_energy_cell_from_game_status(self, json_energy_cell): energy_cell = EnergyCell() energy_cell.x = json_energy_cell["x"] energy_cell.y = json_energy_cell["y"] energy_cell.energy = json_energy_cell["energy"] self.energy_cells.append(energy_cell) def connection(self): # Afficher la GUI de loading try: self.networking.identify() self.me.name = self.networking.id except Exception as e: return False return True def wait_game_start(self): # Waiting for game start notification notification = None running = True while (notification is None or notification["notification_type"] != 1) and running: socks = dict(self.networking.poller.poll(0)) if socks.get(self.networking.sub_skt) == zmq.POLLIN: notification = self.networking.recieve_notification() self.update_game_from_notification(notification) self.gui.init_map(self) self.gui.display(self) running = self.gui.handle_events() self.game_status = 1 # Todo : init game gui def disconnect(self): pass def run(self): if not self.connection(): print("[NETWORK] IMPOSSIBLE DE SE CONNECTER AU SERVEUR") return self.gui.init_map(self) self.wait_game_start() print("[NETWORK] LA PARTIE SE LANCE...") self.gui.display(self) running = True sleep(1) while running: socks = dict(self.networking.poller.poll(0)) if socks.get(self.networking.sub_skt) == zmq.POLLIN: notification = self.networking.recieve_notification() self.update_game_from_notification(notification) self.gui.display(self) running = self.gui.handle_events() # TODO: IA self.disconnect() def __str__(self): return "map_size : %s, game_status: %s, enemies: %s, me: %s" % ( self.map_size, self.game_status, self.enemies, self.me)
from network.client import Client c = Client() c.connect() c.disconnect()
from network.client import Client from GUI.game import Game from GUI.board import Board host = "192.168.1.19" port = 50000 unit = 60 if __name__ == "__main__": client = Client(host, port) board = Board(unit, client.color) board.display() game = Game(board, client) game.launchGame() client.mySocket.close()
def __init__(self, port: int): self.client = Client() self.controller = RemoteClient(port) self.handler = Core(self.controller, self.client)