예제 #1
0
 def load_config(self):
     try:
         self.colors = DotDict(self.config.config.colors)
         self.logger.info("Configuration loaded!")
     except:
         self.logger.warning(
             "Failed to load from config! Initiating with default values")
         self.colors = DotDict({
             "Admin": "^#F7434C",
             "SuperAdmin": "^#E23800;",
             "Admin": "^#C443F7;",
             "Moderator": "^#4385F7",
             "Registered": "^#A0F743;",
             "default": "^green;"
         })
예제 #2
0
 def get_plugin_config(self, plugin_name):
     if plugin_name not in self.config.plugins:
         storage = DotDict({})
         self.config.plugins[plugin_name] = storage
     else:
         storage = self.config.plugins[plugin_name]
     return storage
예제 #3
0
    def get_storage(self, caller):
        """
        Collect the storage for caller.

        :param caller: Entity requesting its storage
        :return: Storage shelf for caller. If called doesn't have anything in
                 storage, return an empty shelf.
        """
        name = caller.name
        if name not in self.plugin_shelf:
            self.plugin_shelf[name] = DotDict({})
        return self.plugin_shelf[name]
예제 #4
0
 def load_config(self, path, default=False):
     if not isinstance(path, Path):
         path = Path(path)
     if default:
         self.load_defaults(path)
     try:
         with path.open() as f:
             self._raw_config = f.read()
     except FileNotFoundError:
         path.touch()
         with path.open("w") as f:
             f.write("{}")
         self._raw_config = "{}"
     self._path = path
     recursive_dictionary_update(self._config, json.loads(self._raw_config))
     if "plugins" not in self._config:
         self._config['plugins'] = DotDict({})
예제 #5
0
 def load_config(self, path, default=False):
     if not isinstance(path, Path):
         path = Path(path)
     if default:
         self.load_defaults(path)
     try:
         with path.open() as f:
             self._raw_config = f.read()
     except FileNotFoundError:
         path.touch()
         with path.open("w") as f:
             f.write("{}")
         self._raw_config = "{}"
     self._path = path
     try:
         recursive_dictionary_update(self._config,
                                     json.loads(self._raw_config))
     except ValueError as e:
         logger.error("Error while loading config.json file:\n\t"
                      "{}".format(e))
         sys.exit(1)
     if "plugins" not in self._config:
         self._config['plugins'] = DotDict({})
