示例#1
0
def client_sync():
    global time_since_last_update

    should_update = time.time() - time_since_last_update > 0.01
    if should_update:
        time_since_last_update = time.time()
    else:
        return


    client_manager = services.client_manager()
    client = None

    if client_manager is not None:
        client = client_manager.get_first_client()

        if client is None:
            return
    else:
        return
    while True:
        pop_element = commandQueue.pop_incoming_command()
        if not pop_element:
            # no more entries left in the queue.
            return False


        if isinstance(pop_element, ProtocolBufferMessage):
            omega.send(client.id, pop_element.msg_id, pop_element.msg)
        elif isinstance(pop_element, HeartbeatMessage):
            # we don't do anything with Heartbeats.
            ts4mp_log("latency", time.time() - pop_element.sent_time, force = True)
            pass
示例#2
0
def server_sync():

    while True:
        with Timer("Server Sync"):
            pop_element = commandQueue.pop_incoming_command()
            if not pop_element:
                # no more entries left in the queue.
                return False

            # this is a server message coming from the client. Don't parse it.
            if isinstance(pop_element, ProtocolBufferMessage):
                continue
            current_line = pop_element.split(',')
            function_name = current_line[0]

            if not function_name:
                continue

            parsed_args = list()
            parse_all_args_except_for_function_name(current_line, function_name, parsed_args)

            stripped_function_name = function_name.strip()
            ts4mp_log("arg_handler", stripped_function_name)

            client_id = replace_client_id_for_ui_commands(stripped_function_name)
            parsed_args[-1] = client_id


            ts4mp_log("client_specific", "New function called {} recieved".format(stripped_function_name))

            create_and_append_pendable_command(client_id, stripped_function_name)

            attempt_command(stripped_function_name, parsed_args)
示例#3
0
def wrapper_client(func, *args, **kwargs):
    # Wrapper for functions that have their data needed to be sent to the server.
    # This is used for client commands so the server can respond.
    # For example, selecting a choice from the pie menu.
    # Only supports one multiplayer client at the moment.

    ts4mp_log("locks", "acquiring outgoing lock")

    parsed_args = []
    for arg in args:
        if isinstance(arg, RequiredTargetParam):
            arg = arg.target_id
        parsed_args.append(arg)
    ts4mp_log("arg_handler",
              "\n" + str(func.__name__) + ", " + str(parsed_args) + "  " +
              str(kwargs),
              force=False)

    commandQueue.queue_outgoing_command("\n" + str(func.__name__) + ", " +
                                        str(parsed_args) + "  " + str(kwargs))

    def do_nothing():
        pass

    return do_nothing
示例#4
0
def _do_command(command_name, *args):
    if command_name in PERFORM_COMMAND_FUNCTIONS:
        PERFORM_COMMAND_FUNCTIONS[command_name](*args)

        ts4mp_log("commands", "There is a command named: {}. Executing it.".format(command_name))
    else:
        ts4mp_log("commands", "There is no such command named: {}!".format(command_name))
示例#5
0
def update(self, time_slice=True):
    ts4mp_log("simulate",
              "Client is online?: {}".format(execution.client_online),
              force=False)

    if execution.client_online:
        # ts4mp_log("simulate", "Client is online?: {}".format(ts4mp.core.mp_essential.client_online), force=True)

        return
    max_time_ms = self.MAX_TIME_SLICE_MILLISECONDS if time_slice else None
    t1 = time.time()
    result = self.sim_timeline.simulate(services.game_clock_service().now(),
                                        max_time_ms=max_time_ms)
    t2 = time.time()

    # ts4mp_log("simulate", "{} ms".format((t2 - t1) * 1000), force=True)
    if not result:
        logger.debug(
            'Did not finish processing Sim Timeline. Current element: {}',
            self.sim_timeline.heap[0])
    result = self.wall_clock_timeline.simulate(
        services.server_clock_service().now())
    if not result:
        logger.error(
            'Too many iterations processing wall-clock Timeline. Likely culprit: {}',
            self.wall_clock_timeline.heap[0])
示例#6
0
def attempt_command(command, function_name, function_to_execute, incoming_commands, parsed_args):
    ts4mp_log('arg_handler', str(function_to_execute))
    try:
        _do_command(function_name, *parsed_args)
    except Exception as e:
        ts4mp_log("Execution Errors", str(e))
    incoming_commands.remove(command)
