{"id":15009499,"url":"https://github.com/nosix/pyminehub","last_synced_at":"2025-04-09T17:24:34.246Z","repository":{"id":134901206,"uuid":"111290519","full_name":"nosix/PyMineHub","owner":"nosix","description":"Multiplay server of Minecraft Pocket Edition (This project is finished. There are no plans to update in the future. )","archived":false,"fork":false,"pushed_at":"2023-12-05T03:50:27.000Z","size":2785,"stargazers_count":11,"open_issues_count":3,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-23T19:38:23.096Z","etag":null,"topics":["minecraft-server","python-3-5","raspberry-pi"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nosix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-19T11:55:09.000Z","updated_at":"2023-12-23T13:54:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"c45ddedf-c738-4a9f-9ee8-06431058aef7","html_url":"https://github.com/nosix/PyMineHub","commit_stats":{"total_commits":551,"total_committers":2,"mean_commits":275.5,"dds":"0.019963702359346636","last_synced_commit":"124162191268dcc1599d6e6e55cf6e9dc78f21fd"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nosix%2FPyMineHub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nosix%2FPyMineHub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nosix%2FPyMineHub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nosix%2FPyMineHub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nosix","download_url":"https://codeload.github.com/nosix/PyMineHub/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248075617,"owners_count":21043623,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["minecraft-server","python-3-5","raspberry-pi"],"created_at":"2024-09-24T19:25:44.438Z","updated_at":"2025-04-09T17:24:34.228Z","avatar_url":"https://github.com/nosix.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u0026#x26a0; **This project is finished. There are no plans to update in the future. If you need to update, please use fork.** \u0026#x26a0;\n\n# PyMineHub (PMH)\n\nMultiplay server of Minecraft Pocket Edition\n\nThe goal of this project is to make the server small and to work with others.\nExtensibility than full spec implementation.\nThis project will assume that MineCraft is used as an environment of creation, not as a game.\n\n## Target version\n\n- Python 3.5.3\n  - 2017-09-07-raspbian-stretch-lite.img\n- and later\n\n## Testing environment\n\n- Python 3.6.1\n  - macOS High Sierra 10.13\n- Python 3.5.3\n  - Raspbian stretch lite 2017-09-07\n\n## Demo\n\n[![demo1](http://img.youtube.com/vi/ezoJ7GiG7rQ/0.jpg)](http://www.youtube.com/watch?v=ezoJ7GiG7rQ?loop=1\u0026cc_load_policy=1)\n\n[![demo2](http://img.youtube.com/vi/nPKKtxPtl98/0.jpg)](http://www.youtube.com/watch?v=nPKKtxPtl98?loop=1)\n\n## Trial\n\nFirst, get the source code and start the server.\n\n```\n$ git clone https://github.com/nosix/PyMineHub.git\n$ cd PyMineHub\nPyMineHub $ bin/run.sh\nIn your environment, Python 3.6.1 is used.\nINFO:pyminehub.config:RAKNET_SERVER_PORT=19132\nINFO:pyminehub.config:TCP_SERVER_PORT=19142\nINFO:pyminehub.config:WORLD_NAME=PyMineHub\nINFO:pyminehub.config:GAME_MODE=SURVIVAL\nINFO:pyminehub.config:SPAWN_MOB=True\nINFO:pyminehub.config:INIT_SPACE=(32, 32)\nINFO:pyminehub.config:PLAYER_SPAWN_POSITION=(256, 56, 256)\nINFO:pyminehub.mcpe.plugin.loader:Plugin is loaded from directory \"plugin\".\nINFO:pyminehub.mcpe.plugin.loader:AboutCommandProcessor was registered into CommandRegistry.\nINFO:pyminehub.mcpe.plugin.loader:LevelDBChunkGeneratorPlugin overrode ChunkGeneratorPlugin.\nINFO:pyminehub.mcpe.plugin.loader:ActionCommandProcessor was registered into CommandRegistry.\nINFO:pyminehub.mcpe.plugin.loader:GameEventCommandProcessor was registered into CommandRegistry.\n```\n\nSign-in from Friends tab on MineCraft.\nPyMineHub support MineCraft version 1.2.7 (maybe, later versions as well) and protocol version 160.\nWe have confirmed working at version 1.2.10.\n\nWhen you start the game, a world of only water is generated.\nAnd, birds move randomly.\nIf you want to change the generated world and mob movements, use the plugin.\nBy default, the source code under the `plugin` directory in the current directory is loaded.\nIf you want to change the plugin directory, specify the directory in the `MPH_PLUGIN_ROOT` environment variable.\nTo disable the plugin, specify the `MPH_PLUGIN_ROOT` environment variable to be `\"\"`.\nRun `run.sh` with the `-d` option to disable the plugin.\n\n```\nPyMineHub $ rm PyMineHub-p0.db \nPyMineHub $ bin/run.sh -d\nIn your environment, Python 3.6.1 is used.\nINFO:pyminehub.config:RAKNET_SERVER_PORT=19132\nINFO:pyminehub.config:TCP_SERVER_PORT=19142\nINFO:pyminehub.config:WORLD_NAME=PyMineHub\nINFO:pyminehub.config:GAME_MODE=SURVIVAL\nINFO:pyminehub.config:SPAWN_MOB=True\nINFO:pyminehub.config:INIT_SPACE=(32, 32)\nINFO:pyminehub.config:PLAYER_SPAWN_POSITION=(256, 56, 256)\nINFO:pyminehub.mcpe.plugin.loader:PMH_PLUGIN_ROOT=\nINFO:pyminehub.mcpe.plugin.loader:Plugin is disabled.\n```\n\n`PyMineHub-p0.db` is a data file.\nCurrently SQLite DB is used, but we might change it (the timing is undecided).\nIf `INIT_SPACE` is specified,\nit creates chunks (parts of terrain data) in the area specified at startup\nand duplicates chunks in this area to other area.\nIf `INIT_SPACE` is `None`, chunks are generated when they are needed.\nThis is a feature to lower the CPU load during play.\n\nAgain, sign-in from Friends tab on MineCraft.\nWhen you start the game, a world of only grass is generated. And, birds move randomly. \nIn this example, the plugin directories are not loaded and the default plugins are used.\nThe default plugins are in `src/pyminehub/mcpe/plugin/default`.\nThen, the interface of the plugins are defined in `src/pyminehub/mcpe/plugin`.\n\n- `ChunkGeneratorPlugin`\n  - override\n- `MobProcessorPlugin`\n  - override\n- `PlayerConfigPlugin`\n  - override\n- `WorldExtensionPlugin`\n  - append\n- `ExtraCommandPlugin`\n  - append\n\nWhen running `run.sh` without the `-d` option (first example),\n`LevelDBChunkGeneratorPlugin` in `plugin` directory override the default plugin.\nIn the case of overloading, the last loaded plugin is enabled.\nOn the other hand, more than one `ExtraCommandPlugin` will be added, all loaded plugins are enabled.\n\n## Plugin\n\nThe plugin loader imports the module directly under the plugin directory,\nand it reads the class described in those `__all__`.\nClasses need to have plugin's interface in superclass.\nDeleting the description of `__all__` will disable the plugin.\n\n```\nplugin (or directory specified by MPH_PLUGIN_ROOT)\n  xxx_plugin\n    __init__.py\n      __all__ = [...]\n  yyy_plugin\n    __init__.py\n      __all__ = [...]\n```\n\n### ChunkGeneratorPlugin\n\nThis plugin is a plugin for generating terrain data.\n\n### MobProcessorPlugin\n\nThis plugin is a plugin for controlling the appearance, movement, and extinction of mobs.\nThe contents that can be done if there is a demand may increase.\n\n### PlayerConfigPlugin\n\nThis plugin is a plugin for setting for each player.\nAlthough we have set it for extension, we recommend that you do not want to use the current situation.\nThe contents that can be done if there is demand may increase.\n\n### WorldExtensionPlugin\n\nThis plugin customizes the update of the world.\nYou will be able to do the following.\n\n- Change or cancel the received update instruction (`filter_action`)\n- Change or cancel update notification to be sent (`filter_event`)\n- Periodically generate update instructions (`update`)\n\nAll update instructions received from the client and all update notifications sent from the world server,\nit passes through `filter` of all loaded `WorldExtensionPlugin`.\n\n```\nClient -\u003e (action a) -\u003e PluginA.filter_action -\u003e (action a') -\u003e PluginB.filter_action -\u003e (action a') -\u003e World Server\nClient \u003c- (event e') \u003c- PluginA.filter_event \u003c- (event e') \u003c- PluginB.filter_event \u003c- (event e) \u003c- World Server\n\naction a : original update instruction\naction a' : modified update instruction\nevent e : original update notification\nevent e' : modified update notification\n```\n\nIt can cancel, when `filter` return `None`.\n\n```\nClient -\u003e (action a) -\u003e PluginA.filter_action -\u003e (None) -\u003e X\nX \u003c- (None) \u003c- PluginB.filter_event \u003c- (event e) \u003c- World Server\n\naction a : original update instruction\nevent e : original update notification\nX : processing exit\n```\n\n`update` can generate update instructions.\n`update` is executed at the interval set by` WORLD_TICK_TIME`.\n\n### ExtraCommandPlugin\n\nThis plugin enables the use of the command.\nCommands allow you to operate the server.\nThe plugin return a command processor.\nWhen the client executes the command, the method of the command processor is executed.\n\nFor example, `ActionCommandProcessor` in `plugin/action/main.py` is below.\n\n```python\nfrom binascii import unhexlify\nfrom pickle import loads\nfrom pyminehub.mcpe.command.annotation import String\nfrom pyminehub.mcpe.command.api import CommandContext, command\n\nclass ActionCommandProcessor:\n\n    @command\n    def perform(self, context: CommandContext, args: str) -\u003e None:\n        \"\"\"Perform action in the world.\"\"\"\n        self._perform(context, String(args))\n\n    @perform.overload\n    def _perform(self, context: CommandContext, data: String) -\u003e None:\n        action = loads(unhexlify(data))\n        context.perform_action(action)\n```\n\n`ActionCommandProcessor` provide `/perform data` command.\nThe command name `perform` is named from method name `perform`.\nBy applying the `command` decorator to the method, the method name becomes the command name.\nThe method parameters must be `CommandContext` and `str`.\n\nUse the `overload` decorator to provide the method signature to the client.\nSignatures are used to indicate usage of the command.\nThe parameters of the method with `overload` decorator must be `CommandContext` and\nthe types defined in `pyminehub.mcpe.command.annotation`.\nWhen calling the method, wrapping in the types in `pyminehub.mcpe.command.annotation` will enable overloading.\nFor that reason, The method names may be the same.\n\n## Client\n\nNot only servers, we also have a simple client.\n\nFor example, `ActionCommandClient` in `plugin/action/client.py` is below.\n\n```python\nfrom binascii import hexlify\nfrom pickle import dumps\nfrom typing import Union\nfrom pyminehub.mcpe.action import Action, ActionType, action_factory\nfrom pyminehub.mcpe.network import MCPEClient\nfrom pyminehub.mcpe.geometry import Vector3\nfrom pyminehub.mcpe.const import MoveMode\nfrom pyminehub.mcpe.main.client import connect\n\nclass ActionCommandMixin:\n\n    @property\n    def client(self) -\u003e MCPEClient:\n        raise NotImplementedError()\n\n    def perform_action(self, action_or_type: Union[Action, ActionType], *args, **kwargs) -\u003e None:\n        action = action_factory.create(action_or_type, *args, **kwargs) \\\n            if isinstance(action_or_type, ActionType) else action_or_type\n        data = hexlify(dumps(action)).decode()\n        self.client.execute_command('/perform {}'.format(data))\n\nclass ActionCommandClient(MCPEClient, ActionCommandMixin):\n\n    @property\n    def client(self) -\u003e MCPEClient:\n        return self\n\ndef run_client():\n    with connect('127.0.0.1', player_name='Taro', client_factory=ActionCommandClient) as client:\n        client.perform_action(\n            ActionType.MOVE_PLAYER, 1, Vector3(256.0, 64.0, 256.0), 0.0, 0.0, 0.0, MoveMode.NORMAL, True, 0, True)\n        client.wait_response(timeout=10)\n        print(client.get_entity())\n```\n\nIt connects to the server by method `connect`.\nTo extend the client, specify the parameter `client_factory`.\nFor the parameter `client_factory`, specify a function that creates an instance of a class that extends `MCPEClient`.\nWhen the connection to the server is successful,\nthe generated instance is bound to the variable `client` specified by `as`.\n\nThe method `wait_response` waits for something packet.\nIt does not wait for the response of the packet sent immediately before.\nIf some packet is received, proceed to the next.\n\nPlease see `test/multiplay.py`, too.\n\n## Server Config\n\nIf you want to change the setting, edit `src/pyminehub/mcpe/main/server.py`.\nFor example, the part of `src/pyminehub/mcpe/main/server.py` is below.\n\n```python\nif __name__ == '__main__':\n    from pyminehub.config import set_config\n    set_config(game_mode='CREATIVE', spawn_mob=False)\n    set_config(\n        world_name='Small',\n        init_space=(1, 1),\n        player_spawn_position=(0, 56, 0)\n    )\n    # ... snip ...\n```\n\nCalls to `set_config` can be combined in one operation or divided.\nThe parameter names is defined in `pyminehub.config`.\n\n### Reference\n\n- This project is implemented by referring to [PocketMine-MP](https://github.com/pmmp/PocketMine-MP) source code.\n- [RakNet](http://www.raknet.net/raknet/manual/systemoverview.html)\n- [Pocket Edition Protocol Documentation](http://wiki.vg/Pocket_Edition_Protocol_Documentation)\n- [Java Edition data values](https://minecraft.gamepedia.com/Java_Edition_data_values)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnosix%2Fpyminehub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnosix%2Fpyminehub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnosix%2Fpyminehub/lists"}