예제 #6
0
class ChatEnhancements(StorageCommandPlugin):
    name = "chat_enhancements"
    depends = ["player_manager", "command_dispatcher"]
    default_config = {"chat_timestamps": True,
                      "timestamp_color": "^gray;",
                      "colors": DotDict({
                          "Owner": "^#F7434C;",
                          "SuperAdmin": "^#E23800;",
                          "Admin": "^#C443F7;",
                          "Moderator": "^#4385F7;",
                          "Registered": "^#A0F743;",
                          "default": "^yellow;"
                      })}

    def __init__(self):
        super().__init__()
        self.command_dispatcher = None
        self.colors = None
        self.cts = None
        self.cts_color = None
        self.last_whisper = {}

    def activate(self):
        super().activate()
        self.command_dispatcher = self.plugins.command_dispatcher.plugin_config
        self.colors = self.config.get_plugin_config(self.name)["colors"]
        self.cts = self.config.get_plugin_config(self.name)["chat_timestamps"]
        self.cts_color = self.config.get_plugin_config(self.name)[
            "timestamp_color"]
        self.last_whisper = {}
        link_plugin_if_available(self, "irc_bot")
        if "ignores" not in self.storage:
            self.storage["ignores"] = {}

    # Packet hooks - look for these packets and act on them

    def on_connect_success(self, data, connection):
        """
        Catch when a successful connection is established. Set the player's
        chat style to be the server default.

        :param data:
        :param connection:
        :return: Boolean: True. Must be true, so that packet get passed on.
        """
        return True

    def on_chat_received(self, data, connection):
        sender = ""
        if data["parsed"]["name"]:
            if data["parsed"]["name"] != "server":
                sender = self.plugins['player_manager'].get_player_by_name(
                    data["parsed"]["name"])
                if connection.player.uuid not in self.storage["ignores"]:
                    self.storage["ignores"][connection.player.uuid] = []
                if sender.uuid in self.storage["ignores"][
                    connection.player.uuid]:
                    return False
                try:
                    sender = self.decorate_line(sender.connection)
                except AttributeError:
                    self.logger.warning("Sender {} is sending a message that "
                                        "the wrapper isn't handling correctly"
                                        "".format(data["parsed"]["name"]))
                    sender = data["parsed"]["name"]

        yield from send_message(connection,
                                data["parsed"]["message"],
                                mode=data["parsed"]["header"]["mode"],
                                client_id=data["parsed"]["header"]["client_id"],
                                name=sender,
                                channel=data["parsed"]["header"]["channel"])

    def on_chat_sent(self, data, connection):
        """
        Catch when someone sends a message. Add a timestamp to the message (if
        that feature is turned on). Colorize the player's name based on their
        role.

        :param data: The packet containing the message.
        :param connection: The connection from which the packet came.
        :return: Boolean. True if an error occurred while generating a colored
                 name (so that we don't stop the packet from flowing). Null if
                 the message came from the server (since it doesn't need
                 colors) or if the message is a command.
        """
        message = data['parsed']['message']
        if message.startswith(self.command_dispatcher.command_prefix):
            return True
        if self.plugins['chat_manager'].mute_check(connection.player):
            return False

        return True

    # Helper functions - Used by commands

    def decorate_line(self, connection):
        if self.cts:
            now = datetime.now()
            timestamp = "{}{}{}> <".format(self.cts_color,
                                           now.strftime("%H:%M"),
                                           "^reset;")
        else:
            timestamp = ""
        try:
            sender = timestamp + self._colored_name(connection.player)
        except AttributeError as e:
            self.logger.warning(
                "AttributeError in colored_name: {}".format(str(e)))
            sender = connection.player.alias
        return sender

    def _colored_name(self, data):
        """
        Generate colored name based on target's role.

        :param data: target to check against
        :return: DotDict. Name of target will be colorized.
        """
        if "Owner" in data.roles:
            color = self.colors.Owner
        elif "SuperAdmin" in data.roles:
            color = self.colors.SuperAdmin
        elif "Admin" in data.roles:
            color = self.colors.Admin
        elif "Moderator" in data.roles:
            color = self.colors.Moderator
        elif "Registered" in data.roles:
            color = self.colors.Registered
        else:
            color = self.colors.default

        return color + data.alias + "^reset;"

    @asyncio.coroutine
    def _send_to_server(self, message, mode, connection):
        msg_base = data_parser.ChatSent.build(dict(message=" ".join(message),
                                                   send_mode=mode))
        msg_packet = pparser.build_packet(packets.packets['chat_sent'],
                                          msg_base)
        yield from connection.client_raw_write(msg_packet)

    # Commands - In-game actions that can be performed

    @Command("l",
             doc="Send message only to people on same world.",
             syntax="(message)")
    def _local(self, data, connection):
        """
        Local chat. Sends a message only to characters who are on the same
        planet.

        :param data: The packet containing the command.
        :param connection: The connection from which the packet came.
        :return: Null
        """
        if self.plugins['chat_manager'].mute_check(connection.player):
            send_message(connection, "You are muted and cannot chat.")
            return False
        if data:
            yield from self._send_to_server(data,
                                            ChatSendMode.LOCAL,
                                            connection)
            return True

    @Command("u",
             doc="Send message to the entire universe.",
             syntax="(message)")
    def _universe(self, data, connection):
        """
        Universal chat. Sends a message that everyone can see.

        :param data: The packet containing the command.
        :param connection: The connection from which the packet came.
        :return: Null
        """
        if self.plugins['chat_manager'].mute_check(connection.player):
            send_message(connection, "You are muted and cannot chat.")
            return False
        if data:
            yield from self._send_to_server(data,
                                            ChatSendMode.UNIVERSE,
                                            connection)
            if link_plugin_if_available(self, "irc_bot"):
                # Try sending it to IRC if we have that available.
                asyncio.ensure_future(
                    self.plugins["irc_bot"].bot_write(
                        "<{}> {}".format(connection.player.alias,
                                         " ".join(data))))
            if link_plugin_if_available(self, "discord_bot"):
                discord = self.plugins['discord_bot']
                asyncio.ensure_future(discord.bot.send_message(
                    discord.bot.get_channel(discord.channel),
                    "**<{}>** {}".format(connection.player.alias, " ".join(
                        data))))
            return True

    @Command("p",
             doc="Send message to only party members.")
    def _party(self, data, connection):
        """
        Party chat. Sends a message to only members of your party.

        :param data: The packet containing the command.
        :param connection: The connection from which the packet came.
        :return: Null
        """
        if self.plugins['chat_manager'].mute_check(connection.player):
            send_message(connection, "You are muted and cannot chat.")
            return False
        if data:
            yield from self._send_to_server(data,
                                            ChatSendMode.PARTY,
                                            connection)
            return True

    @Command("whisper", "w",
             doc="Send message privately to a person.")
    def _whisper(self, data, connection):
        """
        Whisper. Sends a message to only one person.

        This command shadows the built-in whisper.

        :param data: The packet containing the command.
        :param connection: The connection from which the packet came.
        :return: Null
        """
        try:
            name = data[0]
        except IndexError:
            raise SyntaxWarning("No target provided.")

        recipient = self.plugins.player_manager.find_player(name)
        if recipient is not None:
            if not recipient.logged_in:
                send_message(connection,
                             "Player {} is not currently logged in."
                             "".format(recipient.alias))
                return False
            if connection.player.uuid in self.storage["ignores"][recipient.uuid]:
                send_message(connection, "Player {} is currently ignoring you."
                             .format(recipient.alias))
                return False
            if recipient.uuid in self.storage["ignores"][
                connection.player.uuid]:
                send_message(connection, "Cannot send message to player {} "
                                         "as you are currently ignoring "
                                         "them.".format(recipient.alias))
                return False
            self.last_whisper[recipient.uuid] = connection.player.alias
            self.last_whisper[connection.player.uuid] = recipient.alias
            message = " ".join(data[1:])
            client_id = connection.player.client_id
            sender = self.decorate_line(connection)
            send_mode = ChatReceiveMode.WHISPER
            channel = "Private"
            yield from send_message(recipient.connection,
                                    message,
                                    client_id=client_id,
                                    name=sender,
                                    mode=send_mode,
                                    channel=channel)
            yield from send_message(connection,
                                    message,
                                    client_id=client_id,
                                    name=sender,
                                    mode=send_mode,
                                    channel=channel)
        else:
            yield from send_message(connection,
                                    "Couldn't find a player with name {}"
                                    "".format(name))

    @Command("reply", "r",
             doc="Send message privately to the last person who privately " \
                 "messaged you.")
    def _reply(self, data, connection):
        """
        Reply. Sends a message to the last person who whispered you.

        :param data: The packet containing the command.
        :param connection: The connection from which the packet came.
        :return: Null
        """
        if connection.player.uuid in self.last_whisper:
            name = self.last_whisper[connection.player.uuid]
            recipient = self.plugins.player_manager.find_player(name)
        else:
            recipient = None
        if recipient is not None:
            if not recipient.logged_in:
                send_message(connection,
                             "Player {} is not currently logged in."
                             "".format(recipient.alias))
                return False
            if connection.player.uuid in self.storage["ignores"][recipient.uuid]:
                send_message(connection, "Player {} is currently ignoring you."
                             .format(recipient.alias))
                return False
            if recipient.uuid in self.storage["ignores"][
                connection.player.uuid]:
                send_message(connection, "Cannot send message to player {} "
                                         "as you are currently ignoring "
                                         "them.".format(recipient.alias))
                return False
            self.last_whisper[recipient.uuid] = connection.player.alias
            self.last_whisper[connection.player.uuid] = recipient.alias
            message = " ".join(data)
            client_id = connection.player.client_id
            sender = self.decorate_line(connection)
            send_mode = ChatReceiveMode.WHISPER
            channel = "Private"
            yield from send_message(recipient.connection,
                                    message,
                                    client_id=client_id,
                                    name=sender,
                                    mode=send_mode,
                                    channel=channel)
            yield from send_message(connection,
                                    message,
                                    client_id=client_id,
                                    name=sender,
                                    mode=send_mode,
                                    channel=channel)
        else:
            yield from send_message(connection,
                                    "You haven't been messaged by anyone.")

    @Command("ignore",
             doc="Ignores a player, preventing you from seeing their "
                 "messages. Use /ignore again to toggle.")
    def _ignore(self, data, connection):
        user = connection.player.uuid
        try:
            name = data[0]
        except IndexError:
            raise SyntaxWarning("No target provided.")
        target = self.plugins.player_manager.find_player(name)
        if target is not None:
            if target == connection.player:
                send_message(connection, "Can't ignore yourself!")
                return False
            if not self.storage["ignores"][user]:
                self.storage["ignores"][user] = []
            if target.uuid in self.storage["ignores"][user]:
                self.storage["ignores"][user].remove(target.uuid)
                yield from send_message(connection, "User {} removed from "
                                        "ignores list.".format(target.alias))
            else:
                self.storage["ignores"][user].append(target.uuid)
                yield from send_message(connection, "User {} added to ignores "
                                        "list.".format(target.alias))
