From bfa37cfb55cde458f9a9401db00c7450fe147325 Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 24 May 2024 05:38:17 +0100 Subject: [PATCH] feat: update plugin metadata --- README.md | 76 +-------------- pyproject.toml | 18 ++-- src/endstone_discord/__init__.py | 3 + src/endstone_discord/discord_plugin.py | 5 + src/endstone_example/__init__.py | 3 - src/endstone_example/example_listener.py | 28 ------ src/endstone_example/example_plugin.py | 115 ----------------------- src/endstone_example/python_command.py | 30 ------ 8 files changed, 20 insertions(+), 258 deletions(-) create mode 100644 src/endstone_discord/__init__.py create mode 100644 src/endstone_discord/discord_plugin.py delete mode 100644 src/endstone_example/__init__.py delete mode 100644 src/endstone_example/example_listener.py delete mode 100644 src/endstone_example/example_plugin.py delete mode 100644 src/endstone_example/python_command.py diff --git a/README.md b/README.md index 775018d..0b720ae 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,3 @@ -# Endstone Python Example Plugin +# Discord for Endstone -Welcome to the example Python plugin for Endstone servers. - -## Prerequisites - -- Python 3.9 or higher. -- Endstone installed and set up in your Python environment. - -## Structure Overview - -``` -python-example-plugin/ -├── src/ # Main source directory -│ └── endstone_example/ # Directory for the plugin package -│ ├── __init__.py # Initializer for the package, importing ExamplePlugin class from example_plugin.py -│ ├── example_plugin.py # Implementation of ExamplePlugin class -│ └── python_command.py # Custom command executor for /python -├── .gitignore # Git ignore rules -├── LICENSE # License details -├── README.md # This file -└── pyproject.toml # Plugin configuration file which specifies the entrypoint -``` - -## Getting Started - -1. **Clone this Repository** - - ```bash - git clone https://github.com/EndstoneMC/python-example-plugin.git - ``` - -2. **Navigate to the Cloned Directory** - - ```bash - cd python-example-plugin - ``` - -3. **Install Your Plugin** - - When developing the plugin, you may want to install an editable package to your Python environment, this allows you - to update the codes without having to reinstall the package everytime: - ```bash - pip install -e . - ``` - **NOTE: It is strongly recommended to create a virtual environment for your Endstone server and plugins. When - installing your plugin using `pip install`, please ensure the virtual environment is activated.** - - Ensure your plugin is loaded correctly by checking the server logs or console for the log messages. - -4. **Package and Distribute Your Plugin** - - When everything is good to go, you can package your plugin into a `.whl` (Wheel) file for easier distribution: - - ```bash - pip install pipx - pipx run build --wheel - ``` - - This command will produce a `.whl` file in the `dist` directory. Copy the `.whl` file to the `plugins` directory - of your Endstone server. Start the Endstone server and check the logs to ensure your plugin loads and operates - as expected. - - To publish your plugin to a package index such as PyPI, please refer to: - - [Using TestPyPI](https://packaging.python.org/en/latest/guides/using-testpypi/) - - [Publishing package distribution releases using GitHub Actions CI/CD workflows](https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/) - -## Documentation - -For a deeper dive into the Endstone API and its functionalities, refer to the main -Endstone [documentation](https://endstone.readthedocs.io) (WIP). - -## License - -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. +A Discord plugin for Endstone servers diff --git a/pyproject.toml b/pyproject.toml index d24c711..b11b76b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,19 +3,21 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project] -name = "endstone-example" -version = "0.4.0" -dependencies = [] +name = "endstone-discord" +version = "0.0.1" +dependencies = [ + "discord.py" +] authors = [ - { name = "Endstone Developers", email = "hello@endstone.dev" }, + { name = "Vincent Wu", email = "magicdroidx@gmail.com" }, ] -description = "Python example plugin for Endstone servers" +description = "A Discord plugin for Endstone servers" readme = "README.md" license = { file = "LICENSE" } -keywords = ["endstone", "plugin"] +keywords = ["endstone", "plugin", "discord"] [project.urls] -Homepage = "https://github.com/EndstoneMC/python-example-plugin" +Homepage = "https://github.com/wu-vincent/endstone-discord" [project.entry-points."endstone"] -example = "endstone_example:ExamplePlugin" \ No newline at end of file +discord = "endstone_discord:DiscordPlugin" \ No newline at end of file diff --git a/src/endstone_discord/__init__.py b/src/endstone_discord/__init__.py new file mode 100644 index 0000000..d100922 --- /dev/null +++ b/src/endstone_discord/__init__.py @@ -0,0 +1,3 @@ +from endstone_discord.discord_plugin import DiscordPlugin + +__all__ = ["DiscordPlugin"] diff --git a/src/endstone_discord/discord_plugin.py b/src/endstone_discord/discord_plugin.py new file mode 100644 index 0000000..10bdd96 --- /dev/null +++ b/src/endstone_discord/discord_plugin.py @@ -0,0 +1,5 @@ +from endstone.plugin import Plugin + + +class DiscordPlugin(Plugin): + api_version = "0.4" diff --git a/src/endstone_example/__init__.py b/src/endstone_example/__init__.py deleted file mode 100644 index 7839c19..0000000 --- a/src/endstone_example/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from endstone_example.example_plugin import ExamplePlugin - -__all__ = ["ExamplePlugin"] diff --git a/src/endstone_example/example_listener.py b/src/endstone_example/example_listener.py deleted file mode 100644 index 6d62b09..0000000 --- a/src/endstone_example/example_listener.py +++ /dev/null @@ -1,28 +0,0 @@ -import datetime - -from endstone import ColorFormat -from endstone.event import event_handler, EventPriority, PlayerJoinEvent, PlayerQuitEvent, ServerListPingEvent -from endstone.plugin import Plugin - - -class ExampleListener: - def __init__(self, plugin: Plugin): - self._plugin = plugin - - @event_handler(priority=EventPriority.HIGHEST) - def on_server_list_ping(self, event: ServerListPingEvent): - event.motd = ColorFormat.BOLD + ColorFormat.AQUA + datetime.datetime.now().strftime("%c") - event.level_name = f"Your IP is {ColorFormat.YELLOW}{event.remote_host}:{event.remote_port}{ColorFormat.RESET}" - - @event_handler - def on_player_join(self, event: PlayerJoinEvent): - player = event.player - self._plugin.logger.info( - ColorFormat.YELLOW - + f"{player.name}[/{player.address}] joined the game with UUID {player.unique_id}" - ) - - @event_handler - def on_player_quit(self, event: PlayerQuitEvent): - player = event.player - self._plugin.logger.info(ColorFormat.YELLOW + f"{player.name}[/{player.address}] left the game.") diff --git a/src/endstone_example/example_plugin.py b/src/endstone_example/example_plugin.py deleted file mode 100644 index b0d852f..0000000 --- a/src/endstone_example/example_plugin.py +++ /dev/null @@ -1,115 +0,0 @@ -import datetime - -from endstone.command import Command, CommandSender -from endstone.event import EventPriority, ServerLoadEvent, event_handler -from endstone.plugin import Plugin - -from endstone_example.example_listener import ExampleListener -from endstone_example.python_command import PythonCommandExecutor - - -class ExamplePlugin(Plugin): - name = "PythonExamplePlugin" - version = "0.4.0" - api_version = "0.4" - description = "Python example plugin for Endstone servers" - authors = ["Endstone Developers "] - website = "https://github.com/EndstoneMC/python-example-plugin" - load = "POSTWORLD" - - commands = { - "python": { - "description": "Zen of python", - "usages": ["/python"], - "aliases": ["py"], - "permissions": ["python_example.command.python"], - }, - "test": { - "description": "This is a test command from python", - "usages": [ - "/test", - "/test [value: int]", - "/test [value: float]", - ], - "permissions": ["python_example.command.test"], - }, - "kickme": { - "description": "Ask the server to kick you with a custom message", - "usages": ["/kickme [reason: message]"], - "permissions": ["python_example.command.kickme"], - }, - } - - permissions = { - "python_example.command": { - "description": "Allow users to use all commands provided by this plugin.", - "default": True, - "children": { - "python_example.command.python": True, - "python_example.command.test": True, - "python_example.command.kickme": True, - }, - }, - "python_example.command.python": { - "description": "Allow users to use the /python command.", - "default": "op", - }, - "python_example.command.test": { - "description": "Allow users to use the /test command.", - "default": True, - }, - "python_example.command.kickme": { - "description": "Allow users to use the /kickme command.", - "default": True, - }, - } - - def on_load(self) -> None: - self.logger.info("on_load is called!") - - def on_enable(self) -> None: - self.logger.info("on_enable is called!") - self.get_command("python").executor = PythonCommandExecutor() - - self.register_events(self) # register event listeners defined directly in Plugin class - self._listener = ExampleListener(self) - self.register_events(self._listener) # you can also register event listeners in a separate class - - self.server.scheduler.run_task_timer(self, self.log_time, 0, 20 * 1) # every second - - def on_disable(self) -> None: - self.logger.info("on_disable is called!") - - def on_command(self, sender: CommandSender, command: Command, args: list[str]) -> bool: - # You can also handle commands here instead of setting an executor in on_enable if you prefer - match command.name: - case "test": - if len(args) > 0: - sender.send_message(f"Test with number: {args[0]}!") - else: - sender.send_message("Test!!") - case "kickme": - player = sender.as_player() - if player is None: - sender.send_error_message("You must be a player to execute this command.") - return False - - if len(args) > 0: - player.kick(args[0]) - else: - player.kick("You asked for it!") - - return True - - @event_handler - def on_server_load(self, event: ServerLoadEvent): - self.logger.info(f"{event.event_name} is passed to on_server_load") - - @event_handler(priority=EventPriority.HIGH) - def on_server_load_2(self, event: ServerLoadEvent): - self.logger.info(f"{event.event_name} is passed to on_server_load_2. This will be called after on_server_load.") - - def log_time(self): - now = datetime.datetime.now().strftime("%c") - for player in self.server.online_players: - player.send_popup(now) diff --git a/src/endstone_example/python_command.py b/src/endstone_example/python_command.py deleted file mode 100644 index 102b9a7..0000000 --- a/src/endstone_example/python_command.py +++ /dev/null @@ -1,30 +0,0 @@ -from endstone.command import Command, CommandSender, CommandExecutor - -# Zen of python - https://peps.python.org/pep-0020/ -zen_of_python = """The Zen of Python, by Tim Peters - -Beautiful is better than ugly. -Explicit is better than implicit. -Simple is better than complex. -Complex is better than complicated. -Flat is better than nested. -Sparse is better than dense. -Readability counts. -Special cases aren't special enough to break the rules. -Although practicality beats purity. -Errors should never pass silently. -Unless explicitly silenced. -In the face of ambiguity, refuse the temptation to guess. -There should be one-- and preferably only one --obvious way to do it. -Although that way may not be obvious at first unless you're Dutch. -Now is better than never. -Although never is often better than *right* now. -If the implementation is hard to explain, it's a bad idea. -If the implementation is easy to explain, it may be a good idea. -Namespaces are one honking great idea -- let's do more of those!""" - - -class PythonCommandExecutor(CommandExecutor): - def on_command(self, sender: CommandSender, command: Command, args: list[str]) -> bool: - sender.send_message(zen_of_python) - return True