Exemple #1
0
class SimpleServerTest(unittest.TestCase):
    def verify_client_msg(self, msg):
        assert(not self.received_message)
        assert(msg == "hello server")
        self.received_message = True

    def got_client(self, client):
        assert(self.connected_client == None)
        client.set_read_callback(lambda msg: self.verify_client_msg(msg))
        self.connected_client = client

    def setUp(self):
        # create a socket and server:
        self.test_socket = socket.socket(family=socket.AF_INET6,
            type=socket.SOCK_STREAM)
        self.server = SimpleServer(12345, lambda client: self.got_client(\
            client))

    def tearDown(self):
        # close test socket and server:
        self.test_socket.close()
        self.server.close()

    def test_server(self):
        print("test_server.py: test_server start")        
        self.received_message = False
        self.connected_client = None
        
        # connect socket to server:
        self.test_socket.connect(("::1", 12345, 0, 0))
        assert(self.connected_client == None)
        
        # only after a tick, the server should recognise the new client:
        assert(self.server.tick() == 1)
        assert(self.connected_client != None)
        assert(self.received_message == False)

        # send something from the server to the client:
        self.connected_client.send("hello client")
        assert(self.server.tick() == 1)
        received_str = self.test_socket.recv(512).decode("utf-8")
        assert(received_str == "hello client\n")

        # send something from the client to the server:
        self.test_socket.send("hello server\n".encode("utf-8"))
        assert(self.received_message == False)
        assert(self.server.tick() == 1)

        # only after a tick, the message should arrive with the server:
        assert(self.received_message == True)

        # send bye to client but close connection immediately afterwards:
        self.connected_client.send("bye client")
        self.connected_client.close()
        assert(self.server.tick() == 1)

        # the goodbye should still arrive:
        assert(self.test_socket.recv(512).decode("utf-8") == "bye client\n")
        assert(self.server.tick() == 0)

        # test complete!

        print("test_server.py: test_server end")
Exemple #2
0
class OnlineGame(Game):
    def __init__(self, game_path, port, version_str):
        super(OnlineGame, self).__init__(game_path)

        self.connections = []
        self.port = port
        self.version_str = version_str
        self.required_client_version = 1

        module_instances = get_module_instances()
        logging.info("Starting game with " + str(len(module_instances))\
            + " module instances available")
        for module in module_instances.values():
            if isinstance(module, OnlineGameBaseModule):
                module.set_online_game_instance(self)
            else:
                module.set_game_instance(self)

    def split_args(self, args_line):
        if len(args_line) == 0:
            return []

        splitted_list = args_line.split(":", 1)
        last_arg = ""
        if len(splitted_list) == 2:
            last_arg = splitted_list[1].strip()

        splittable_args = splitted_list[0]
        while splittable_args.find("  ") >= 0:
            splittable_args = splittable_args.replace("  ", " ")
        args = splittable_args.split(" ")
        if len(args[0]) == 0:
            del args[0]

        if len(last_arg) > 0:
            args.append(last_arg)
        return args

    def connection_has_data(self, connection, data):
        data = data.strip()
        if len(data) == 0:
            return
        module = data.split(" ", 1)[0]
        data = data[len(module)+1:]

        cmd = data.split(" ", 1)[0]
        args = self.split_args(data[len(cmd)+1:])
        if len(cmd) == 0:
            connection.send("core error-empty-cmd")
            return

        if not module == "core":
            module_instances = get_module_instances()
            # forward to appropriate module:
            if module in module_instances:
                if not connection.connected_as_client:
                    if not isinstance(module_instances[module], \
                            OnlineGameBaseModule):
                        connection.send("core error-module-unavailable " +\
                            module)
                        return
                    self.process_cmd(connection, module, cmd, args)
                    return
                self.process_cmd(connection.client, module, cmd, args)
                return
            # module not found:
            connection.send("core error-invalid-module :" + module)
            return
        else:
            if cmd == "quit":
                connection.send("core confirm-quit :Bye!")
                connection.close()
                self.connections.remove(connection)
            elif cmd == "ping":
                if len(args) == 0:
                    connection.send("core error-missing-arguments core ping")
                    return
                if len(args[0]) > 64:
                    connection.send("core error-invalid-argument core " +\
                        "ping 1 :excessive length")
                    return
                connection.send("core pong :" + args[0]) 
            else:
                connection.send("core error-unknown-cmd core :" + cmd)

    def server_reports_new_connection(self, connection):
        connection.connected_as_client = False
        connection.set_read_callback(lambda data:
            self.connection_has_data(connection, data))
        self.connections.append(connection)
        connection.send("core hello-msg :Hello client! This is Miracle "\
            "Crafter Server Version " + self.version_str)
        connection.send("core version-info " + self.version_str + " :" + \
            "unmodified")
        connection.send("core available-server-protocol-extensions :" + \
            "core")
        connection.send("core required-client-protocol-extensions :" + \
            "core")
        connection.send("core required-client-version " +\
            str(self.required_client_version))

    def run(self):
        self.server = SimpleServer(self.port, \
            self.server_reports_new_connection)
        frame_time = 1/10
        while 1:
            self.server.tick(frame_time)