예제 #7
0
class BasePlugin(metaclass=BaseMeta):
    """
    Defines an interface for all plugins to inherit from. Note that the init
    method should generally not be overrode; all setup work should be done in
    activate() if possible. If you do override __init__, remember to super()!

    Note that only one instance of each plugin will be instantiated for *all*
    connected clients. self.connection will be changed by the plugin
    manager to the current connection.

    You may access the factory if necessary via self.factory.connections
    to access other clients, but this "Is Not A Very Good Idea" (tm)

    `name` *must* be defined in child classes or else the plugin manager will
    complain quite thoroughly.
    """

    name = "Base Plugin"
    description = "The common class for all plugins to inherit from."
    version = ".1"
    depends = ()
    default_config = None
    plugins = DotDict({})
    auto_activate = True

    def __init__(self):
        self.loop = asyncio.get_event_loop()
        self.plugin_config = self.config.get_plugin_config(self.name)
        if isinstance(self.default_config, collections.Mapping):
            temp = recursive_dictionary_update(self.default_config,
                                               self.plugin_config)
            self.plugin_config.update(temp)

        else:
            self.plugin_config = self.default_config

    def activate(self):
        pass

    def deactivate(self):
        pass

    def on_protocol_request(self, data, connection):
        """Packet type: 0 """
        return True

    def on_protocol_response(self, data, connection):
        """Packet type: 1 """
        return True

    def on_server_disconnect(self, data, connection):
        """Packet type: 2 """
        return True

    def on_connect_success(self, data, connection):
        """Packet type: 3 """
        return True

    def on_connect_failure(self, data, connection):
        """Packet type: 4 """
        return True

    def on_handshake_challenge(self, data, connection):
        """Packet type: 5 """
        return True

    def on_chat_received(self, data, connection):
        """Packet type: 6 """
        return True

    def on_universe_time_update(self, data, connection):
        """Packet type: 7 """
        return True

    def on_celestial_response(self, data, connection):
        """Packet type: 8 """
        return True

    def on_player_warp_result(self, data, connection):
        """Packet type: 9 """
        return True

    def on_client_connect(self, data, connection):
        """Packet type: 10 """
        return True

    def on_client_disconnect_request(self, data, connection):
        """Packet type: 11 """
        return True

    def on_handshake_response(self, data, connection):
        """Packet type: 12 """
        return True

    def on_player_warp(self, data, connection):
        """Packet type: 13 """
        return True

    def on_fly_ship(self, data, connection):
        """Packet type: 14 """
        return True

    def on_chat_sent(self, data, connection):
        """Packet type: 15 """
        return True

    def on_celestial_request(self, data, connection):
        """Packet type: 16 """
        return True

    def on_client_context_update(self, data, connection):
        """Packet type: 17 """
        return True

    def on_world_start(self, data, connection):
        """Packet type: 18 """
        return True

    def on_world_stop(self, data, connection):
        """Packet type: 19 """
        return True

    def on_central_structure_update(self, data, connection):
        """Packet type: 20 """
        return True

    def on_tile_array_update(self, data, connection):
        """Packet type: 21 """
        return True

    def on_tile_update(self, data, connection):
        """Packet type: 22 """
        return True

    def on_tile_liquid_update(self, data, connection):
        """Packet type: 23 """
        return True

    def on_tile_damage_update(self, data, connection):
        """Packet type: 24 """
        return True

    def on_tile_modification_failure(self, data, connection):
        """Packet type: 25 """
        return True

    def on_give_item(self, data, connection):
        """Packet type: 26 """
        return True

    def on_environment_update(self, data, connection):
        """Packet type: 27 """
        return True

    def on_entity_interact_result(self, data, connection):
        """Packet type: 28 """
        return True

    def on_update_tile_protection(self, data, connection):
        """Packet type: 29 """
        return True

    def on_set_player_start(self, data, connection):
        """Packet type: 30 """
        return True

    def on_find_unique_entity_response(self, data, connection):
        """Packet type: 31 """
        return True

    def on_modify_tile_list(self, data, connection):
        """Packet type: 32 """
        return True

    def on_damage_tile_group(self, data, connection):
        """Packet type: 33 """
        return True

    def on_collect_liquid(self, data, connection):
        """Packet type: 34 """
        return True

    def on_request_drop(self, data, connection):
        """Packet type: 35 """
        return True

    def on_spawn_entity(self, data, connection):
        """Packet type: 36 """
        return True

    def on_entity_interact(self, data, connection):
        """Packet type: 37 """
        return True

    def on_connect_wire(self, data, connection):
        """Packet type: 38 """
        return True

    def on_disconnect_all_wires(self, data, connection):
        """Packet type: 39 """
        return True

    def on_world_client_state_update(self, data, connection):
        """Packet type: 40 """
        return True

    def on_find_unique_entity(self, data, connection):
        """Packet type: 41 """
        return True

    def on_entity_create(self, data, connection):
        """Packet type: 42 """
        return True

    def on_entity_update(self, data, connection):
        """Packet type: 43 """
        return True

    def on_entity_destroy(self, data, connection):
        """Packet type: 44 """
        return True

    def on_hit_request(self, data, connection):
        """Packet type: 45 """
        return True

    def on_damage_request(self, data, connection):
        """Packet type: 46 """
        return True

    def on_damage_notification(self, data, connection):
        """Packet type: 47 """
        return True

    def on_entity_message(self, data, connection):
        """Packet type: 48 """
        return True

    def on_entity_message_response(self, data, connection):
        """Packet type: 49 """
        return True

    def on_update_world_properties(self, data, connection):
        """Packet type: 50 """
        return True

    def on_step_update(self, data, connection):
        """Packet type: 51 """
        return True

    def __repr__(self):
        return "<Plugin instance: %s (version %s)>" % (self.name, self.version)