示例#7
0
def _parse_arg(arg):
    #Horrible, hacky way of parsing arguments from the client commands.
    #DO NOT EVER CHANGE THESE LINES OF CODE.
    #IT WILL SCREW UP OBJECT IDS AND VERY LONG NUMBERS, EVEN THOUGH IT SEEMS THAT THIS CODE IS COMPLETELY
    #USELESS. THE ASSIGNING OF THE VARIABLE TO ANOTHER VARIABLE CAUSES IT TO BREAK IF REMOVED
    new_arg = arg
    bool_arg = None
    if "True" in new_arg:
        bool_arg = True
    elif "False" in new_arg:
        bool_arg = False
    if bool_arg is not None:
        return bool_arg


    orig_arg = new_arg.replace('"', "").replace("(", "").replace(")", "").replace("'", "").strip()
    new_arg = orig_arg
    ts4mp_log("arg_handler", "First pass: "******"\n", force=False)



    try:
        new_arg = float(orig_arg)

        try:
            new_arg = int(orig_arg)
        except BaseException:
            pass
    except BaseException:
        pass 
    ts4mp_log("arg_handler", "Second pass: "******"\n", force=False)

    return new_arg
示例#8
0
def server_sync():

    with incoming_lock:
        global incoming_commands

        for command in incoming_commands:
            # this is a server message coming from the client. Don't parse it.
            if isinstance(command, ProtocolBufferMessage):
                continue
            current_line = command.split(',')
            function_name = current_line[0]

            if not function_name:
                continue

            parsed_args = list()
            parse_all_args_except_for_function_name(current_line, function_name, parsed_args)

            stripped_function_name = function_name.strip()
            ts4mp_log("arg_handler", stripped_function_name)

            client_id = replace_client_id_for_ui_commands(stripped_function_name)
            parsed_args[-1] = client_id

            function_to_execute = format_command_to_execute(function_name, parsed_args)

            ts4mp_log("client_specific", "New function called {} recieved".format(stripped_function_name))

            create_and_append_pendable_command(client_id, stripped_function_name)

            attempt_command(command, stripped_function_name, function_to_execute, incoming_commands, parsed_args)
示例#9
0
def remove_unneeded_symbols_from_command(arg_index, current_line):
    arg = current_line[arg_index].replace(')', '').replace('{}', '').replace('(', '').replace("[", "").replace("]", "")
    ts4mp_log("arg_handler", str(arg) + "\n", force=False)
    if "'" not in arg and "True" not in arg and "False" not in arg:
        arg = ALPHABETIC_REGEX.sub('', arg)
        arg = arg.replace('<._ = ', '').replace('>', '')
    return arg
示例#10
0
    def listen_loop(self):
        serversocket = self.serversocket
        size = None
        data = b''
        while self.alive:
            if self.connected:
                try:
                    new_command, data, size = generic_listen_loop(
                        serversocket, data, size)
                    if new_command is not None:
                        # if we've never received data, then this is the first time we've gotten data.
                        # obviously.
                        if not self.ever_recieved_data:
                            show_client_connect_on_client()

                            ts4mp.core.client_utils.on_successful_client_connect(
                            )
                            self.ever_recieved_data = True
                        commandQueue.queue_incoming_command(new_command)
                except socket.error as e:
                    ts4mp_log("sockets",
                              "Catastrophic failure: {}".format(e),
                              force=True)

                    show_client_connection_failure()
                    self.connected = False
示例#11
0
def wrapper_client(func, *args, **kwargs):
    # Wrapper for functions that have their data needed to be sent to the server.
    # This is used for client commands so the server can respond.
    # For example, selecting a choice from the pie menu.
    # Only supports one multiplayer client at the moment.

    ts4mp_log("locks", "acquiring outgoing lock")

    with outgoing_lock:
        # TODO: You should not be referring to a global variable that is in a different module
        parsed_args = []
        for arg in args:
            if isinstance(arg, RequiredTargetParam):
                arg = arg.target_id
            parsed_args.append(arg)
        ts4mp_log("arg_handler",
                  "\n" + str(func.__name__) + ", " + str(parsed_args) + "  " +
                  str(kwargs),
                  force=False)
        outgoing_commands.append("\n" + str(func.__name__) + ", " +
                                 str(parsed_args) + "  " + str(kwargs))
    # we sleep here so the networking threads can send the commands, if you remove this, it will make the response times
    # higher
    time.sleep(0.2)

    def do_nothing():
        pass

    return do_nothing
