mcserver-cli 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. mcserver/__init__.py +1 -0
  2. mcserver/__main__.py +3 -0
  3. mcserver/app.py +24 -0
  4. mcserver/caching.py +0 -0
  5. mcserver/cli.py +326 -0
  6. mcserver/commands/__init__.py +39 -0
  7. mcserver/commands/add_projects.py +7 -0
  8. mcserver/commands/import_setup.py +6 -0
  9. mcserver/commands/initialize_server.py +119 -0
  10. mcserver/commands/list_projects.py +6 -0
  11. mcserver/commands/op_grant.py +7 -0
  12. mcserver/commands/op_list.py +32 -0
  13. mcserver/commands/op_revoke.py +7 -0
  14. mcserver/commands/print_help.py +7 -0
  15. mcserver/commands/remove_projects.py +6 -0
  16. mcserver/commands/search_projects.py +7 -0
  17. mcserver/commands/server_status.py +6 -0
  18. mcserver/commands/show_projects.py +26 -0
  19. mcserver/commands/start_server.py +150 -0
  20. mcserver/commands/stop_server.py +46 -0
  21. mcserver/commands/update_projects.py +6 -0
  22. mcserver/commands/whitelist_add.py +7 -0
  23. mcserver/commands/whitelist_list.py +31 -0
  24. mcserver/commands/whitelist_remove.py +31 -0
  25. mcserver/commandsa.py +1297 -0
  26. mcserver/config.py +37 -0
  27. mcserver/constants.py +14 -0
  28. mcserver/fabricmc/meta.py +41 -0
  29. mcserver/legacyfabric/meta.py +37 -0
  30. mcserver/metadata.py +33 -0
  31. mcserver/minecraft/api.py +94 -0
  32. mcserver/minecraft/player_identity.py +21 -0
  33. mcserver/modrinth/api.py +657 -0
  34. mcserver/modrinth/modpack.py +101 -0
  35. mcserver/modrinth/project_records/metadata.py +0 -0
  36. mcserver/modrinth/project_records/relationships.py +203 -0
  37. mcserver/modrinth/project_records/shared.py +9 -0
  38. mcserver/modrinth/projects.py +80 -0
  39. mcserver/modrinth/shared.py +13 -0
  40. mcserver/modrinth/slug_index.py +36 -0
  41. mcserver/mojang/eula.py +28 -0
  42. mcserver/mojang/manifest.py +69 -0
  43. mcserver/mysterious.py +5 -0
  44. mcserver/networking.py +152 -0
  45. mcserver/papermc/api.py +81 -0
  46. mcserver/purpurmc/api.py +81 -0
  47. mcserver/quiltmc/meta.py +54 -0
  48. mcserver/resolver.py +164 -0
  49. mcserver/server_files/banned_ips.py +120 -0
  50. mcserver/server_files/banned_players.py +166 -0
  51. mcserver/server_files/ops.py +143 -0
  52. mcserver/server_files/properties.py +41 -0
  53. mcserver/server_files/usercaches.py +0 -0
  54. mcserver/server_files/whitelist.py +163 -0
  55. mcserver/shared.py +198 -0
  56. mcserver/state.py +77 -0
  57. mcserver_cli-3.0.0.dist-info/METADATA +63 -0
  58. mcserver_cli-3.0.0.dist-info/RECORD +61 -0
  59. mcserver_cli-3.0.0.dist-info/WHEEL +4 -0
  60. mcserver_cli-3.0.0.dist-info/entry_points.txt +2 -0
  61. mcserver_cli-3.0.0.dist-info/licenses/LICENSE +9 -0