예제 #8
0
 def config(self):
     if self._dot_dict is None:
         self._dot_dict = DotDict(self._config)
     return self._dot_dict
예제 #9
0
class BasePlugin(metaclass=BaseMeta):
    """
    Defines an interface for all plugins to inherit from. Note that the __init__
    method should generally not be overrode; all setup work should be done in
    activate() if possible. If you do override __init__, remember to super()!
    
    Note that only one instance of each plugin will be instantiated for *all*
    connected clients. self.protocol will be changed by the plugin manager to
    the current protocol.
    
    You may access the factory if necessary via self.factory.protocols
    to access other clients, but this "Is Not A Very Good Idea" (tm)

    `name` *must* be defined in child classes or else the plugin manager will
    complain quite thoroughly.
    """

    name = "Base Plugin"
    description = "The common class for all plugins to inherit from."
    version = ".1"
    depends = []
    plugins = DotDict({})
    auto_activate = True

    def __init__(self):
        self.loop = asyncio.get_event_loop()

    def activate(self):
        pass

    def deactivate(self):
        pass

    def on_protocol_version(self, data, protocol):
        return True

    def on_server_disconnect(self, data, protocol):
        return True

    def on_handshake_challenge(self, data, protocol):
        return True

    def on_chat_received(self, data, protocol):
        return True

    def on_universe_time_update(self, data, protocol):
        return True

    def on_handshake_response(self, data, protocol):
        return True

    def on_client_context_update(self, data, protocol):
        return True

    def on_world_start(self, data, protocol):
        return True

    def on_world_stop(self, data, protocol):
        return True

    def on_tile_array_update(self, data, protocol):
        return True

    def on_tile_update(self, data, protocol):
        return True

    def on_tile_liquid_update(self, data, protocol):
        return True

    def on_tile_damage_update(self, data, protocol):
        return True

    def on_tile_modification_failure(self, data, protocol):
        return True

    def on_give_item(self, data, protocol):
        return True

    def on_swap_in_container_result(self, data, protocol):
        return True

    def on_environment_update(self, data, protocol):
        return True

    def on_entity_interact_result(self, data, protocol):
        return True

    def on_modify_tile_list(self, data, protocol):
        return True

    def on_damage_tile(self, data, protocol):
        return True

    def on_damage_tile_group(self, data, protocol):
        return True

    def on_request_drop(self, data, protocol):
        return True

    def on_spawn_entity(self, data, protocol):
        return True

    def on_entity_interact(self, data, protocol):
        return True

    def on_connect_wire(self, data, protocol):
        return True

    def on_disconnect_all_wires(self, data, protocol):
        return True

    def on_open_container(self, data, protocol):
        return True

    def on_close_container(self, data, protocol):
        return True

    def on_swap_in_container(self, data, protocol):
        return True

    def on_item_apply_in_container(self, data, protocol):
        return True

    def on_start_crafting_in_container(self, data, protocol):
        return True

    def on_stop_crafting_in_container(self, data, protocol):
        return True

    def on_burn_container(self, data, protocol):
        return True

    def on_clear_container(self, data, protocol):
        return True

    def on_world_update(self, data, protocol):
        return True

    def on_entity_create(self, data, protocol):
        return True

    def on_entity_update(self, data, protocol):
        return True

    def on_entity_destroy(self, data, protocol):
        return True

    def on_status_effect_request(self, data, protocol):
        return True

    def on_update_world_properties(self, data, protocol):
        return True

    def on_heartbeat(self, data, protocol):
        return True

    def on_connect_response(self, data, protocol):
        return True

    def on_chat_sent(self, data, protocol):
        return True

    def on_damage_notification(self, data, protocol):
        return True

    def on_client_connect(self, data, protocol):
        return True

    def on_client_disconnect(self, data, protocol):
        return True

    def on_warp_command(self, data, protocol):
        return True

    def __repr__(self):
        return "<Plugin instance: %s (version %s)>" % (self.name, self.version)