示例#12
0
    def add_event(self, msg_id, msg, immediate=False):
        if self.client is None:
            logger.error(
                'Could not add event {0} because there are no attached clients',
                msg_id)
            return

        ts4mp_log("client_specific", "Trying to add an event to a client.")
        function_name = get_command_function_from_pb(msg_id)
        ts4mp_log("client_specific", "Function is {}".format(function_name))

        if function_name is not None:
            client_id = try_get_client_id_of_pending_command(function_name)
            ts4mp_log("client_specific", "Client is {}".format(client_id))

            if client_id is not None:
                remove_earliest_command_client(function_name)
                target_client = self.get_client(client_id)

                if target_client is not None:
                    target_client.add_event(msg_id, msg, immediate)
                    ts4mp_log("client_specific", "Adding event to client")
                    return

        ts4mp_log(
            "client_specific",
            "No suitable client found, so I'm just going to send it to everybody"
        )
        self.events.append((msg_id, msg))

        if immediate:
            self.process_events()
示例#13
0
def get_objects_in_view_gen(_connection=None):
    all_objs = []
    for manager in services.client_object_managers():
        for obj in manager.get_all():
            #if issubclass(type(obj), BaseSituation):
                all_objs.append(type(obj))
    ts4mp_log("objs in view", str(all_objs))
示例#14
0
    def get_client(self, client_id):
        for client_distributor in self.client_distributors:
            ts4mp_log(
                "debugging",
                "Attempting to find client distributor with id: {}, currently found: {}"
                .format(client_id, client_distributor.client.id))

            if client_distributor.client.id == client_id:
                return client_distributor
示例#15
0
def distribute_dialog(self, dialog_type, dialog_msg, immediate=False):
    distributor_instance = Distributor.instance()
    distributor_to_send_to = distributor_instance.get_distributor_with_active_sim_matching_sim_id(
        dialog_msg.owner_id)
    distributor_instance.add_event_for_client(distributor_to_send_to,
                                              dialog_type, dialog_msg,
                                              immediate)

    if dialog_msg:
        ts4mp_log("events", "{}".format(str(dialog_msg.owner_id)))
示例#16
0
def server_sync():
    ts4mp_log("locks", "acquiring incoming lock 1")

    with incoming_lock:
        global incoming_commands

        for command in incoming_commands:
            current_line = command.split(',')
            function_name = current_line[0]

            if not function_name:
                continue

            parsed_args = list()

            for arg_index in range(1, len(current_line)):
                arg = current_line[arg_index].replace(')', '').replace(
                    '{}', '').replace('(', '')

                if "'" not in arg:
                    arg = ALPHABETIC_REGEX.sub('', arg)
                    arg = arg.replace('<._ = ', '').replace('>', '')

                parsed_arg = _parse_arg(arg)
                parsed_args.append(parsed_arg)

            # set connection to other client
            client_id = 1000
            parsed_args[-1] = client_id

            function_to_execute = "{}({})".format(
                function_name,
                str(parsed_args).replace('[', '').replace(']', ''))
            function_name = function_name.strip()

            ts4mp_log("client_specific",
                      "New function called {} recieved".format(function_name))

            if function_name in pendable_functions:
                with pending_commands_lock:
                    if function_name not in pending_commands:
                        pending_commands[function_name] = []
                    if client_id not in pending_commands[function_name]:
                        pending_commands[function_name].append(client_id)

            ts4mp_log('arg_handler', str(function_to_execute))

            try:
                _do_command(function_name, *parsed_args)
            except Exception as e:
                ts4mp_log("Execution Errors", str(e))

            incoming_commands.remove(command)

    ts4mp_log("locks", "releasing incoming lock")
