prc-client 1.1.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.
Files changed (46) hide show
  1. prc_client-1.1.0/.github/workflows/publish.yml +21 -0
  2. prc_client-1.1.0/.github/workflows/tests.yml +33 -0
  3. prc_client-1.1.0/.gitignore +7 -0
  4. prc_client-1.1.0/.python-version +1 -0
  5. prc_client-1.1.0/LICENSE +21 -0
  6. prc_client-1.1.0/PKG-INFO +221 -0
  7. prc_client-1.1.0/README.md +194 -0
  8. prc_client-1.1.0/examples/command_policy.py +20 -0
  9. prc_client-1.1.0/examples/events/fastapi_integration.py +23 -0
  10. prc_client-1.1.0/examples/events/router_usage.py +53 -0
  11. prc_client-1.1.0/examples/v2/get_server.py +10 -0
  12. prc_client-1.1.0/examples/v2/get_server_async.py +11 -0
  13. prc_client-1.1.0/examples/v2/send_command.py +17 -0
  14. prc_client-1.1.0/pyproject.toml +59 -0
  15. prc_client-1.1.0/src/prc/__init__.py +13 -0
  16. prc_client-1.1.0/src/prc/base_client.py +263 -0
  17. prc_client-1.1.0/src/prc/command.py +163 -0
  18. prc_client-1.1.0/src/prc/events/__init__.py +4 -0
  19. prc_client-1.1.0/src/prc/events/decorators.py +56 -0
  20. prc_client-1.1.0/src/prc/events/integrations/__init__.py +5 -0
  21. prc_client-1.1.0/src/prc/events/integrations/fastapi.py +24 -0
  22. prc_client-1.1.0/src/prc/events/integrations/quart.py +25 -0
  23. prc_client-1.1.0/src/prc/events/integrations/starlette.py +29 -0
  24. prc_client-1.1.0/src/prc/events/models.py +138 -0
  25. prc_client-1.1.0/src/prc/events/router.py +294 -0
  26. prc_client-1.1.0/src/prc/exceptions.py +73 -0
  27. prc_client-1.1.0/src/prc/policy.py +91 -0
  28. prc_client-1.1.0/src/prc/users.py +57 -0
  29. prc_client-1.1.0/src/prc/utils.py +107 -0
  30. prc_client-1.1.0/src/prc/v1/__init__.py +5 -0
  31. prc_client-1.1.0/src/prc/v1/client.py +61 -0
  32. prc_client-1.1.0/src/prc/v1/fetch.py +119 -0
  33. prc_client-1.1.0/src/prc/v1/models.py +263 -0
  34. prc_client-1.1.0/src/prc/v1/send_command.py +26 -0
  35. prc_client-1.1.0/src/prc/v2/__init__.py +5 -0
  36. prc_client-1.1.0/src/prc/v2/client.py +262 -0
  37. prc_client-1.1.0/src/prc/v2/models.py +502 -0
  38. prc_client-1.1.0/src/prc/v2/send_command.py +31 -0
  39. prc_client-1.1.0/src/prc/v2/server.py +105 -0
  40. prc_client-1.1.0/tests/conftest.py +3 -0
  41. prc_client-1.1.0/tests/events/test_router_decorators.py +159 -0
  42. prc_client-1.1.0/tests/test_command.py +24 -0
  43. prc_client-1.1.0/tests/test_policy.py +47 -0
  44. prc_client-1.1.0/tests/v1/test_v1_client.py +300 -0
  45. prc_client-1.1.0/tests/v2/test_client.py +174 -0
  46. prc_client-1.1.0/uv.lock +711 -0