예제 #10
0
 def __init__(self):
     super().__init__()
     self.greeting = None
     self.gifts = DotDict({})
예제 #11
0
class NewPlayerGreeter(SimpleCommandPlugin):
    name = "new_player_greeters"
    depends = ["player_manager"]
    default_config = {"greeting": "Why hello there. You look like you're "
                                  "new here. Here, take this. It should "
                                  "help you on your way.",
                      "gifts": DotDict({
                      })}

    def __init__(self):
        super().__init__()
        self.greeting = None
        self.gifts = DotDict({})

    def activate(self):
        super().activate()
        self.greeting = self.config.get_plugin_config(self.name)["greeting"]
        self.gifts = self.config.get_plugin_config(self.name)["gifts"]

    def on_world_start(self, data, connection):
        """
        Client on world hook. After a client connects, when their world
        first loads, check if they are new to the server (never been seen
        before). If they're new, send them a nice message and give them some
        starter items.

        :param data: The packet saying the client connected.
        :param connection: The connection from which the packet came.
        :return: Boolean: True. Anything else stops the client from being able
                 to connect.
        """
        player = self.plugins['player_manager'].get_player_by_name(
            connection.player.name)
        if hasattr(player, 'seen_before'):
            return True
        else:
            asyncio.ensure_future(self._new_player_greeter(connection))
            asyncio.ensure_future(self._new_player_gifter(connection))
            player.seen_before = True
        return True

    # Helper functions - Used by commands

    @asyncio.coroutine
    def _new_player_greeter(self, connection):
        """
        Helper routine for greeting new players.

        :param connection: The connection we're showing the message to.
        :return: Null.
        """
        yield from asyncio.sleep(1.3)
        yield from send_message(connection,
                                "{}".format(self.greeting),
                                mode=ChatReceiveMode.CHANNEL)
        return

    @asyncio.coroutine
    def _new_player_gifter(self, connection):
        """
        Helper routine for giving items to new players.

        :param connection: The connection we're showing the message to.
        :return: Null.
        """
        yield from asyncio.sleep(2)
        for item, count in self.gifts.items():
            count = int(count)
            if count > 10000 and item != "money":
                count = 10000
            item_base = GiveItem.build(dict(name=item,
                                            count=count,
                                            variant_type=7,
                                            description=""))
            item_packet = pparser.build_packet(packets.packets['give_item'],
                                               item_base)
            yield from asyncio.sleep(.1)
            yield from connection.raw_write(item_packet)
            send_message(connection,
                         "You have been given {} {}".format(str(count), item),
                         mode=ChatReceiveMode.COMMAND_RESULT)
        return