示例#17
0
def show_notif(sim, text):
    title = "{} said".format(
        Distributor.instance().get_distributor_with_active_sim_matching_sim_id(
            sim.id).client._account.persona_name)
    ts4mp_log("chat", LocalizationHelperTuning.get_raw_text(text))

    notification = UiDialogNotification.TunableFactory().default(
        sim,
        text=lambda **_: LocalizationHelperTuning.get_raw_text(text),
        title=lambda **_: LocalizationHelperTuning.get_raw_text(title))
    notification.show_dialog(icon_override=(None, sim))
    def send_loop(self):
        while self.alive:
            if self.clientsocket is not None:
                ts4mp_log("locks", "acquiring outgoing lock")

                with outgoing_lock:
                    for data in outgoing_commands:
                        generic_send_loop(data, self.clientsocket)
                        outgoing_commands.remove(data)

                ts4mp_log("locks", "releasing outgoing lock")
示例#19
0
    def get_distributor_with_active_sim_matching_sim_id(self, sim_id):
        for client_distributor in self.client_distributors:
            if client_distributor.client.active_sim is not None:
                ts4mp_log(
                    "chat", "Active client sim id: {}".format(
                        client_distributor.client.active_sim.id))

                if client_distributor.client.active_sim.id == sim_id:
                    return client_distributor

        return None
    def send_loop(self):
        self.serversocket.connect((self.host, self.port))
        self.connected = True

        while self.alive:
            ts4mp_log("locks", "acquiring outgoing lock")

            with outgoing_lock:
                for data in outgoing_commands:
                    generic_send_loop(data, self.serversocket)
                    outgoing_commands.remove(data)

            ts4mp_log("locks", "releasing outgoing lock")
示例#21
0
        def enter_dialog_callback(dialog):
            if not dialog.accepted:
                return
            dialog_text = dialog.text_input_responses.get("dialog")
            ts4mp_log("chat", 'Showing message')

            distributor = Distributor.instance(
            ).get_distributor_with_active_sim_matching_sim_id(target_id)
            if distributor is not None:
                client = distributor.client
                ts4mp_log("chat", 'Showing message')

                show_notif(client.active_sim, dialog_text)
示例#22
0
def generic_listen_loop(socket, data, size):
    try:
        new_command = None
        if size is None:
            ts4mp_log("networking state", "Receiving length")

            size = socket.recv(8)
            (size, ) = unpack('>Q', size)
            ts4mp_log("networking state", "Received length is {}".format(size))

            size = int(size)
        elif size > len(data):
            bytes_to_receive = size - len(data)
            ts4mp_log("networking state", "Receiving data")

            new_data = socket.recv(bytes_to_receive)
            data += new_data
        elif size == len(data):
            data = pickle.loads(data)
            new_command = data
            size = None
            data = b''

        return new_command, data, size
    except Exception as e:
        ts4mp_log("critical error", str(e))
示例#23
0
 def send_loop(self):
     while self.alive:
         messages_sent = 0
         if self.clientsocket is not None:
             ts4mp_log("Messages",
                       "Sending {} messages".format(len(outgoing_commands)))
             with outgoing_lock:
                 for data in outgoing_commands:
                     generic_send_loop(data, self.clientsocket)
                     outgoing_commands.remove(data)
                     messages_sent += 1
                     if messages_sent >= 100:
                         break
             time.sleep(0.2)
示例#24
0
def send_lot_architecture_and_reload(_connection=None):
    output = sims4.commands.CheatOutput(_connection)
    output("working")

    zone = services.current_zone()
    name = str(hex(zone.id)).replace("0x", "")

    ts4mp_log("zone_id", "{}, {}".format(name, zone.id))

    (file_path, file_name) = get_file_matching_name(name)

    if file_path is not None:
        with outgoing_lock:
            ts4mp_log("zone_id", "{}, {}".format(file_path, file_name))
            msg = File(name, open(file_path, "rb").read())
            outgoing_commands.append(msg)
    def listen_loop(self):
        self.serversocket.listen(5)
        self.clientsocket, address = self.serversocket.accept()

        ts4mp_log("network", "Client Connect")

        clientsocket = self.clientsocket
        size = None
        data = b''

        while self.alive:
            new_command, data, size = generic_listen_loop(
                clientsocket, data, size)
            if new_command is not None:
                with incoming_lock:
                    ts4mp.core.mp_essential.incoming_commands.append(
                        new_command)
示例#26
0
def get_file_matching_name(name):
    scratch_directory = "{}saves/scratch".format(get_sims_documents_directory())

    file_path = ""
    file_name = ""

    for root, _, files in os.walk(scratch_directory):
        for file_name in files:
            replaced = file_name.replace("zoneObjects-", "").replace("-6.sav", "").strip()
            replaced = replaced[1:]

            ts4mp_log("zone_id", "{} , {}".format(replaced, name))

            if name == replaced:
                file_path = str(os.path.join(root, file_name))
                break

    return (file_path, file_name)
