mcserver-cli 4.3.0__tar.gz → 4.4.0__tar.gz
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.
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/CHANGELOG.md +15 -1
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/NOTES.txt +2 -1
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/PKG-INFO +14 -7
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/README.md +13 -6
- mcserver_cli-4.4.0/src/mcserver/__init__.py +1 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/cli.py +16 -2
- mcserver_cli-4.4.0/src/mcserver/commands/op_list.py +35 -0
- mcserver_cli-4.4.0/src/mcserver/commands/op_revoke.py +43 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/whitelist_list.py +11 -11
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/whitelist_remove.py +6 -4
- mcserver_cli-4.4.0/src/mcserver/server_files/ops.py +114 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/server_files/paths.py +1 -0
- mcserver_cli-4.4.0/src/mcserver/server_files/whitelist.py +102 -0
- mcserver_cli-4.3.0/src/mcserver/__init__.py +0 -1
- mcserver_cli-4.3.0/src/mcserver/commands/op_list.py +0 -32
- mcserver_cli-4.3.0/src/mcserver/commands/op_revoke.py +0 -9
- mcserver_cli-4.3.0/src/mcserver/server_files/ops.py +0 -143
- mcserver_cli-4.3.0/src/mcserver/server_files/whitelist.py +0 -138
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/.gitignore +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/CONTRIBUTING.md +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/LICENSE +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/legacy/mcserver_v2.0.0.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/pyproject.toml +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/__main__.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/__main__.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/app.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/caching.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/__init__.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/add_projects.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/import_setup.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/initialize_server.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/list_projects.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/op_grant.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/print_help.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/remove_projects.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/search_projects.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/server_status.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/show_projects.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/start_server.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/stop_server.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/update_projects.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/commands/whitelist_add.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/config.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/constants.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/fabricmc/meta.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/legacy_fabric/meta.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/metadata.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/minecraft/api.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/minecraft/player_identity.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/apis/__init__.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/apis/get_project_informations.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/apis/get_project_versions.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/apis/search_projects.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/constants.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/modpack.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/paths.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/project_records.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/projects.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/shared.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/slug_index.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/typings/__init__.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/typings/project_information.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/typings/project_version.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/typings/search_projects.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/typings/shared.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/mojang/eula.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/mojang/manifest.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/mysterious.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/networking.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/papermc/api.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/paths.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/purpurmc/api.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/quiltmc/meta.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/resolver.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/server_files/banned_ips.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/server_files/banned_players.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/server_files/properties.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/server_files/usercaches.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/shared.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/state.py +0 -0
- {mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/zip_app.py +0 -0
|
@@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
|
|
9
|
+
## [4.4.0] - 2026-11-04
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `op remove` to remove players based on UUIDs or names
|
|
14
|
+
- Player count to `whitelist list`
|
|
15
|
+
|
|
16
|
+
### Fixes
|
|
17
|
+
|
|
18
|
+
- Wrong description for `whitelist remove`
|
|
19
|
+
- Fixing the wrong singular text in whitelist when no whitelisted player
|
|
20
|
+
|
|
8
21
|
## [4.3.0] - 2026-11-02
|
|
9
22
|
|
|
10
23
|
### Added
|
|
@@ -234,7 +247,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
234
247
|
- Better mod conflict error
|
|
235
248
|
- Faster mod resolving
|
|
236
249
|
|
|
237
|
-
[unreleased]: https://github.com/Othecat35/MCServer/compare/v4.
|
|
250
|
+
[unreleased]: https://github.com/Othecat35/MCServer/compare/v4.4.0...HEAD
|
|
251
|
+
[4.4.0]: https://github.com/Othecat35/MCServer/compare/v4.3.0...v4.4.0
|
|
238
252
|
[4.3.0]: https://github.com/Othecat35/MCServer/compare/v4.2.0...v4.3.0
|
|
239
253
|
[4.2.0]: https://github.com/Othecat35/MCServer/compare/v4.1.0...v4.2.0
|
|
240
254
|
[4.1.0]: https://github.com/Othecat35/MCServer/compare/v4.0.0...v4.1.0
|
|
@@ -390,4 +390,5 @@ it can be the default config of all your new Minecraft server derived from
|
|
|
390
390
|
and yea
|
|
391
391
|
|
|
392
392
|
|
|
393
|
-
|
|
393
|
+
Ah yes... rcon, and also swrver management protocol.
|
|
394
|
+
Don't forget to add a warning fof whitelist remove if the server is running to run whitelist remove
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: mcserver-cli
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.0
|
|
4
4
|
Summary: A CLI tool to manage Minecraft: Java Edition servers.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Othecat35/MCServer
|
|
6
6
|
Project-URL: Repository, https://github.com/Othecat35/MCServer.git
|
|
@@ -25,8 +25,7 @@ Supported platforms:
|
|
|
25
25
|
- JRE (depends on Minecraft version)
|
|
26
26
|
|
|
27
27
|
## How to install
|
|
28
|
-
- Using pip:
|
|
29
|
-
1. Run `pip install mcserver-cli`
|
|
28
|
+
- Using pip: Run `pip install mcserver-cli`
|
|
30
29
|
|
|
31
30
|
- System-wide (Requires root):
|
|
32
31
|
1. Download the `mcserver` script file from GitHub releases
|
|
@@ -44,28 +43,36 @@ Supported platforms:
|
|
|
44
43
|
## Usage
|
|
45
44
|
- Initialize a server: `mcserver init [options]`
|
|
46
45
|
- List operator players: `mcserver op list`
|
|
46
|
+
- Revoke operator players: `mcserver op revoke <players>`
|
|
47
|
+
- Search projects: `mcserver search [query] [options]`
|
|
47
48
|
- Show information about projects: `mcserver show <projects>`
|
|
48
49
|
- Start the server: `mcserver start`
|
|
49
|
-
- Stop the server: `mcserver stop
|
|
50
|
+
- Stop the server: `mcserver stop`
|
|
50
51
|
- List whitelisted players: `mcserver whitelist list`
|
|
52
|
+
- Remove whitelisted players: `mcserver whitelist remove <players>`
|
|
51
53
|
|
|
52
|
-
###
|
|
54
|
+
### Examples
|
|
53
55
|
- Create and start a Fabric 1.20.1 server on current directory
|
|
54
56
|
```bash
|
|
55
57
|
mcserver init --game-version=1.20.1 --loader=fabric
|
|
56
58
|
mcserver start
|
|
57
59
|
```
|
|
58
60
|
|
|
61
|
+
- Search top 50 Fabric mods for Minecraft 1.20.1 in modrinth
|
|
62
|
+
```bash
|
|
63
|
+
mcserver search --loader=fabric --game-version=1.20.1 --limit=50
|
|
64
|
+
```
|
|
65
|
+
|
|
59
66
|
- List all operator and whitelisted players on current directory
|
|
60
67
|
```bash
|
|
61
68
|
mcserver op list
|
|
62
69
|
mcserver whitelist list
|
|
63
70
|
```
|
|
64
71
|
|
|
65
|
-
- Stop
|
|
72
|
+
- Stop a server on current directory with sigterm
|
|
66
73
|
```bash
|
|
67
74
|
mcserver stop
|
|
68
75
|
```
|
|
69
76
|
|
|
70
77
|
## Note
|
|
71
|
-
This is a **Personal Project
|
|
78
|
+
This is a **Personal Project** by Othecat35, so don't expect much from me :>
|
|
@@ -12,8 +12,7 @@ Supported platforms:
|
|
|
12
12
|
- JRE (depends on Minecraft version)
|
|
13
13
|
|
|
14
14
|
## How to install
|
|
15
|
-
- Using pip:
|
|
16
|
-
1. Run `pip install mcserver-cli`
|
|
15
|
+
- Using pip: Run `pip install mcserver-cli`
|
|
17
16
|
|
|
18
17
|
- System-wide (Requires root):
|
|
19
18
|
1. Download the `mcserver` script file from GitHub releases
|
|
@@ -31,28 +30,36 @@ Supported platforms:
|
|
|
31
30
|
## Usage
|
|
32
31
|
- Initialize a server: `mcserver init [options]`
|
|
33
32
|
- List operator players: `mcserver op list`
|
|
33
|
+
- Revoke operator players: `mcserver op revoke <players>`
|
|
34
|
+
- Search projects: `mcserver search [query] [options]`
|
|
34
35
|
- Show information about projects: `mcserver show <projects>`
|
|
35
36
|
- Start the server: `mcserver start`
|
|
36
|
-
- Stop the server: `mcserver stop
|
|
37
|
+
- Stop the server: `mcserver stop`
|
|
37
38
|
- List whitelisted players: `mcserver whitelist list`
|
|
39
|
+
- Remove whitelisted players: `mcserver whitelist remove <players>`
|
|
38
40
|
|
|
39
|
-
###
|
|
41
|
+
### Examples
|
|
40
42
|
- Create and start a Fabric 1.20.1 server on current directory
|
|
41
43
|
```bash
|
|
42
44
|
mcserver init --game-version=1.20.1 --loader=fabric
|
|
43
45
|
mcserver start
|
|
44
46
|
```
|
|
45
47
|
|
|
48
|
+
- Search top 50 Fabric mods for Minecraft 1.20.1 in modrinth
|
|
49
|
+
```bash
|
|
50
|
+
mcserver search --loader=fabric --game-version=1.20.1 --limit=50
|
|
51
|
+
```
|
|
52
|
+
|
|
46
53
|
- List all operator and whitelisted players on current directory
|
|
47
54
|
```bash
|
|
48
55
|
mcserver op list
|
|
49
56
|
mcserver whitelist list
|
|
50
57
|
```
|
|
51
58
|
|
|
52
|
-
- Stop
|
|
59
|
+
- Stop a server on current directory with sigterm
|
|
53
60
|
```bash
|
|
54
61
|
mcserver stop
|
|
55
62
|
```
|
|
56
63
|
|
|
57
64
|
## Note
|
|
58
|
-
This is a **Personal Project
|
|
65
|
+
This is a **Personal Project** by Othecat35, so don't expect much from me :>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "4.4.0"
|
|
@@ -224,6 +224,18 @@ def main() -> int:
|
|
|
224
224
|
|
|
225
225
|
op_list_command.set_defaults(command_name="op_list")
|
|
226
226
|
|
|
227
|
+
# 'op revoke'
|
|
228
|
+
op_revoke_command = op_subcommands.add_parser(
|
|
229
|
+
"revoke",
|
|
230
|
+
help="Revoke operator players permission",
|
|
231
|
+
description="Revoke operator players permission.",
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
op_revoke_command.set_defaults(command_name="op_revoke")
|
|
235
|
+
op_revoke_command.add_argument(
|
|
236
|
+
"players", nargs="+", type=str, help="List of player names or UUIDs"
|
|
237
|
+
)
|
|
238
|
+
|
|
227
239
|
# 'search' command
|
|
228
240
|
search_command = commands.add_parser(
|
|
229
241
|
"search",
|
|
@@ -336,11 +348,13 @@ def main() -> int:
|
|
|
336
348
|
whitelist_remove_command = whitelist_subcommands.add_parser(
|
|
337
349
|
"remove",
|
|
338
350
|
help="Remove players from the whitelist",
|
|
339
|
-
description="
|
|
351
|
+
description="Remove players from the whitelist.",
|
|
340
352
|
)
|
|
341
353
|
|
|
342
354
|
whitelist_remove_command.set_defaults(command_name="whitelist_remove")
|
|
343
|
-
whitelist_remove_command.add_argument(
|
|
355
|
+
whitelist_remove_command.add_argument(
|
|
356
|
+
"players", nargs="+", type=str, help="List of player names or UUIDs"
|
|
357
|
+
)
|
|
344
358
|
|
|
345
359
|
args = parser.parse_args()
|
|
346
360
|
return args.func(args)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from argparse import Namespace
|
|
3
|
+
|
|
4
|
+
from ..server_files import ops
|
|
5
|
+
from ..shared import pluralize
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def run(args: Namespace) -> int:
|
|
11
|
+
ops_file = ops.ops_file_path
|
|
12
|
+
if not ops_file.exists():
|
|
13
|
+
logger.error(f"Operator file '{ops.ops_file_path}' not found.")
|
|
14
|
+
return 1
|
|
15
|
+
|
|
16
|
+
operator_players = ops.list_players()
|
|
17
|
+
|
|
18
|
+
player_count = len(operator_players)
|
|
19
|
+
if player_count == 0:
|
|
20
|
+
logger.info("There's no operator player.")
|
|
21
|
+
return 0
|
|
22
|
+
|
|
23
|
+
player_list: list[str] = []
|
|
24
|
+
for player in operator_players:
|
|
25
|
+
player_list.append(
|
|
26
|
+
f"{player['player_name']} ({player['player_uuid']}) Level: {player['permission_level']}"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
logger.info(
|
|
30
|
+
f"There {pluralize('is', player_count)} {player_count} {pluralize('operator', player_count)}:"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
player_list.sort()
|
|
34
|
+
print("\n".join(player_list))
|
|
35
|
+
return 0
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from argparse import Namespace
|
|
3
|
+
from uuid import UUID
|
|
4
|
+
|
|
5
|
+
from ..server_files import ops
|
|
6
|
+
from ..shared import pluralize
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def run(args: Namespace) -> int:
|
|
12
|
+
player_identifiers: list[str] = args.players
|
|
13
|
+
|
|
14
|
+
player_uuids: list[UUID] = []
|
|
15
|
+
player_names: list[str] = []
|
|
16
|
+
for player in player_identifiers:
|
|
17
|
+
if len(player) > 16:
|
|
18
|
+
logger.debug(f"{player} is probably an UUID")
|
|
19
|
+
player_uuids.append(UUID(player))
|
|
20
|
+
else:
|
|
21
|
+
logger.debug(f"{player} is probably a name")
|
|
22
|
+
player_names.append(player)
|
|
23
|
+
|
|
24
|
+
removed_players = ops.remove_players(player_uuids, player_names)
|
|
25
|
+
|
|
26
|
+
player_count: int = len(removed_players)
|
|
27
|
+
if player_count == 0:
|
|
28
|
+
logger.info("No matching player found.")
|
|
29
|
+
return 0
|
|
30
|
+
|
|
31
|
+
player_list: list[str] = []
|
|
32
|
+
for player in removed_players:
|
|
33
|
+
player_list.append(
|
|
34
|
+
f"{player['player_name']} ({player['player_uuid']}) Level: {player['permission_level']}"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
logger.info(
|
|
38
|
+
f"There {pluralize('is', player_count)} {player_count} operator {pluralize('player', player_count)} that {pluralize('is', player_count)} removed:"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
player_list.sort()
|
|
42
|
+
print("\n".join(player_list))
|
|
43
|
+
return 0
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import argparse
|
|
2
1
|
import logging
|
|
2
|
+
from argparse import Namespace
|
|
3
3
|
|
|
4
4
|
from ..server_files import whitelist
|
|
5
5
|
from ..shared import pluralize
|
|
@@ -7,26 +7,26 @@ from ..shared import pluralize
|
|
|
7
7
|
logger = logging.getLogger(__name__)
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
def run(args:
|
|
10
|
+
def run(args: Namespace) -> int:
|
|
11
11
|
whitelist_file = whitelist.whitelist_file_path
|
|
12
12
|
if not whitelist_file.exists():
|
|
13
|
-
logger.error(f"Whitelist file ({whitelist_file})
|
|
13
|
+
logger.error(f"Whitelist file ({whitelist_file}) not found!")
|
|
14
14
|
return 1
|
|
15
15
|
|
|
16
16
|
whitelisted_players = whitelist.list_players()
|
|
17
17
|
|
|
18
|
+
player_count: int = len(whitelisted_players)
|
|
19
|
+
if player_count == 0:
|
|
20
|
+
logger.info("There are no whitelisted player.")
|
|
21
|
+
return 0
|
|
22
|
+
|
|
18
23
|
player_list: list[str] = []
|
|
19
24
|
for player in whitelisted_players:
|
|
20
25
|
player_list.append(f"{player['player_name']} ({player['player_uuid']})")
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return 0
|
|
26
|
-
else:
|
|
27
|
-
logger.info(
|
|
28
|
-
f"There {pluralize('is', player_count)} whitelisted {pluralize('player', player_count)}:"
|
|
29
|
-
)
|
|
27
|
+
logger.info(
|
|
28
|
+
f"There {pluralize('is', player_count)} {player_count} whitelisted {pluralize('player', player_count)}:"
|
|
29
|
+
)
|
|
30
30
|
|
|
31
31
|
player_list.sort()
|
|
32
32
|
print("\n".join(player_list))
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import argparse
|
|
2
1
|
import logging
|
|
2
|
+
from argparse import Namespace
|
|
3
|
+
from uuid import UUID
|
|
3
4
|
|
|
4
5
|
from ..server_files import whitelist
|
|
5
6
|
from ..shared import pluralize
|
|
6
7
|
|
|
7
8
|
logger = logging.getLogger(__name__)
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
def run(args: Namespace) -> int:
|
|
10
12
|
player_identifiers: list[str] = args.players
|
|
11
13
|
|
|
12
|
-
player_uuids: list[
|
|
14
|
+
player_uuids: list[UUID] = []
|
|
13
15
|
player_names: list[str] = []
|
|
14
16
|
for player in player_identifiers:
|
|
15
17
|
if len(player) > 16:
|
|
16
18
|
logger.debug(f"{player} is probably an UUID")
|
|
17
|
-
player_uuids.append(player)
|
|
19
|
+
player_uuids.append(UUID(player))
|
|
18
20
|
else:
|
|
19
21
|
logger.debug(f"{player} is probably a name")
|
|
20
22
|
player_names.append(player)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
from typing import TypedDict
|
|
5
|
+
from uuid import UUID
|
|
6
|
+
|
|
7
|
+
from ..minecraft.player_identity import normalize_player_uuid
|
|
8
|
+
from .paths import ops_file_path
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class OperatorPlayer(TypedDict):
|
|
14
|
+
player_uuid: UUID
|
|
15
|
+
player_name: str
|
|
16
|
+
permission_level: int
|
|
17
|
+
bypasses_player_limit: bool
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class OperatorFilePlayer(TypedDict):
|
|
21
|
+
uuid: str
|
|
22
|
+
name: str
|
|
23
|
+
level: int
|
|
24
|
+
bypassesPlayerLimit: bool
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def remove_players(
|
|
28
|
+
player_uuids: Sequence[UUID | str] | UUID | str | None = None,
|
|
29
|
+
player_names: list[str] | str | None = None,
|
|
30
|
+
) -> list[OperatorPlayer]:
|
|
31
|
+
"""Remove operator players that matches either by UUIDs or names
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
player_uuids: List of player UUIDs to be removed
|
|
35
|
+
player_names: List of player names to be removed
|
|
36
|
+
|
|
37
|
+
Raises:
|
|
38
|
+
ValueError: Must provide at least a player UUID or player name
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
List of operator players that are removed"""
|
|
42
|
+
if player_uuids is None:
|
|
43
|
+
player_uuids = []
|
|
44
|
+
elif isinstance(player_uuids, (UUID, str)):
|
|
45
|
+
player_uuids = [player_uuids]
|
|
46
|
+
|
|
47
|
+
if player_names is None:
|
|
48
|
+
player_names = []
|
|
49
|
+
elif isinstance(player_names, str):
|
|
50
|
+
player_names = [player_names]
|
|
51
|
+
|
|
52
|
+
if not player_uuids and not player_names:
|
|
53
|
+
raise ValueError("Must provide at least a player UUID or player name")
|
|
54
|
+
|
|
55
|
+
names: set[str] = set(player_names)
|
|
56
|
+
|
|
57
|
+
uuids: set[UUID] = set()
|
|
58
|
+
for player_uuid in player_uuids:
|
|
59
|
+
uuids.add(normalize_player_uuid(player_uuid))
|
|
60
|
+
|
|
61
|
+
removed_players: list[OperatorPlayer] = []
|
|
62
|
+
with open(ops_file_path, mode="r+") as ops_file:
|
|
63
|
+
ops_data: list[OperatorFilePlayer] = json.load(ops_file)
|
|
64
|
+
|
|
65
|
+
new_ops_data: list[OperatorFilePlayer] = []
|
|
66
|
+
for operator_file_player in ops_data:
|
|
67
|
+
if (
|
|
68
|
+
UUID(operator_file_player["uuid"]) in uuids
|
|
69
|
+
or operator_file_player["name"] in names
|
|
70
|
+
):
|
|
71
|
+
logger.debug(
|
|
72
|
+
f"Operator player {operator_file_player['name']} ({operator_file_player['uuid']}) is removed"
|
|
73
|
+
)
|
|
74
|
+
operator_player: OperatorPlayer = {
|
|
75
|
+
"player_uuid": UUID(operator_file_player["uuid"]),
|
|
76
|
+
"player_name": operator_file_player["name"],
|
|
77
|
+
"permission_level": operator_file_player["level"],
|
|
78
|
+
"bypasses_player_limit": operator_file_player[
|
|
79
|
+
"bypassesPlayerLimit"
|
|
80
|
+
],
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
removed_players.append(operator_player)
|
|
84
|
+
continue
|
|
85
|
+
|
|
86
|
+
new_ops_data.append(operator_file_player)
|
|
87
|
+
|
|
88
|
+
ops_file.seek(0)
|
|
89
|
+
json.dump(new_ops_data, ops_file, indent=2)
|
|
90
|
+
ops_file.truncate()
|
|
91
|
+
|
|
92
|
+
return removed_players
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def list_players() -> list[OperatorPlayer]:
|
|
96
|
+
"""List all operator players
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
List of operator players"""
|
|
100
|
+
logger.debug(f"Reading {ops_file_path}")
|
|
101
|
+
ops_json: list[OperatorFilePlayer] = json.loads(ops_file_path.read_text())
|
|
102
|
+
|
|
103
|
+
operator_players: list[OperatorPlayer] = []
|
|
104
|
+
for player in ops_json:
|
|
105
|
+
operator_player: OperatorPlayer = {
|
|
106
|
+
"player_uuid": UUID(player["uuid"]),
|
|
107
|
+
"player_name": player["name"],
|
|
108
|
+
"permission_level": player["level"],
|
|
109
|
+
"bypasses_player_limit": player["bypassesPlayerLimit"],
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
operator_players.append(operator_player)
|
|
113
|
+
|
|
114
|
+
return operator_players
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
from typing import TypedDict
|
|
5
|
+
from uuid import UUID
|
|
6
|
+
|
|
7
|
+
from ..minecraft.player_identity import normalize_player_uuid
|
|
8
|
+
from .paths import whitelist_file_path
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class WhitelistedPlayer(TypedDict):
|
|
14
|
+
player_uuid: UUID
|
|
15
|
+
player_name: str
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class WhitelistedFilePlayer(TypedDict):
|
|
19
|
+
uuid: str
|
|
20
|
+
name: str
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def remove_players(
|
|
24
|
+
player_uuids: Sequence[UUID | str] | UUID | str | None = None,
|
|
25
|
+
player_names: list[str] | str | None = None,
|
|
26
|
+
) -> list[WhitelistedPlayer]:
|
|
27
|
+
"""Remove players from the whitelist that matches either by UUIDs or names
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
player_uuids: List of player UUIDs to be removed
|
|
31
|
+
player_names: List of player names to be removed
|
|
32
|
+
|
|
33
|
+
Raises:
|
|
34
|
+
ValueError: Must provide at least a player UUID or player name
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
List of whitelisted players that are removed"""
|
|
38
|
+
if player_uuids is None:
|
|
39
|
+
player_uuids = []
|
|
40
|
+
elif isinstance(player_uuids, (UUID, str)):
|
|
41
|
+
player_uuids = [player_uuids]
|
|
42
|
+
|
|
43
|
+
if player_names is None:
|
|
44
|
+
player_names = []
|
|
45
|
+
elif isinstance(player_names, str):
|
|
46
|
+
player_names = [player_names]
|
|
47
|
+
|
|
48
|
+
if not player_uuids and not player_names:
|
|
49
|
+
raise ValueError("Must provide at least a player UUID or player name")
|
|
50
|
+
|
|
51
|
+
names: set[str] = set(player_names)
|
|
52
|
+
|
|
53
|
+
uuids: set[UUID] = set()
|
|
54
|
+
for player_uuid in player_uuids:
|
|
55
|
+
uuids.add(normalize_player_uuid(player_uuid))
|
|
56
|
+
|
|
57
|
+
removed_players: list[WhitelistedPlayer] = []
|
|
58
|
+
with open(whitelist_file_path, mode="r+") as whitelist_file:
|
|
59
|
+
whitelist_data: list[WhitelistedFilePlayer] = json.load(whitelist_file)
|
|
60
|
+
|
|
61
|
+
new_whitelist_data: list[WhitelistedFilePlayer] = []
|
|
62
|
+
for whitelisted_file_player in whitelist_data:
|
|
63
|
+
if (
|
|
64
|
+
UUID(whitelisted_file_player["uuid"]) in uuids
|
|
65
|
+
or whitelisted_file_player["name"] in names
|
|
66
|
+
):
|
|
67
|
+
logger.debug(
|
|
68
|
+
f"Whitelisted player {whitelisted_file_player['name']} ({whitelisted_file_player['uuid']}) is removed"
|
|
69
|
+
)
|
|
70
|
+
whitelisted_player: WhitelistedPlayer = {
|
|
71
|
+
"player_uuid": UUID(whitelisted_file_player["uuid"]),
|
|
72
|
+
"player_name": whitelisted_file_player["name"],
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
removed_players.append(whitelisted_player)
|
|
76
|
+
continue
|
|
77
|
+
|
|
78
|
+
new_whitelist_data.append(whitelisted_file_player)
|
|
79
|
+
|
|
80
|
+
whitelist_file.seek(0)
|
|
81
|
+
json.dump(new_whitelist_data, whitelist_file, indent=2)
|
|
82
|
+
whitelist_file.truncate()
|
|
83
|
+
|
|
84
|
+
return removed_players
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def list_players() -> list[WhitelistedPlayer]:
|
|
88
|
+
logger.debug(f"Reading whitelist file {whitelist_file_path}")
|
|
89
|
+
whitelist_data: list[WhitelistedFilePlayer] = json.loads(
|
|
90
|
+
whitelist_file_path.read_text()
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
whitelisted_players: list[WhitelistedPlayer] = []
|
|
94
|
+
for player in whitelist_data:
|
|
95
|
+
whitelisted_player: WhitelistedPlayer = {
|
|
96
|
+
"player_uuid": UUID(player["uuid"]),
|
|
97
|
+
"player_name": player["name"],
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
whitelisted_players.append(whitelisted_player)
|
|
101
|
+
|
|
102
|
+
return whitelisted_players
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "4.3.0"
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
from argparse import Namespace
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def run(args: Namespace) -> int:
|
|
5
|
-
import logging as log
|
|
6
|
-
|
|
7
|
-
from ..server_files import ops
|
|
8
|
-
from ..shared import pluralize
|
|
9
|
-
|
|
10
|
-
if not ops.ops_file.exists():
|
|
11
|
-
log.error(f"File '{ops.ops_file}' not found.")
|
|
12
|
-
return 1
|
|
13
|
-
|
|
14
|
-
operator_players = ops.list_players()
|
|
15
|
-
|
|
16
|
-
players: list[str] = []
|
|
17
|
-
for player in operator_players:
|
|
18
|
-
players.append(
|
|
19
|
-
f"{player['player_name']} ({player['player_uuid']}) Level: {player['permission_level']}"
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
players.sort()
|
|
23
|
-
sorted_players = "\n".join(players)
|
|
24
|
-
|
|
25
|
-
player_count = len(operator_players)
|
|
26
|
-
if player_count == 0:
|
|
27
|
-
log.info("There's no operator player.")
|
|
28
|
-
return 0
|
|
29
|
-
|
|
30
|
-
log.info(f"All {player_count} operator {pluralize('player', player_count)}:")
|
|
31
|
-
print(sorted_players)
|
|
32
|
-
return 0
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
# Modules
|
|
2
|
-
# Standard
|
|
3
|
-
import json
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import Literal, TypedDict
|
|
6
|
-
from uuid import UUID
|
|
7
|
-
|
|
8
|
-
# MCServer
|
|
9
|
-
from mcserver.minecraft.player_identity import (
|
|
10
|
-
PlayerID,
|
|
11
|
-
PlayerUUID,
|
|
12
|
-
normalize_player_uuid,
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
# Paths
|
|
16
|
-
ops_file = Path("ops.json")
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
# TypedDicts
|
|
20
|
-
class OperatorEntry(TypedDict):
|
|
21
|
-
uuid: str
|
|
22
|
-
name: str
|
|
23
|
-
level: Literal[0, 1, 2, 3, 4]
|
|
24
|
-
bypassesPlayerLimit: bool
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class OperatorPlayer(TypedDict):
|
|
28
|
-
player_uuid: PlayerUUID
|
|
29
|
-
player_name: str
|
|
30
|
-
permission_level: Literal[0, 1, 2, 3, 4]
|
|
31
|
-
bypasses_player_limit: bool
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# Functions
|
|
35
|
-
# Add Players
|
|
36
|
-
def add_player(
|
|
37
|
-
player_uuid: PlayerUUID,
|
|
38
|
-
player_name: str,
|
|
39
|
-
permission_level: Literal[0, 1, 2, 3, 4],
|
|
40
|
-
bypasses_player_limit: bool = False,
|
|
41
|
-
) -> None:
|
|
42
|
-
operator_player: OperatorPlayer = {
|
|
43
|
-
"player_uuid": player_uuid,
|
|
44
|
-
"player_name": player_name,
|
|
45
|
-
"permission_level": permission_level,
|
|
46
|
-
"bypasses_player_limit": bypasses_player_limit,
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
add_players(operator_player)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def add_players(operator_players: list[OperatorPlayer] | OperatorPlayer) -> None:
|
|
53
|
-
if not isinstance(operator_players, list):
|
|
54
|
-
operator_players = [operator_players]
|
|
55
|
-
|
|
56
|
-
with open(ops_file, mode="r+") as file:
|
|
57
|
-
ops_data: list[OperatorEntry] = json.load(file)
|
|
58
|
-
|
|
59
|
-
for player in operator_players:
|
|
60
|
-
permission_level = player["permission_level"]
|
|
61
|
-
if permission_level < 0 or permission_level > 4:
|
|
62
|
-
raise ValueError("Permission level must be between 0 and 4.")
|
|
63
|
-
|
|
64
|
-
operator_entry: OperatorEntry = {
|
|
65
|
-
"uuid": str(normalize_player_uuid(player["player_uuid"])),
|
|
66
|
-
"name": player["player_name"],
|
|
67
|
-
"level": permission_level,
|
|
68
|
-
"bypassesPlayerLimit": player["bypasses_player_limit"],
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
ops_data.append(operator_entry)
|
|
72
|
-
|
|
73
|
-
file.seek(0)
|
|
74
|
-
json.dump(ops_data, file, indent=2)
|
|
75
|
-
file.truncate()
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
# Remove Players
|
|
79
|
-
def remove_player(
|
|
80
|
-
player_uuid: PlayerUUID | None = None, player_name: str | None = None
|
|
81
|
-
) -> None:
|
|
82
|
-
if player_uuid is None and player_name is None:
|
|
83
|
-
raise ValueError(
|
|
84
|
-
"At least one of 'player_uuid' or 'player_name' must be provided"
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
player_id: PlayerID = {}
|
|
88
|
-
if player_uuid is not None:
|
|
89
|
-
player_id["player_uuid"] = normalize_player_uuid(player_uuid)
|
|
90
|
-
|
|
91
|
-
if player_name is not None:
|
|
92
|
-
player_id["player_name"] = player_name
|
|
93
|
-
|
|
94
|
-
remove_players(player_id)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def remove_players(player_ids: list[PlayerID] | PlayerID) -> None:
|
|
98
|
-
if not isinstance(player_ids, list):
|
|
99
|
-
player_ids = [player_ids]
|
|
100
|
-
|
|
101
|
-
player_uuids: set[PlayerUUID | None] = set()
|
|
102
|
-
player_names: set[str | None] = set()
|
|
103
|
-
|
|
104
|
-
for player_id in player_ids:
|
|
105
|
-
if "player_uuid" in player_id:
|
|
106
|
-
player_uuids.add(player_id["player_uuid"])
|
|
107
|
-
|
|
108
|
-
if "player_name" in player_id:
|
|
109
|
-
player_names.add(player_id["player_name"])
|
|
110
|
-
|
|
111
|
-
with open(ops_file, mode="r+") as file:
|
|
112
|
-
ops_data: list[OperatorEntry] = json.load(file)
|
|
113
|
-
|
|
114
|
-
new_ops_data: list[OperatorEntry] = []
|
|
115
|
-
for player in ops_data:
|
|
116
|
-
if player["uuid"] in player_uuids or player["name"] in player_names:
|
|
117
|
-
continue
|
|
118
|
-
|
|
119
|
-
new_ops_data.append(player)
|
|
120
|
-
|
|
121
|
-
file.seek(0)
|
|
122
|
-
json.dump(new_ops_data, file, indent=2)
|
|
123
|
-
file.truncate()
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
# TODO: add 'update_player' and 'update_players', just use plain dict.update() because it has no depth
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
# List Players
|
|
130
|
-
def list_players() -> list[OperatorPlayer]:
|
|
131
|
-
ops_data: list[OperatorEntry] = json.loads(ops_file.read_text())
|
|
132
|
-
operator_players: list[OperatorPlayer] = []
|
|
133
|
-
for entry in ops_data:
|
|
134
|
-
operator_player: OperatorPlayer = {
|
|
135
|
-
"player_uuid": UUID(entry["uuid"]),
|
|
136
|
-
"player_name": entry["name"],
|
|
137
|
-
"permission_level": entry["level"],
|
|
138
|
-
"bypasses_player_limit": entry["bypassesPlayerLimit"],
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
operator_players.append(operator_player)
|
|
142
|
-
|
|
143
|
-
return operator_players
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import logging
|
|
3
|
-
from typing import TypedDict
|
|
4
|
-
|
|
5
|
-
from ..minecraft.player_identity import PlayerUUID
|
|
6
|
-
from .paths import whitelist_file_path
|
|
7
|
-
|
|
8
|
-
logger = logging.getLogger(__name__)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class WhitelistedPlayer(TypedDict):
|
|
12
|
-
player_uuid: PlayerUUID
|
|
13
|
-
player_name: str
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class WhitelistedFilePlayer(TypedDict):
|
|
17
|
-
uuid: str
|
|
18
|
-
name: str
|
|
19
|
-
|
|
20
|
-
def remove_players(player_uuids: list[str] | str | None = None, player_names: list[str] | str | None = None) -> list[WhitelistedPlayer]:
|
|
21
|
-
"""Remove players from the whitelist that matches either the UUIDs or names
|
|
22
|
-
|
|
23
|
-
Args:
|
|
24
|
-
player_uuids: List of player UUIDs to be removed
|
|
25
|
-
player_names: List of player names to be removed
|
|
26
|
-
|
|
27
|
-
Raises:
|
|
28
|
-
ValueError: Must provide at least a player UUID or player name
|
|
29
|
-
|
|
30
|
-
Returns:
|
|
31
|
-
List of whitelisted players that are removed"""
|
|
32
|
-
if player_uuids is None:
|
|
33
|
-
player_uuids = []
|
|
34
|
-
|
|
35
|
-
if player_names is None:
|
|
36
|
-
player_names = []
|
|
37
|
-
|
|
38
|
-
if isinstance(player_uuids, str):
|
|
39
|
-
player_uuids = [player_uuids]
|
|
40
|
-
|
|
41
|
-
if isinstance(player_names, str):
|
|
42
|
-
player_names = [player_names]
|
|
43
|
-
|
|
44
|
-
if not player_uuids and not player_names:
|
|
45
|
-
raise ValueError("Must provide at least a player UUID or player name")
|
|
46
|
-
|
|
47
|
-
uuids: set[str] = set(player_uuids)
|
|
48
|
-
names: set[str] = set(player_names)
|
|
49
|
-
|
|
50
|
-
removed_players: list[WhitelistedPlayer] = []
|
|
51
|
-
with open(whitelist_file_path, mode="r+") as whitelist_file:
|
|
52
|
-
whitelist_data: list[WhitelistedFilePlayer] = json.load(whitelist_file)
|
|
53
|
-
|
|
54
|
-
new_whitelist_data: list[WhitelistedFilePlayer] = []
|
|
55
|
-
for whitelisted_file_player in whitelist_data:
|
|
56
|
-
if whitelisted_file_player["uuid"] in uuids or whitelisted_file_player["name"] in names:
|
|
57
|
-
logger.debug(f"Whitelisted player {whitelisted_file_player['name']} ({whitelisted_file_player['uuid']}) is removed")
|
|
58
|
-
whitelisted_player: WhitelistedPlayer = {
|
|
59
|
-
"player_uuid": whitelisted_file_player["uuid"],
|
|
60
|
-
"player_name": whitelisted_file_player["name"]
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
removed_players.append(whitelisted_player)
|
|
64
|
-
continue
|
|
65
|
-
|
|
66
|
-
new_whitelist_data.append(whitelisted_file_player)
|
|
67
|
-
|
|
68
|
-
whitelist_file.seek(0)
|
|
69
|
-
json.dump(new_whitelist_data, whitelist_file, indent=2)
|
|
70
|
-
whitelist_file.truncate()
|
|
71
|
-
|
|
72
|
-
return removed_players
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
# def remove_players(player_ids: list[PlayerID] | PlayerID) -> None:
|
|
77
|
-
# """Remove player entries matching the exact UUIDs or names
|
|
78
|
-
|
|
79
|
-
# Args:
|
|
80
|
-
# player_ids: Player UUIDs and/or names object
|
|
81
|
-
|
|
82
|
-
# Returns:
|
|
83
|
-
# None: Returns nothing
|
|
84
|
-
|
|
85
|
-
# Raises:
|
|
86
|
-
# FileNotFoundError: The 'whitelist.json' file not found
|
|
87
|
-
# """
|
|
88
|
-
# if not isinstance(player_ids, list):
|
|
89
|
-
# player_ids = [player_ids]
|
|
90
|
-
|
|
91
|
-
# player_uuids: set[PlayerUUID | None] = set()
|
|
92
|
-
# player_names: set[str | None] = set()
|
|
93
|
-
# for player_id in player_ids:
|
|
94
|
-
# if "player_uuid" in player_id:
|
|
95
|
-
# player_uuids.add(player_id["player_uuid"])
|
|
96
|
-
|
|
97
|
-
# if "player_name" in player_id:
|
|
98
|
-
# player_names.add(player_id["player_name"])
|
|
99
|
-
|
|
100
|
-
# if not whitelist_file.exists():
|
|
101
|
-
# raise FileNotFoundError(f"File '{whitelist_file}' is not found.")
|
|
102
|
-
|
|
103
|
-
# with open(whitelist_file, mode="r+") as file:
|
|
104
|
-
# whitelist_data: list[WhitelistFileEntry] = json.load(file)
|
|
105
|
-
# new_whitelist_data: list[WhitelistFileEntry] = []
|
|
106
|
-
# for player in whitelist_data:
|
|
107
|
-
# player_uuid = player["uuid"]
|
|
108
|
-
# player_name = player["name"]
|
|
109
|
-
|
|
110
|
-
# if player_uuid in player_uuids or player_name in player_names:
|
|
111
|
-
# log.debug(
|
|
112
|
-
# f"Removed player '{player_name}' ({player_uuid}) from the whitelisted player list"
|
|
113
|
-
# )
|
|
114
|
-
# continue
|
|
115
|
-
|
|
116
|
-
# new_whitelist_data.append(player)
|
|
117
|
-
|
|
118
|
-
# file.seek(0)
|
|
119
|
-
# json.dump(new_whitelist_data, file, indent=2)
|
|
120
|
-
# file.truncate()
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def list_players() -> list[WhitelistedPlayer]:
|
|
125
|
-
logger.debug(f"Reading whitelist file {whitelist_file_path}")
|
|
126
|
-
whitelist_json = whitelist_file_path.read_text()
|
|
127
|
-
whitelist_data: list[WhitelistedFilePlayer] = json.loads(whitelist_json)
|
|
128
|
-
|
|
129
|
-
whitelisted_players: list[WhitelistedPlayer] = []
|
|
130
|
-
for player in whitelist_data:
|
|
131
|
-
whitelisted_player: WhitelistedPlayer = {
|
|
132
|
-
"player_uuid": player["uuid"],
|
|
133
|
-
"player_name": player["name"],
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
whitelisted_players.append(whitelisted_player)
|
|
137
|
-
|
|
138
|
-
return whitelisted_players
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/apis/get_project_informations.py
RENAMED
|
File without changes
|
{mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/apis/get_project_versions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcserver_cli-4.3.0 → mcserver_cli-4.4.0}/src/mcserver/modrinth/typings/project_information.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|