예제 #12
0
 def __init__(self):
     super().__init__()
     self.greeting = None
     self.gifts = DotDict({})
예제 #13
0
class NewPlayerGreeter(SimpleCommandPlugin):
    name = "new_player_greeters"
    depends = ["player_manager"]
    default_config = {
        "greeting":
        "Why hello there. You look like you're "
        "new here. Here, take this. It should "
        "help you on your way.",
        "gifts":
        DotDict({})
    }

    def __init__(self):
        super().__init__()
        self.greeting = None
        self.gifts = DotDict({})

    def activate(self):
        super().activate()
        self.greeting = self.config.get_plugin_config(self.name)["greeting"]
        self.gifts = self.config.get_plugin_config(self.name)["gifts"]

    def on_world_start(self, data, connection):
        """
        Client on world hook. After a client connects, when their world
        first loads, check if they are new to the server (never been seen
        before). If they're new, send them a nice message and give them some
        starter items.

        :param data: The packet saying the client connected.
        :param connection: The connection from which the packet came.
        :return: Boolean: True. Anything else stops the client from being able
                 to connect.
        """
        player = self.plugins['player_manager'].get_player_by_name(
            connection.player.name)
        if hasattr(player, 'seen_before'):
            return True
        else:
            asyncio.ensure_future(self._new_player_greeter(connection))
            asyncio.ensure_future(self._new_player_gifter(connection))
            player.seen_before = True
        return True

    # Helper functions - Used by commands

    @asyncio.coroutine
    def _new_player_greeter(self, connection):
        """
        Helper routine for greeting new players.

        :param connection: The connection we're showing the message to.
        :return: Null.
        """
        yield from asyncio.sleep(1.3)
        yield from send_message(connection,
                                "{}".format(self.greeting),
                                mode=ChatReceiveMode.RADIO_MESSAGE)
        return

    @asyncio.coroutine
    def _new_player_gifter(self, connection):
        """
        Helper routine for giving items to new players.

        :param connection: The connection we're showing the message to.
        :return: Null.
        """
        yield from asyncio.sleep(2)
        for item, count in self.gifts.items():
            count = int(count)
            if count > 10000 and item != "money":
                count = 10000
            item_base = GiveItem.build(
                dict(name=item, count=count, variant_type=7, description=""))
            item_packet = pparser.build_packet(packets.packets['give_item'],
                                               item_base)
            yield from asyncio.sleep(.1)
            yield from connection.raw_write(item_packet)
            send_message(connection,
                         "You have been given {} {}".format(str(count), item),
                         mode=ChatReceiveMode.COMMAND_RESULT)
        return
예제 #14
0
 def get_storage(self, caller):
     name = caller.name
     if name not in self.plugin_shelf:
         self.plugin_shelf[name] = DotDict({})
     return self.plugin_shelf[name]