@@ -0,0 +1,150 @@
1
+ import argparse
2
+
3
+
4
+ def main(args: argparse.Namespace) -> int:
5
+ import logging as log
6
+
7
+ from .. import state
8
+
9
+ # Check MCServer status
10
+ current_state = state.get_state()
11
+ if current_state["is_active"]:
12
+ log.error(
13
+ f"There's another active MCServer process ({current_state["action"]}) running with process ID: {current_state["process_id"]}"
14
+ )
15
+ return 1
16
+
17
+ # Set state
18
+ state.set_state("running_server")
19
+
20
+ import os
21
+ import shutil
22
+ from pathlib import Path
23
+
24
+ from .. import config
25
+
26
+ # Load configs
27
+ launcher_config = config.load_config("launcher")
28
+
29
+ jarfile = Path(launcher_config["jarfile"])
30
+ memory_config = launcher_config["ram"]
31
+
32
+ # Download jarfile
33
+ if not jarfile.exists():
34
+ import json
35
+
36
+ from .. import networking
37
+
38
+ state.set_state("downloading_server")
39
+
40
+ server_config = config.load_config("server")
41
+ game_version = server_config["game_version"]
42
+ server_loader = server_config["loader"]
43
+
44
+ loader_name = server_loader["name"]
45
+ loader_version = server_loader["version"]
46
+
47
+ if loader_name != "vanilla" and loader_version is None:
48
+ log.error(f"Loader version cannot be null")
49
+ return 1
50
+
51
+ match loader_name:
52
+ # Mod loaders
53
+ case "fabric":
54
+ from ..fabricmc import meta as fabricmc_meta
55
+
56
+ log.info(
57
+ f"Downloading Fabric loader {loader_version} for Minecraft version {game_version}..."
58
+ )
59
+ networking.download(
60
+ fabricmc_meta.download_url(game_version, loader_version, "1.0.1"),
61
+ jarfile,
62
+ )
63
+
64
+ # case "quilt":
65
+ # log.info(f"Downloading Quilt loader {loader_version} for Minecraft version {game_version}...")
66
+ # networking.download(f"https://")
67
+
68
+ # case "legacy-fabric":
69
+ # pass
70
+
71
+ # Plugin loaders
72
+ case "paper":
73
+ from ..papermc import api as papermc_api
74
+
75
+ log.info(
76
+ f"Downloading Paper build {loader_version} for Minecraft version {game_version}..."
77
+ )
78
+
79
+ download_prop = papermc_api.get_project_build(
80
+ "paper", game_version, loader_version
81
+ )["download_props"]["server:default"]
82
+ networking.download(download_prop["download_url"], jarfile)
83
+ case "purpur":
84
+ from ..purpurmc import api as purpurmc_api
85
+
86
+ log.info(
87
+ f"Downloading Purpur build {loader_version} for Minecraft version {game_version}..."
88
+ )
89
+ networking.download(
90
+ purpurmc_api.download_url("purpur", game_version, loader_version),
91
+ jarfile,
92
+ )
93
+
94
+ # Vanilla
95
+ case "vanilla":
96
+ from ..mojang import manifest as mojang_manifest
97
+
98
+ log.info(f"Downloading vanilla Minecraft version {game_version}...")
99
+
100
+ version_manifest = mojang_manifest.get_version_manifest()[
101
+ "game_versions"
102
+ ]
103
+ package_url = None
104
+ for version in version_manifest:
105
+ if version["version_id"] == game_version:
106
+ package_url = version["package_url"]
107
+ break
108
+
109
+ if package_url is None:
110
+ log.error(f"Minecraft version not found: {game_version}")
111
+ return 1
112
+
113
+ package_data = networking.request(package_url)["text"]
114
+ package_json = json.loads(package_data)
115
+ version_download = package_json["downloads"]["server"]
116
+
117
+ networking.download(
118
+ version_download["url"],
119
+ jarfile,
120
+ hashes={"sha1": version_download["sha1"]},
121
+ )
122
+ case _:
123
+ log.error(f"Loader is not supported: {loader_name}")
124
+
125
+ # Check stuff
126
+ if not shutil.which("java"):
127
+ log.error("Java is not installed in PATH")
128
+ return 1
129
+
130
+ if memory_config["min"] > memory_config["max"]:
131
+ log.error("Minimum RAM is bigger than maximum RAM")
132
+ return 1
133
+
134
+ # Run the server
135
+ java_command_argv = [
136
+ "java",
137
+ f"-Xmx{memory_config['max']}M",
138
+ f"-Xms{memory_config['min']}M",
139
+ "-jar",
140
+ str(jarfile),
141
+ ]
142
+
143
+ if launcher_config["is_nogui"]:
144
+ java_command_argv.append("nogui")
145
+
146
+ # Execute java
147
+ log.debug(f"Executing command: {' '.join(java_command_argv)}")
148
+
149
+ state.set_state("server_running")
150
+ os.execvp(java_command_argv[0], java_command_argv)
@@ -0,0 +1,46 @@
1
+ import argparse
2
+
3
+
4
+ def main(args: argparse.Namespace) -> int:
5
+ # CLI arguments
6
+ force_stop: bool = args.force_stop
7
+
8
+ import logging as log
9
+ import os
10
+ from signal import SIGKILL, SIGTERM
11
+
12
+ from .. import state
13
+
14
+ try:
15
+ current_state = state.get_state()
16
+ except FileNotFoundError:
17
+ log.error(f"File '{state.state_file}' not found; MCServer not initialized.")
18
+ return 1
19
+
20
+ if not current_state["is_active"]:
21
+ log.error("Server is not running.")
22
+ return 1
23
+
24
+ log.info("Stopping server...")
25
+ os.kill(current_state["process_id"], SIGTERM)
26
+
27
+ current_state = state.get_state()
28
+ if current_state["is_active"]:
29
+ return 0
30
+
31
+ if not force_stop:
32
+ log.warning(
33
+ "Server appears to still be running, you may stop the server manually."
34
+ )
35
+ return 1
36
+
37
+ import time
38
+
39
+ from .. import config
40
+
41
+ launcher_config = config.load_config("launcher")
42
+ time.sleep(launcher_config["force_stop"])
43
+
44
+ log.warning("Server process is still running, force stopping the server...")
45
+ os.kill(current_state["process_id"], SIGKILL)
46
+ return 1
@@ -0,0 +1,6 @@
1
+ import argparse
2
+
3
+
4
+ def main(args: argparse.Namespace) -> int:
5
+ print(args)
6
+ return 0
@@ -0,0 +1,7 @@
1
+ import argparse
2
+
3
+
4
+ def main(args: argparse.Namespace) -> int:
5
+ players: list[str] = args.players
6
+ print(args)
7
+ return 0
@@ -0,0 +1,31 @@
1
+ import argparse
2
+
3
+
4
+ def main(args: argparse.Namespace) -> int:
5
+ import logging as log
6
+
7
+ from ..server_files import whitelist
8
+ from ..shared import pluralize
9
+
10
+ if not whitelist.whitelist_file.exists():
11
+ log.error(f"File '{whitelist.whitelist_file}' not found.")
12
+ return 1
13
+
14
+ whitelisted_players = whitelist.list_players()
15
+
16
+ player_list: list[str] = []
17
+ for player in whitelisted_players:
18
+ player_list.append(f"{player['player_name']} ({player['player_uuid']})")
19
+
20
+ player_count: int = len(player_list)
21
+ if player_count == 0:
22
+ log.info("There are no whitelisted players.")
23
+ return 0
24
+ else:
25
+ log.info(
26
+ f"There {pluralize('is', player_count)} whitelisted {pluralize('player', player_count)}:"
27
+ )
28
+
29
+ player_list.sort()
30
+ print("\n".join(player_list))
31
+ return 0
@@ -0,0 +1,31 @@
1
+ import argparse
2
+ from uuid import UUID
3
+ from ..server_files.whitelist import remove_players
4
+ from ..minecraft.player_identity import PlayerID
5
+
6
+ import logging as log
7
+
8
+
9
+ def main(args: argparse.Namespace) -> int:
10
+ players: list[str] = args.players
11
+ player_ids: list[PlayerID] = []
12
+ for player in players:
13
+ try:
14
+ UUID(player)
15
+ log.debug(f"{player} is likely an UUID")
16
+ player_id: PlayerID = {"player_uuid": player}
17
+
18
+ player_ids.append(player_id)
19
+ except ValueError:
20
+ log.debug(f"{player} is likely a name")
21
+ player_id: PlayerID = {"player_name": player}
22
+
23
+ player_ids.append(player_id)
24
+
25
+ try:
26
+ remove_players(player_ids)
27
+ except FileNotFoundError as error:
28
+ log.error(error)
29
+ return 1
30
+
31
+ return 0