├── .gitignore ├── LICENSE ├── README.md ├── docs ├── introduction-en.md └── introduction-zh_CN.md ├── mcdreforged.plugin.json └── mirror_server_reforged └── __init__.py /.gitignore: -------------------------------------------------------------------------------- 1 | mirror_server_reforged.mcdr 2 | *.mcdr 3 | temp/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2022 GamerNoTitle 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MirrorServerReforged 2 | 3 | ![MirrorServerReforged](https://socialify.git.ci/EMUnion/MirrorServerReforged/image?description=1&font=Inter&forks=1&issues=1&language=1&owner=1&pattern=Circuit%20Board&stargazers=1&theme=Light) 4 | 5 | 适用于MCDR 2.0+的镜像服插件,主要是有时间摸了,而且自己服务器确实需要这个东西,就写了XD 6 | 7 | 简单说一下这个插件吧~ 8 | 9 | ## 初次运行 10 | 11 | 本插件在初次运行的时候会进行一定的初始化,进行的操作如下(文件夹路径可以在配置文件中进行修改) 12 | - 在config文件夹内创建`MirrorServerReforged.json`配置文件并自动填入初始配置 13 | - 创建`Mirror`文件夹以用于存放镜像服文件 14 | - 在`Mirror`文件夹下创建`./server/world/`/`./world`(取决于你是否使用MCDR,默认为使用) 15 | 16 | 但这些是仅仅不够的,你还需要做以下的操作:(路径可以在配置文件中进行修改) 17 | - 将你的服务器核心以及各种服务器依赖放入`./Mirror/server`内 18 | - 修改你的`./Mirror/`的`config.yml`中的启动命令以及rcon相关信息 19 | - 修改你的`./Mirror/server/server.properties`的内容,特别是要注意端口以及rcon相关内容,避免与主服务器冲突 20 | 21 | 当然,镜像服务器不一定要使用MCDR,你也可以直接配置一个正常的服务器 22 | 23 | ## 配置文件 24 | 25 | 如果需要修改插件配置,只需要修改`config`文件夹下的`MirrorServerReforged.json`即可! 26 | 27 | ```json 28 | { 29 | "world":[ 30 | "world" 31 | ], 32 | "command":"python3 -m mcdreforged", 33 | "rcon":{ 34 | "enable":false, 35 | "host":"localhost", 36 | "port":25565, 37 | "password":"password" 38 | }, 39 | "source": "./server", 40 | "target": "./Mirror/server" 41 | } 42 | ``` 43 | 44 | 配置文件的内容说明如下: 45 | - `world`世界列表,对于`Vanilla`类型的服务器可以不用动,但是对于`Bukkit`/`Waterfall`/`Catserver`之类的客户端,它的世界文件夹有多个,则需要逐个填入,例如`world_nether`和`world_the_end`,加上原有的`world`,就应该改成`['world','world_nether','world_the_end']` 46 | - `command` 启动命令,对于默认的启动命令,则是在认为您使用了MCDReforged的情况下填写的,但如果是使用上面说的纯`Vanilla`或者类`Bukkit`服务端,则需要进行修改,例如改成`java -Xmx16G -Xms1G -jar server.jar nogui` 47 | - `rcon`是rcon功能的详细配置,该功能只会被用于远程关闭服务器 48 | - `enable`是rcon功能的总开关,表示您是否要启用本插件的rcon来进行远程服务器的关闭,参考值为`true`和`false`,当设定为`false`时,`!!msr stop`命令将不可用 49 | - `host`是rcon功能的宿服务器地址,根据自身需求填写即可 50 | - `port`是rcon功能的宿服务器端口,根据自身需求填写即可 51 | - `password`是rcon功能的宿服务器的密码,根据自身需求填写即可 52 | - `source`是你的主服务器的存档位置 53 | - `target`是你镜像服的存档位置 54 | 55 | ## 命令列表 56 | 57 | ``` 58 | !!msr help - 显示帮助信息 59 | !!msr sync - 同步服务器地图至镜像 60 | !!msr reload - 重载配置文件 61 | !!msr start - 启动镜像服务器 62 | !!msr stop - 关闭镜像服务器(需要开启Rcon) 63 | !!msr init - 初始化镜像服务器(仅MCDR类服务器可用) 64 | !!msr status - 查看镜像服务器状态 65 | ``` 66 | -------------------------------------------------------------------------------- /docs/introduction-en.md: -------------------------------------------------------------------------------- 1 | # MirrorServerReforged 2 | 3 | ![MirrorServerReforged](https://socialify.git.ci/EMUnion/MirrorServerReforged/image?description=1&font=Inter&forks=1&issues=1&language=1&owner=1&pattern=Circuit%20Board&stargazers=1&theme=Light) 4 | 5 | A reforged version of [MCDR-Mirror-Server](https://github.com/GamerNoTitle/MCDR-Mirror-Server), which is a plugin for MCDR-Reforged 2.0+. 6 | 7 | I'll simply introduce it. 8 | 9 | ## Getting Started 10 | 11 | This plugin will initalize when the first run, it will do the following opeartions (the path can be changed in the config) 12 | - Create `MirrorServerReforged.json` in your `config` folder and fill the default config in it 13 | - Create`Mirror` folder to store your files of mirror server 14 | - Create `./server/world/`/`./world` in `Mirror` folder (This depends on whether you use MCDR or not, use as default) 15 | 16 | But these operations are not enough, what you need to do are as following (the path can be changed in the config) 17 | - Put your server core and dependencies into `./Mirror/server` folder 18 | - Edit start command and rcon information in file `config.yml` in the folder`./Mirror/` 19 | - Edit the content in `./Mirror/server/server.properties`. What you need to pay attention to is the ports of the mirror server and rcon related information in order to avoid encountering to the main server 20 | 21 | It's not essential for a mirror server to be a MCDR server, you can use the vanilla or something else. 22 | 23 | ## Config 24 | 25 | If you want to change the config of this plugin, you can change the content of `MirrorServerReforged.json` in `config` folder 26 | 27 | ```json 28 | { 29 | "world":[ 30 | "world" 31 | ], 32 | "command":"python3 -m mcdreforged", 33 | "rcon":{ 34 | "enable":false, 35 | "host":"localhost", 36 | "port":25565, 37 | "password":"password" 38 | }, 39 | "source": "./server", 40 | "target': './Mirror/server" 41 | } 42 | ``` 43 | 44 | Now, I'll introduce the content of the config file: 45 | - `world` is a list include all your world's folders. For `Vanilla` type server, this can leave it as default. But for `Bukkit`/`Waterfall`/`Catserver` or other server cores like them that have more than one world folder, you need to input them in the list follow after `world`. E.G.: The `Bukkit` server has folders `world`, `world_nether`, `world_the_end`, then it should be filled with `['world','world_nether','world_the_end']`. 46 | - `command` Start command. Here we use this command as you use MCDR in your mirror server as default. For `Vanilla` or `Bukkit-Like` server, you need to change it to the suitable one. E.G.: `java -Xmx16G -Xms1G -jar server.jar nogui` 47 | - `rcon` will contain all the rcon-related config and this feature will only be used to turn off the mirror server remotely. 48 | - `enable` is the switch of rcon feature, it should be `true` or `false`. Rcon will not be able to use if this is set to `false`, especially the command `!!msr stop` 49 | - `host` is the address of your mirror server, change it as your need. 50 | - `port` is the port of your mirror server, change it as your need. 51 | - `password` is the password of the rcon feature on your mirror server, change it as your need. 52 | - `source` is the save folder of you main server save. 53 | - `target` is the save folder of your mirror server save. 54 | 55 | ## Command List 56 | 57 | ``` 58 | !!msr help - Display help message 59 | !!msr sync - Sync the world to the mirror server 60 | !!msr reload - Reload config 61 | !!msr start - Start mirror server 62 | !!msr stop - Stop mirror server (Rcon feature enable is needed) 63 | !!msr init - Initalize mirror server (Use it only when you use MCDR in your mirror server) 64 | !!msr status - Checkout the status of your mirror server 65 | ``` 66 | -------------------------------------------------------------------------------- /docs/introduction-zh_CN.md: -------------------------------------------------------------------------------- 1 | # MirrorServerReforged 2 | 3 | ![MirrorServerReforged](https://socialify.git.ci/EMUnion/MirrorServerReforged/image?description=1&font=Inter&forks=1&issues=1&language=1&owner=1&pattern=Circuit%20Board&stargazers=1&theme=Light) 4 | 5 | 适用于MCDR 2.0+的镜像服插件,主要是有时间摸了,而且自己服务器确实需要这个东西,就写了XD 6 | 7 | 简单说一下这个插件吧~ 8 | 9 | ## 初次运行 10 | 11 | 本插件在初次运行的时候会进行一定的初始化,进行的操作如下(文件夹路径可以在配置文件中进行修改) 12 | - 在config文件夹内创建`MirrorServerReforged.json`配置文件并自动填入初始配置 13 | - 创建`Mirror`文件夹以用于存放镜像服文件 14 | - 在`Mirror`文件夹下创建`./server/world/`/`./world`(取决于你是否使用MCDR,默认为使用) 15 | 16 | 但这些是仅仅不够的,你还需要做以下的操作:(路径可以在配置文件中进行修改) 17 | - 将你的服务器核心以及各种服务器依赖放入`./Mirror/server`内 18 | - 修改你的`./Mirror/`的`config.yml`中的启动命令以及rcon相关信息 19 | - 修改你的`./Mirror/server/server.properties`的内容,特别是要注意端口以及rcon相关内容,避免与主服务器冲突 20 | 21 | 当然,镜像服务器不一定要使用MCDR,你也可以直接配置一个正常的服务器 22 | 23 | ## 配置文件 24 | 25 | 如果需要修改插件配置,只需要修改`config`文件夹下的`MirrorServerReforged.json`即可! 26 | 27 | ```json 28 | { 29 | "world":[ 30 | "world" 31 | ], 32 | "command":"python3 -m mcdreforged", 33 | "rcon":{ 34 | "enable":false, 35 | "host":"localhost", 36 | "port":25565, 37 | "password":"password" 38 | }, 39 | "source": "./server", 40 | "target': './Mirror/server" 41 | } 42 | ``` 43 | 44 | 配置文件的内容说明如下: 45 | - `world`世界列表,对于`Vanilla`类型的服务器可以不用动,但是对于`Bukkit`/`Waterfall`/`Catserver`之类的客户端,它的世界文件夹有多个,则需要逐个填入,例如`world_nether`和`world_the_end`,加上原有的`world`,就应该改成`['world','world_nether','world_the_end']` 46 | - `command` 启动命令,对于默认的启动命令,则是在认为您使用了MCDReforged的情况下填写的,但如果是使用上面说的纯`Vanilla`或者类`Bukkit`服务端,则需要进行修改,例如改成`java -Xmx16G -Xms1G -jar server.jar nogui` 47 | - `rcon`是rcon功能的详细配置,该功能只会被用于远程关闭服务器 48 | - `enable`是rcon功能的总开关,表示您是否要启用本插件的rcon来进行远程服务器的关闭,参考值为`true`和`false`,当设定为`false`时,`!!msr stop`命令将不可用 49 | - `host`是rcon功能的宿服务器地址,根据自身需求填写即可 50 | - `port`是rcon功能的宿服务器端口,根据自身需求填写即可 51 | - `password`是rcon功能的宿服务器的密码,根据自身需求填写即可 52 | - `source`是你的主服务器的存档位置 53 | - `target`是你镜像服的存档位置 54 | 55 | ## 命令列表 56 | 57 | ``` 58 | !!msr help - 显示帮助信息 59 | !!msr sync - 同步服务器地图至镜像 60 | !!msr reload - 重载配置文件 61 | !!msr start - 启动镜像服务器 62 | !!msr stop - 关闭镜像服务器(需要开启Rcon) 63 | !!msr init - 初始化镜像服务器(仅MCDR类服务器可用) 64 | !!msr status - 查看镜像服务器状态 65 | ``` 66 | -------------------------------------------------------------------------------- /mcdreforged.plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "mirror_server_reforged", 3 | "version": "1.0.8-alpha", 4 | "name": "MirrorServerReforged", 5 | "description": { 6 | "en_us": "A reforged version of [MCDR-Mirror-Server](https://github.com/GamerNoTitle/MCDR-Mirror-Server), which is a plugin for MCDR-Reforged 2.6.0+.", 7 | "zh_cn": "[MCDR-Mirror-Server](https://github.com/GamerNoTitle/MCDR-Mirror-Server)的重置版,适用于MCDR 2.6.0+的镜像服插件" 8 | }, 9 | "dependencies": { 10 | "mcdreforged": ">=2.6.0" 11 | }, 12 | "resources": ["docs", "README.md"], 13 | "author": "GamerNoTitle", 14 | "link": "https://github.com/EMUnion/MirrorServerReforged" 15 | } 16 | -------------------------------------------------------------------------------- /mirror_server_reforged/__init__.py: -------------------------------------------------------------------------------- 1 | import shutil 2 | import os 3 | import json 4 | import sys 5 | import time 6 | import datetime 7 | import subprocess 8 | # MCDR Command & Class 9 | from mcdreforged.api.decorator import new_thread 10 | from mcdreforged.api.command import Literal, Text, SimpleCommandBuilder 11 | from mcdreforged.api.rcon import RconConnection 12 | from mcdreforged.mcdr_server import ServerInterface 13 | # Initalize Start 14 | platform = sys.platform 15 | Interface = None 16 | 17 | if sys.platform == 'win32': 18 | MCDR_Command = 'python -m mcdreforged' 19 | else: 20 | MCDR_Command = 'python3 -m mcdreforged' 21 | 22 | PLUGIN_METADATA = { 23 | 'id': 'mirror_server_reforged', 24 | 'version': '1.0.8-alpha', 25 | 'name': 'MirrorServerReforged', 26 | 'description': 'A reforged version of [MCDR-Mirror-Server](https://github.com/GamerNoTitle/MCDR-Mirror-Server), which is a plugin for MCDR-Reforged 2.6.0+.', 27 | 'author': 'GamerNoTitle', 28 | 'link': 'https://github.com/EMUnion/MirrorServerReforged', 29 | 'dependencies': { 30 | 'mcdreforged': '>=2.6.0' 31 | } 32 | } 33 | 34 | config = { 35 | 'world': ['world'], 36 | 'command': MCDR_Command, 37 | 'rcon': { 38 | 'enable': False, 39 | 'host': 'localhost', 40 | 'port': 25575, 41 | 'password': 'password' 42 | }, 43 | 'source': './server', 44 | 'target': './Mirror/server' 45 | } 46 | 47 | help_msg = '''{:=^50} 48 | §b!!msr help §r- §6显示帮助信息 49 | §b!!msr sync §r- §6同步服务器地图至镜像 50 | §b!!msr reload §r- §6重载配置文件 51 | §b!!msr start §r- §6启动镜像服务器 52 | §b!!msr stop §r- §6关闭镜像服务器(需要开启Rcon) 53 | §b!!msr init §r- §6初始化镜像服务器(仅MCDR类服务器可用) 54 | {:=^50}'''.format(' §b[MirrorServerReforged] 帮助信息 §r', ' §b[MirrorServerReforged] Version: {} §r'.format(PLUGIN_METADATA['version'])) 55 | # §b!!msr status §r- §6查看镜像服务器状态 56 | 57 | 58 | # Started = False # Mirror server status 59 | MCDR = False # MCDR mode controller 60 | path = os.getcwd() 61 | syncFlag = False 62 | # Initalize End 63 | 64 | 65 | def InitalizeOnFirstRun(): 66 | if os.path.exists('./Mirror/MCDReforged.py') or 'mcdreforged' in config['command']: 67 | global MCDR 68 | MCDR = True # Turn on MCDR mode 69 | if not os.path.exists('./Mirror'): 70 | print('[MirrorServerReforged] 看起来你是第一次运行本插件?我们将会为您进行首次运行的初始化') 71 | print('[MirrorServerReforged] 正在创建镜像文件夹……') 72 | if MCDR: # MCDR mode on, create Mirror folder and a server folder in Mirror folder 73 | print('[MirrorServerReforged] 检测到MCDR,我们将会按照MCDR的目录结构创建文件夹') 74 | try: 75 | os.makedirs('./Mirror') 76 | except: 77 | print('[MirrorServerReforged] Mirror文件夹已存在!') 78 | os.makedirs('./Mirror/server') 79 | os.chdir('Mirror') 80 | # Create MCDR dictionary structure 81 | os.system('python3 -m mcdreforged init') 82 | os.makedirs('./server/world') 83 | os.chdir(path) 84 | else: # MCDR mode off, turn into legacy mode. Like Vanilla, Bukkit, Waterfalls and so on. 85 | print('[MirrorServerReforged] 未检测到MCDR,我们将会按照普通服务器的目录结构创建文件夹') 86 | try: 87 | os.makedirs('./Mirror') 88 | except: 89 | print('[MirrorServerReforged] Mirror文件夹已存在!') 90 | for world in config['world']: 91 | os.makedirs('./Mirror/{}'.format(world)) 92 | print('[MirrorServerReforged] 初始化完成!') 93 | 94 | 95 | def CreateConfig(): 96 | print('[MirrorServerReforged] 正在创建配置文件……') 97 | global config 98 | with open('./config/MirrorServerReforged.json', 'w', encoding="utf-8") as f: 99 | f.write(json.dumps(config, indent=2, separators=( 100 | ',', ':'), ensure_ascii=False)) 101 | f.close() 102 | 103 | 104 | def RconInit(host, port, password): 105 | Rcon = RconConnection(host, port, password) 106 | return Rcon 107 | 108 | 109 | def LoadConfig(): 110 | print('[MirrorServerReforged] 正在加载配置文件……') 111 | global config 112 | with open('./config/MirrorServerReforged.json', 'r', encoding="utf-8") as f: 113 | config = json.load(f) 114 | if 'source' not in config: 115 | config['source'] = './server' 116 | if 'target' not in config: 117 | config['target'] = './Mirror/server' 118 | CreateConfig() 119 | 120 | 121 | @new_thread('MSR-Sync') 122 | def ServerSync(InterFace): 123 | global syncFlag 124 | syncFlag = True 125 | start_time = datetime.datetime.now() 126 | ignore = shutil.ignore_patterns('session.lock') 127 | for world in config['world']: 128 | if os.path.exists(f'{config["target"]}/{world}'): 129 | shutil.rmtree(f'{config["target"]}/{world}/') 130 | if sys.platform == 'win32': 131 | shutil.copytree(f'{config["source"]}/{world}', f'{config["target"]}/{world}', ignore=ignore) 132 | # os.mkdir(f'{config["target"]}/{world}') 133 | # with open('./exclude.txt', 'wt') as f: 134 | # f.write('session.lock') 135 | # os.system(f'xcopy "{config["source"]}/{world}" "{config["target"]}/{world}" /e /h /k /y /exclude:{config["source"]}/*/session.lock /exclude:{config["source"]}/*/level.*') 136 | else: 137 | os.system(f'cp -r {config["source"]}/{world} {config["target"]}/{world}') 138 | end_time = datetime.datetime.now() 139 | InterFace.execute( 140 | f'say §b[MirrorServerReforged] §6同步完成!用时{end_time-start_time}') 141 | syncFlag = False 142 | 143 | 144 | def Sync(): 145 | InterFace = GetInterFace() 146 | if syncFlag: 147 | InterFace.execute( 148 | 'say §b[MirrorServerReforged] §d服务器正在进行同步,请不要重复提交同步任务!') 149 | else: 150 | InterFace.execute('say §b[MirrorServerReforged] §6正在同步服务器地图……') 151 | InterFace.execute('save-off') 152 | InterFace.execute('save-all') 153 | ServerSync(InterFace) 154 | InterFace.execute('save-on') 155 | 156 | 157 | @new_thread('MSR-Start') 158 | def CommandExecute(InterFace): 159 | try: 160 | global MirrorProcess 161 | if platform == 'win32': 162 | MirrorProcess = subprocess.Popen(config['command'], creationflags=subprocess.CREATE_NEW_CONSOLE) 163 | else: 164 | MirrorProcess = subprocess.Popen(config['command'], shell=True) 165 | except Exception as e: 166 | InterFace.execute(f'say §b[MirrorServerReforged] §6启动失败!原因为:{e}') 167 | os.chdir(path) 168 | 169 | @new_thread('MSR-Main') 170 | def ServerStart(InterFace): 171 | # global Started 172 | try: 173 | os.chdir('Mirror') 174 | CommandExecute(InterFace) 175 | time.sleep(5) 176 | os.chdir(path) 177 | except Exception as e: 178 | InterFace.execute( 179 | 'say §b[MirrorServerReforged] §6启动失败!原因为:{}'.format(e)) 180 | 181 | 182 | def Start(server): 183 | # global Started 184 | InterFace = GetInterFace() 185 | # if Started: 186 | # server.reply('§b[MirrorServerReforged] §6镜像服正在运行……') 187 | # else: 188 | if syncFlag: 189 | InterFace.execute('say §b[MirrorServerReforged] §d§l镜像服正在进行同步,请在同步完成后再启动镜像服!') 190 | else: 191 | InterFace.execute('say §b[MirrorServerReforged] §6正在启动镜像服,这可能需要一定的时间……') 192 | InterFace.execute( 193 | 'say §b[MirrorServerReforged] §6启动完成后,请自行利用BungeeCord的转服或者直连进行转服!') 194 | # Started = True 195 | ServerStart(InterFace) 196 | 197 | 198 | def GetInterFace(*args): 199 | global Interface 200 | InterFace = ServerInterface.get_instance().as_plugin_server_interface() 201 | return InterFace 202 | 203 | # def Status(server): 204 | # if Started: 205 | # server.reply('§b[MirrorServerReforged] §6镜像服正在运行……') 206 | # else: 207 | # server.reply('§b[MirrorServerReforged] §6镜像服未运行……') 208 | 209 | 210 | def Stop(server): 211 | # global Started 212 | # if Started: 213 | if config['rcon']['enable']: 214 | conn = RconInit(config['rcon']['host'], config['rcon'] 215 | ['port'], config['rcon']['password']) 216 | try: 217 | connected = conn.connect() 218 | if connected: 219 | conn.send_command('stop', max_retry_time=3) 220 | conn.disconnect() 221 | except Exception as e: 222 | server.reply('§b[MirrorServerReforged] §6无法停止镜像服!原因为:{}'.format(e)) 223 | else: 224 | server.reply('§b[MirrorServerReforged] §6无法通过Rcon停止镜像服,因为Rcon未开启!') 225 | # else: 226 | # server.reply('§b[MirrorServerReforged] §6镜像服未运行!') 227 | 228 | 229 | def Reload(server): 230 | server.reply('§b[MirrorServerReforged] §6正在重载配置文件……') 231 | ConfigToDo() 232 | server.reply('§b[MirrorServerReforged] §6重载完成!') 233 | 234 | 235 | def DisplayHelp(server): 236 | for line in help_msg.splitlines(): 237 | server.reply(line) 238 | 239 | 240 | @new_thread('MSR-Init') 241 | def MCDRInitalize(server): 242 | if MCDR: 243 | try: 244 | os.chdir('Mirror') 245 | system = sys.platform 246 | if system == 'win32': 247 | # Windows NT Platform 248 | os.system('python -m mcdreforged init') 249 | else: 250 | # Linux/Unix Platform 251 | os.system('python3 -m mcdreforged init') 252 | server.reply('§b[MirrorServerReforged] §6初始化已完成!') 253 | except Exception as e: 254 | server.reply('§b[MirrorServerReforged] §6初始化失败!原因为:{}'.format(e)) 255 | os.chdir(path) 256 | else: 257 | server.reply('§b[MirrorServerReforged] §6非MCDR类服务器,无需初始化!') 258 | 259 | 260 | def Initalize(server): 261 | server.reply('§b[MirrorServerReforged] §6已启动初始化进程!') 262 | MCDRInitalize(server) 263 | 264 | 265 | def ConfigToDo(): 266 | if os.path.exists('./config/MirrorServerReforged.json'): 267 | LoadConfig() 268 | else: 269 | CreateConfig() 270 | 271 | 272 | def on_load(server, prev): 273 | ConfigToDo() # Load Config 274 | InitalizeOnFirstRun() # Initalize if this is the first run 275 | # builder = SimpleCommandBuilder() 276 | server.register_help_message('!!msr', 'MirrorServerReforged 帮助') 277 | server.register_command(Literal('!!msr').runs(DisplayHelp) 278 | .then(Literal('help').runs(DisplayHelp)) 279 | .then(Literal('sync').runs(Sync)) 280 | .then(Literal('reload').runs(Reload)) 281 | .then(Literal('start').runs(Start)) 282 | .then(Literal('stop').runs(Stop)) 283 | .then(Literal('init').runs(Initalize)) 284 | # .then(Literal('status').runs(Status)) 285 | ) 286 | # register stop confirm command (TOO LAZY TO REBUILD THE PREVIOUS COMMAND) 287 | # builder.command('!!msr help', DisplayHelp) 288 | # builder.command('!!msr sync', Sync) 289 | # builder.command('!!msr reload', Reload) 290 | # builder.command('!!msr start', Start) 291 | # builder.command('!!msr stop', Stop) 292 | # builder.command('!!msr init', Initalize) 293 | # builder.register(server) 294 | --------------------------------------------------------------------------------