@@ -0,0 +1,21 @@
1
+ name: Publish
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+
11
+ permissions:
12
+ id-token: write
13
+
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - uses: astral-sh/setup-uv@v6
18
+
19
+ - run: uv build
20
+
21
+ - run: uv publish
@@ -0,0 +1,33 @@
1
+ name: Run Tests
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.12", "3.13"]
15
+
16
+ steps:
17
+ - name: Check out code
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Setup UV
26
+ uses: astral-sh/setup-uv@v6
27
+
28
+ - name: Install dependencies
29
+ run: |
30
+ uv sync --all-extras --all-groups
31
+
32
+ - name: Run tests
33
+ run: uv run pytest
@@ -0,0 +1,7 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ .pytest_cache/
5
+ test.py
6
+ prc_client.egg-info/
7
+ dist/
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 garden-yardripper
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,221 @@
1
+ Metadata-Version: 2.4
2
+ Name: prc-client
3
+ Version: 1.1.0
4
+ Summary: A flexible, feature-rich API client for the ER:LC private server API.
5
+ Author-email: garden-yardripper <gardenyardripper@gmail.com>
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
+ Classifier: Typing :: Typed
14
+ Requires-Python: >=3.12
15
+ Requires-Dist: httpx>=0.28.1
16
+ Requires-Dist: pydantic>=2.13.4
17
+ Provides-Extra: events
18
+ Requires-Dist: cryptography>=49.0.0; extra == 'events'
19
+ Provides-Extra: fastapi
20
+ Requires-Dist: fastapi>=0.137.1; extra == 'fastapi'
21
+ Requires-Dist: starlette>=1.3.1; extra == 'fastapi'
22
+ Provides-Extra: quart
23
+ Requires-Dist: quart>=0.20.0; extra == 'quart'
24
+ Provides-Extra: starlette
25
+ Requires-Dist: starlette>=1.3.1; extra == 'starlette'
26
+ Description-Content-Type: text/markdown
27
+
28
+ # prc-client
29
+ `prc-client` is a flexible, feature-rich API client for the ER:LC private server API. This client provides a simple and intuitive interface for interacting with ER:LC private servers with detailed data models, typing, comprehensive error handling, and a high-performance architecture.
30
+
31
+ This library aims to provide all the functionality you need without overwhelming developers with unnecessary features or complexity. `prc-client` stays lightweight, allowing for full control over your development process - whether you're building a simple automation script to fully-featured complex application integrating with the PRC API.
32
+
33
+ # Key Features
34
+ - 100% coverage of all V1 and V2 API endpoints
35
+ - Full support for the event webhook API
36
+ - Support for both synchronous and asynchronous applications
37
+ - Automatic rate limit handling
38
+ - Intuitive developer interface allows for rapid prototyping and high development experience
39
+ - High performance - built on top of [HTTPX](https://github.com/encode/httpx) for HTTP requests and [Pydantic](https://github.com/samuelcolvin/pydantic) for data validation
40
+ - Detailed docstring documentation and examples
41
+ - Comprehensive error handling and logging
42
+
43
+ # Installation
44
+ Install `prc-client` using pip:
45
+
46
+ ```bash
47
+ pip install prc-client
48
+ ```
49
+
50
+ Optionally install additional dependencies:
51
+
52
+ ```bash
53
+ pip install prc-client[events,fastapi]
54
+ ```
55
+
56
+ # Quick Start
57
+ Import the `prc` module and create a client instance.
58
+
59
+ ```python
60
+ import prc
61
+
62
+ client = prc.v2.Client()
63
+ ```
64
+ <details>
65
+ <summary>Or asynchronously...</summary>
66
+
67
+ ```python
68
+ import prc
69
+
70
+ client = prc.v2.AsyncClient()
71
+ ```
72
+ </details>
73
+
74
+ Get a server with configurable parameters, or get a `BundledServer` with all available API data.
75
+
76
+ ```python
77
+ import prc
78
+
79
+ client = prc.v2.Client()
80
+
81
+ # Contains only the specified data
82
+ server = client.get_server(players=True, vehicles=True)
83
+ # Contains all available data
84
+ bundled_server = client.get_bundled_server()
85
+ ```
86
+
87
+ <details>
88
+ <summary>Or asynchronously...</summary>
89
+
90
+ ```python
91
+ import prc
92
+
93
+ async def main():
94
+ client = prc.v2.AsyncClient()
95
+
96
+ # Contains only the specified data
97
+ server = await client.get_server(players=True, vehicles=True)
98
+ # Contains all available data
99
+ bundled_server = await client.get_bundled_server()
100
+ ```
101
+ </details>
102
+
103
+ Send a command to the server using the `send_command` method and `cmd` factory to build commands.
104
+
105
+ ```python
106
+ import prc
107
+ from prc import cmd
108
+
109
+ client = prc.v2.Client()
110
+
111
+ # Contains only the specified data
112
+ server = client.get_server(players=True, vehicles=True)
113
+ # Contains all available data
114
+ bundled_server = client.get_bundled_server()
115
+
116
+ # Send a PM to all players
117
+ client.send_command(cmd.pm(server.players, "Welcome to the server!"))
118
+ ```
119
+
120
+ <details>
121
+ <summary>Or asynchronously...</summary>
122
+
123
+ ```python
124
+ import prc
125
+ from prc import cmd
126
+
127
+ async def main():
128
+ client = prc.v2.AsyncClient()
129
+
130
+ # Contains only the specified data
131
+ server = await client.get_server(players=True, vehicles=True)
132
+ # Contains all available data
133
+ bundled_server = await client.get_bundled_server()
134
+
135
+ # Send a PM to all players
136
+ await client.send_command(cmd.pm(server.players, "Welcome to the server!"))
137
+ ```
138
+ </details>
139
+
140
+ Let's set up a router with a simple command handler to receive requests from PRC.
141
+
142
+ ```python
143
+ import prc
144
+ from prc import cmd
145
+ from prc.events import Router, Context
146
+
147
+ client = prc.v2.Client()
148
+ # Create a router
149
+ router = Router(client)
150
+
151
+ # Define a command handler to run when the command ;myid / ;id / ;whoami is sent
152
+ @router.on.command("myid", "id", "whoami")
153
+ def handle_myid_command(ctx: Context):
154
+ ctx.reply(f"Your ID is: {ctx.user.id}")
155
+
156
+ # This command handler runs when any command is received
157
+ @router.on.any_command()
158
+ def handle_any_command(ctx: Context):
159
+ print(f"User {ctx.user.id} sent command '{ctx.command.command}' with arguments {ctx.command.arguments}")
160
+
161
+ # Contains only the specified data
162
+ server = client.get_server(players=True, vehicles=True)
163
+ # Contains all available data
164
+ bundled_server = client.get_bundled_server()
165
+
166
+ # Send a PM to all players
167
+ client.send_command(cmd.pm(server.players, "Welcome to the server!"))
168
+ ```
169
+
170
+ <details>
171
+ <summary>Or asynchronously...</summary>
172
+
173
+ ```python
174
+ import prc
175
+ from prc import cmd
176
+ from prc.events import Router, Context
177
+
178
+ client = prc.v2.AsyncClient()
179
+ # Create a router
180
+ router = Router(client)
181
+
182
+ # Define a command handler to run when the command ;myid / ;id / ;whoami is sent
183
+ @router.on.command("myid", "id", "whoami")
184
+ async def handle_myid_command(ctx: Context):
185
+ await ctx.areply(f"Your ID is: {ctx.user.id}")
186
+
187
+ # This command handler runs when any command is received
188
+ @router.on.any_command()
189
+ def handle_any_command(ctx: Context):
190
+ print(f"User {ctx.user.id} sent command '{ctx.command.command}' with arguments {ctx.command.arguments}")
191
+
192
+ async def main():
193
+ # Contains only the specified data
194
+ server = await client.get_server(players=True, vehicles=True)
195
+ # Contains all available data
196
+ bundled_server = await client.get_bundled_server()
197
+
198
+ # Send a PM to all players
199
+ await client.send_command(cmd.pm(server.players, "Welcome to the server!"))
200
+ ```
201
+
202
+ </details>
203
+
204
+ <details>
205
+ <summary>FastAPI application code</summary>
206
+
207
+ See the [FastAPI documentation](https://fastapi.tiangolo.com/) for more information on how to use FastAPI.
208
+
209
+ ```python
210
+ from fastapi import FastAPI, Request, Response, BackgroundTasks
211
+
212
+ app = FastAPI()
213
+
214
+ @app.post("/your/endpoint")
215
+ async def prc_webhook(request: Request, background_tasks: BackgroundTasks):
216
+ status = await router.handle_fastapi_request(request, background_tasks)
217
+ return Response(status_code=status)
218
+ ```
219
+ </details>
220
+
221
+ Check out the [examples](./examples) for more information on specific use cases.
@@ -0,0 +1,194 @@
1
+ # prc-client
2
+ `prc-client` is a flexible, feature-rich API client for the ER:LC private server API. This client provides a simple and intuitive interface for interacting with ER:LC private servers with detailed data models, typing, comprehensive error handling, and a high-performance architecture.
3
+
4
+ This library aims to provide all the functionality you need without overwhelming developers with unnecessary features or complexity. `prc-client` stays lightweight, allowing for full control over your development process - whether you're building a simple automation script to fully-featured complex application integrating with the PRC API.
5
+
6
+ # Key Features
7
+ - 100% coverage of all V1 and V2 API endpoints
8
+ - Full support for the event webhook API
9
+ - Support for both synchronous and asynchronous applications
10
+ - Automatic rate limit handling
11
+ - Intuitive developer interface allows for rapid prototyping and high development experience
12
+ - High performance - built on top of [HTTPX](https://github.com/encode/httpx) for HTTP requests and [Pydantic](https://github.com/samuelcolvin/pydantic) for data validation
13
+ - Detailed docstring documentation and examples
14
+ - Comprehensive error handling and logging
15
+
16
+ # Installation
17
+ Install `prc-client` using pip:
18
+
19
+ ```bash
20
+ pip install prc-client
21
+ ```
22
+
23
+ Optionally install additional dependencies:
24
+
25
+ ```bash
26
+ pip install prc-client[events,fastapi]
27
+ ```
28
+
29
+ # Quick Start
30
+ Import the `prc` module and create a client instance.
31
+
32
+ ```python
33
+ import prc
34
+
35
+ client = prc.v2.Client()
36
+ ```
37
+ <details>
38
+ <summary>Or asynchronously...</summary>
39
+
40
+ ```python
41
+ import prc
42
+
43
+ client = prc.v2.AsyncClient()
44
+ ```
45
+ </details>
46
+
47
+ Get a server with configurable parameters, or get a `BundledServer` with all available API data.
48
+
49
+ ```python
50
+ import prc
51
+
52
+ client = prc.v2.Client()
53
+
54
+ # Contains only the specified data
55
+ server = client.get_server(players=True, vehicles=True)
56
+ # Contains all available data
57
+ bundled_server = client.get_bundled_server()
58
+ ```
59
+
60
+ <details>
61
+ <summary>Or asynchronously...</summary>
62
+
63
+ ```python
64
+ import prc
65
+
66
+ async def main():
67
+ client = prc.v2.AsyncClient()
68
+
69
+ # Contains only the specified data
70
+ server = await client.get_server(players=True, vehicles=True)
71
+ # Contains all available data
72
+ bundled_server = await client.get_bundled_server()
73
+ ```
74
+ </details>
75
+
76
+ Send a command to the server using the `send_command` method and `cmd` factory to build commands.
77
+
78
+ ```python
79
+ import prc
80
+ from prc import cmd
81
+
82
+ client = prc.v2.Client()
83
+
84
+ # Contains only the specified data
85
+ server = client.get_server(players=True, vehicles=True)
86
+ # Contains all available data
87
+ bundled_server = client.get_bundled_server()
88
+
89
+ # Send a PM to all players
90
+ client.send_command(cmd.pm(server.players, "Welcome to the server!"))
91
+ ```
92
+
93
+ <details>
94
+ <summary>Or asynchronously...</summary>
95
+
96
+ ```python
97
+ import prc
98
+ from prc import cmd
99
+
100
+ async def main():
101
+ client = prc.v2.AsyncClient()
102
+
103
+ # Contains only the specified data
104
+ server = await client.get_server(players=True, vehicles=True)
105
+ # Contains all available data
106
+ bundled_server = await client.get_bundled_server()
107
+
108
+ # Send a PM to all players
109
+ await client.send_command(cmd.pm(server.players, "Welcome to the server!"))
110
+ ```
111
+ </details>
112
+
113
+ Let's set up a router with a simple command handler to receive requests from PRC.
114
+
115
+ ```python
116
+ import prc
117
+ from prc import cmd
118
+ from prc.events import Router, Context
119
+
120
+ client = prc.v2.Client()
121
+ # Create a router
122
+ router = Router(client)
123
+
124
+ # Define a command handler to run when the command ;myid / ;id / ;whoami is sent
125
+ @router.on.command("myid", "id", "whoami")
126
+ def handle_myid_command(ctx: Context):
127
+ ctx.reply(f"Your ID is: {ctx.user.id}")
128
+
129
+ # This command handler runs when any command is received
130
+ @router.on.any_command()
131
+ def handle_any_command(ctx: Context):
132
+ print(f"User {ctx.user.id} sent command '{ctx.command.command}' with arguments {ctx.command.arguments}")
133
+
134
+ # Contains only the specified data
135
+ server = client.get_server(players=True, vehicles=True)
136
+ # Contains all available data
137
+ bundled_server = client.get_bundled_server()
138
+
139
+ # Send a PM to all players
140
+ client.send_command(cmd.pm(server.players, "Welcome to the server!"))
141
+ ```
142
+
143
+ <details>
144
+ <summary>Or asynchronously...</summary>
145
+
146
+ ```python
147
+ import prc
148
+ from prc import cmd
149
+ from prc.events import Router, Context
150
+
151
+ client = prc.v2.AsyncClient()
152
+ # Create a router
153
+ router = Router(client)
154
+
155
+ # Define a command handler to run when the command ;myid / ;id / ;whoami is sent
156
+ @router.on.command("myid", "id", "whoami")
157
+ async def handle_myid_command(ctx: Context):
158
+ await ctx.areply(f"Your ID is: {ctx.user.id}")
159
+
160
+ # This command handler runs when any command is received
161
+ @router.on.any_command()
162
+ def handle_any_command(ctx: Context):
163
+ print(f"User {ctx.user.id} sent command '{ctx.command.command}' with arguments {ctx.command.arguments}")
164
+
165
+ async def main():
166
+ # Contains only the specified data
167
+ server = await client.get_server(players=True, vehicles=True)
168
+ # Contains all available data
169
+ bundled_server = await client.get_bundled_server()
170
+
171
+ # Send a PM to all players
172
+ await client.send_command(cmd.pm(server.players, "Welcome to the server!"))
173
+ ```
174
+
175
+ </details>
176
+
177
+ <details>
178
+ <summary>FastAPI application code</summary>
179
+
180
+ See the [FastAPI documentation](https://fastapi.tiangolo.com/) for more information on how to use FastAPI.
181
+
182
+ ```python
183
+ from fastapi import FastAPI, Request, Response, BackgroundTasks
184
+
185
+ app = FastAPI()
186
+
187
+ @app.post("/your/endpoint")
188
+ async def prc_webhook(request: Request, background_tasks: BackgroundTasks):
189
+ status = await router.handle_fastapi_request(request, background_tasks)
190
+ return Response(status_code=status)
191
+ ```
192
+ </details>
193
+
194
+ Check out the [examples](./examples) for more information on specific use cases.
@@ -0,0 +1,20 @@
1
+ import prc
2
+ from prc import cmd
3
+ from prc.policy import CommandPolicy
4
+
5
+ # Only allow hint and message commands
6
+ # Blacklist set takes priority over whitelist
7
+ policy = CommandPolicy(whitelist={"h", "hint", "m", "message"}, blacklist={"kick"})
8
+
9
+ with prc.v2.Client(server_key="...", policy=policy) as client:
10
+ hint_preview = policy.preview_command(cmd.h("Hello World!"))
11
+ wanted_preview = policy.preview_command(cmd.wanted("Alice"))
12
+
13
+ if hint_preview.allowed:
14
+ client.send_command(hint_preview.command)
15
+
16
+ if wanted_preview.allowed:
17
+ # This will not run
18
+ client.send_command(wanted_preview.command)
19
+ else:
20
+ print("Command disallowed! Reason:", wanted_preview.reason)
@@ -0,0 +1,23 @@
1
+ from fastapi import FastAPI, BackgroundTasks, Request, Response
2
+
3
+ import prc
4
+ from prc.events import Router, Context
5
+
6
+ client = prc.v2.AsyncClient(server_key="...")
7
+ router = Router(client)
8
+
9
+ @router.on.command("say")
10
+ async def handle_say_command(ctx: Context[prc.v2.AsyncClient]):
11
+ player = await ctx.client.get_player_from_user(ctx.user.id)
12
+ await ctx.areply(f"Hello, {player.user.name}! You said: {ctx.command.argument}")
13
+
14
+ # Basic FastAPI application to receive requests from PRC
15
+ app = FastAPI()
16
+
17
+ @app.post("/prc/webhook")
18
+ async def prc_webhook(request: Request, background_tasks: BackgroundTasks):
19
+ # Handle the incoming request using the handle_fastapi_request method,
20
+ # which will handle all dispatching and background task scheduling for us
21
+ # and immediately return the appropriate HTTP status code.
22
+ status = await router.handle_fastapi_request(request, background_tasks)
23
+ return Response(status_code=status)
@@ -0,0 +1,53 @@
1
+ from fastapi import FastAPI, Request, Response, BackgroundTasks
2
+
3
+ import prc
4
+ from prc import cmd
5
+ from prc.events import Router, Context
6
+
7
+ client = prc.v2.AsyncClient(server_key="...")
8
+
9
+ # No need to send sync handlers to a thread in this example
10
+ # because our sync handlers don't do any blocking operations,
11
+ # which will give better performance.
12
+ router = Router(client, sync_handlers_to_thread=False)
13
+
14
+ # You can assign multiple commands to the same handler
15
+ # by passing them as additional arguments to the decorator
16
+ @router.on.command("myid", "id", "whoami")
17
+ async def handle_myid_command(ctx: Context):
18
+ # This handler will send the command user a PM when they run the command ';myid' in-game
19
+ await ctx.areply(f"Your user ID is {ctx.user.id}.")
20
+
21
+ @router.on.emergency_start()
22
+ async def handle_emergency_start(ctx: Context[prc.v2.AsyncClient]):
23
+ # This handler will check if the caller of an emergency call is on the Police or Sheriff team,
24
+ # and if so, will PM them and then wanted off the team
25
+ player = await ctx.client.get_player_from_user(ctx.emergency_call.caller)
26
+
27
+ if player.team in ("Police", "Sheriff"):
28
+ await ctx.client.send_command(cmd.pm(player,
29
+ "You cannot make emergency calls while on this team! You will be wanted off the team shortly."
30
+ ))
31
+ await ctx.client.send_command(cmd.wanted(player))
32
+
33
+ @router.on.any_event()
34
+ def handle_any_event(ctx: Context):
35
+ # This handler will be called for any non-command event
36
+ print(f"Received event of type {ctx.event_type}.")
37
+
38
+ @router.on.any_custom_command()
39
+ def log_command_usage(ctx: Context):
40
+ # This handler will log the usage of any custom command to the console
41
+ # Replace with a proper logging statement in a production application
42
+ print(f"User {ctx.user.id} executed command '{ctx.command.command}' with argument '{ctx.command.argument}'.")
43
+
44
+ # Basic FastAPI application to receive requests from PRC
45
+ app = FastAPI()
46
+
47
+ @app.post("/prc/webhook")
48
+ async def prc_webhook(request: Request, background_tasks: BackgroundTasks):
49
+ # Handle the incoming request using the handle_fastapi_request method,
50
+ # which will handle all dispatching and background task scheduling for us
51
+ # and immediately return the appropriate HTTP status code.
52
+ status = await router.handle_fastapi_request(request, background_tasks)
53
+ return Response(status_code=status)
@@ -0,0 +1,10 @@
1
+ import prc
2
+
3
+ def main():
4
+ with prc.v2.Client(server_key="...") as client:
5
+ server = client.get_bundled_server()
6
+ for player in server.players:
7
+ print(f"{player.user.name} is on the {player.team} team!")
8
+
9
+ if __name__ == "__main__":
10
+ main()
@@ -0,0 +1,11 @@
1
+ import prc
2
+ import asyncio
3
+
4
+ async def main():
5
+ async with prc.v2.AsyncClient(server_key="...") as client:
6
+ server = await client.get_bundled_server()
7
+ for player in server.players:
8
+ print(f"{player.user.name} is on the {player.team} team!")
9
+
10
+ if __name__ == "__main__":
11
+ asyncio.run(main())
@@ -0,0 +1,17 @@
1
+ import prc
2
+ from prc import cmd
3
+
4
+ with prc.v2.Client(server_key="...") as client:
5
+ server = client.get_server(players=True)
6
+
7
+ # Get players whose names start with 'all' or 'others'
8
+ players_to_kick = [
9
+ player for player in server.players
10
+ if player.user.name.lower().startswith(("all", "others"))
11
+ ]
12
+
13
+ # Kick the players from the server
14
+ client.send_command(cmd.kick(players_to_kick, "Username starts with 'all' or 'others'."))
15
+
16
+ # Alternatively:
17
+ # cmd.kick(players_to_kick, "Username starts with 'all' or 'others'.").send(client)