示例#27
0
def mp_chat(target_id=None, _connection=None):
    try:
        target_id = int(target_id)

        ts4mp_log("chat", target_id)
        distributor = Distributor.instance(
        ).get_distributor_with_active_sim_matching_sim_id(target_id)

        client = distributor.client
        ts4mp_log("chat", client)

        def enter_dialog_callback(dialog):
            if not dialog.accepted:
                ts4mp_log("chat", "Dialog was not accepted.")
                return
            dialog_text = dialog.text_input_responses.get("dialog")
            ts4mp_log("chat", 'Showing message')

            distributor = Distributor.instance(
            ).get_distributor_with_active_sim_matching_sim_id(target_id)
            if distributor is not None:
                client = distributor.client
                ts4mp_log("chat", 'Showing message')

                show_notif(client.active_sim, dialog_text)

        localized_title = lambda **_: LocalizationHelperTuning.get_raw_text(
            "Say Something")
        localized_text = lambda **_: LocalizationHelperTuning.get_raw_text(
            "Say something to anybody who's listening.")
        localized_fname = lambda **_: LocalizationHelperTuning.get_raw_text(
            "Type your message here!")
        localized_lname = lambda **_: LocalizationHelperTuning.get_raw_text(
            "Type your emote here!")

        text_input_1 = UiTextInput(sort_order=0)
        text_input_1.default_text = localized_fname
        text_input_1.title = None
        text_input_1.max_length = 100
        text_input_1.initial_value = localized_fname
        text_input_1.length_restriction = Scum_TextInputLengthName()

        inputs = AttributeDict({'dialog': text_input_1})
        dialog = UiDialogTextInputOkCancel.TunableFactory().default(
            client.active_sim,
            text=localized_text,
            title=localized_title,
            text_inputs=inputs,
            is_special_dialog=True)
        ts4mp_log("chat", "Dialog id: {}".format(dialog.dialog_id))
        dialog.add_listener(enter_dialog_callback)
        dialog.show_dialog()
    except Exception as e:
        ts4mp_log('chat', e)
示例#28
0
    def send_loop(self):
        try:
            self.serversocket.connect((self.host, self.port))
            self.connected = True

            while self.alive:

                with outgoing_lock:
                    with Timer("send network time"):
                        for data in outgoing_commands:
                            generic_send_loop(data, self.serversocket)
                            outgoing_commands.remove(data)

                # time.sleep(1)
        except Exception as e:
            show_client_connection_failure()
            ts4mp_log("sockets", str(e))

            self.connected = False
def send_message_server(self, msg_id, msg):
    # Send message override for the server.
    # This overrides it so any message for a client with an id of 1000 gets packed into a Message and is placed in the outgoing_commands list for
    # sending out to the multiplayer clients.
    # Only supports one multiplayer client at the moment.

    # TODO: You should not be referring to a global variable that is in a different module
    if self.id != 1000 and self.active:
        omega.send(self.id, msg_id, msg.SerializeToString())
        # ts4mp_log_debug("msg", msg)
    else:
        message = Message(msg_id, msg.SerializeToString())

        ts4mp_log("locks", "acquiring outgoing lock")

        # We use a lock here because outgoing_commands is also being altered by the client socket thread.
        with outgoing_lock:
            outgoing_commands.append(message)

        ts4mp_log("locks", "releasing outgoing lock")
示例#30
0
def create_plumbbob(_connection=None):
    # Gets the current client connection
    try:
        sim_instance = services.get_active_sim()
        sim_position = sim_instance.position

        new_plumbob_position = sims4.math.Vector3(float(sim_position.x),
                                                  float(sim_position.y),
                                                  float(sim_position.z))

        plumbob_object = objects.system.create_object(9716920233444718179)
        plumbob_object.move_to(translation=new_plumbob_position)

        # output = sims4.commands.CheatOutput(_connection)
        # output("Spawned plumbob")
        # SetAsHead.set_head_object(current_sim, created_obj, "0F97B21B")
        # output("plumb", dir(created_obj))

        plumbob_object.set_parent(sim_instance)
    except Exception as e:
        ts4mp_log("plumb", e)