Skip to content

Commit

Permalink
Update docs and fix issues with the ws closing
Browse files Browse the repository at this point in the history
  • Loading branch information
olijeffers0n committed Aug 7, 2024
1 parent 20b3e17 commit ee78d8f
Show file tree
Hide file tree
Showing 13 changed files with 60 additions and 63 deletions.
2 changes: 0 additions & 2 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@
* [Getting the Time](api-methods/getting-the-time.md)
* [Getting Entity Information](api-methods/getting-entity-information.md)
* [Getting Map Markers](api-methods/getting-map-markers.md)
* [Getting Current Map Events](api-methods/getting-current-map-events.md)
* [Getting Contents of Monitors](api-methods/getting-contents-of-monitors.md)
* [Promoting Players to Team Leader](api-methods/promoting-players-to-team-leader.md)
* [Toggling Smart Switches](api-methods/toggling-smart-switches.md)

## Command System

Expand Down
12 changes: 0 additions & 12 deletions docs/api-methods/getting-current-map-events.md

This file was deleted.

4 changes: 4 additions & 0 deletions docs/api-methods/getting-entity-information.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ Alarm = 2
StorageMonitor = 3
```

## Setting Entity Information

Calling `rust_socket.set_entity_value(entity_id: int, value: bool)` will set the value of the entity with the given ID to the given value.

16 changes: 14 additions & 2 deletions docs/api-methods/removing-listeners.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,21 @@

### Registered Listeners

A registered listener is a wrapper object around the coroutine itself that will allow the listener to be removed later on. Should you need the coroutine back, call `RegisteredListener.get_coro()`.
A registered listener is a wrapper object around the coroutine itself that will allow the listener to be removed later
on. Should you need the coroutine back, call `RegisteredListener.get_coro()`.

### Removing The listener

Removing a listener is as simple as calling `RustSocket.remove_listener(RegisteredListener)` and will return a boolean value. True if a listener was removed and false otherwise
Removing a listener is as simple as using an Event's HandlerList. This is one example:

```python
@EntityEvent(server_details, 25743493)
async def on_entity_event(payload: EntityEventPayload):
await rust_socket.set_entity_value(payload.entity_id, not payload.value)


EntityEventPayload.HANDLER_LIST.unregister(on_entity_event, server_details)

# You can also unregister all listeners for a specific event
EntityEventPayload.HANDLER_LIST.unregister_all()
```
8 changes: 0 additions & 8 deletions docs/api-methods/toggling-smart-switches.md

This file was deleted.

16 changes: 9 additions & 7 deletions docs/command-system/command-decorator.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
from main import server_details

# Command Decorator

The command decorator is used to mark a coroutine as a command listener. Usage:

```python
@rust_socket.command
async def hi(command: Command):
@Command(server_details)
async def hi(command: ChatCommand):
print("Command Ran!")
```

The fact that the coroutine's name is `hi` means that the command will be `<prefix>hi` .

You also get access to this `Command` object which has a slew of useful information about the how the command was called.
You also get access to this `ChatCommand` object which has a slew of useful information about the how the command was called.

| Field | Value |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
Expand All @@ -27,16 +29,16 @@ This decorator returns a [`RegisteredListener`](../api-methods/removing-listener
You don't want to have to register 100's of commands for every permutation of phrasing, so why should you!

```python
@rust_socket.command(aliases=["hello", "hey"])
async def hi(command: Command):
@ChatCommand(server_details, aliases=["hello", "hey"])
async def hi(command: ChatCommand):
print("Command Ran!")
```

This is a simple example of how you could incorporate different function names into one command, but sometimes we need more than that!

```python
@rust_socket.command(alais_func=lambda x: x.lower() == "test")
async def pair(command: Command):
@ChatCommand(server_details, alais_func=lambda x: x.lower() == "test")
async def pair(command: ChatCommand):
print("Command Ran!")
```

Expand Down
11 changes: 4 additions & 7 deletions docs/command-system/command-options.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
# Command Options

Command options are what you use to tell the [`RustSocket`](../getting-started/rustsocket/) what the general structure of your commands will be. These define the prefix for the command, as well as any "overruling commands" which are commands that do not require a prefix. Usage:
Command options are what you use to tell the [`RustSocket`](../getting-started/rustsocket/) what the general structure of your commands will be.
These define the prefix for the command, as well as any "overruling commands" which are commands that do not require a prefix. Usage:

```python
from rustplus import RustSocket
from rustplus import RustSocket, CommandOptions

options = CommandOptions(prefix="!", overruling_commands = ["time"])

# Prefix is a string, and the overruling_commands are a list of strings which would be the name of the coroutines
options = CommandOptions(prefix="!")
```

You can then just pass these into the RustSocket constructor using the `overruling_commands` kwarg.

9 changes: 5 additions & 4 deletions docs/command-system/commands-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ Commands allow the triggering of custom coroutines when a specific keyword is se

{% code title="main.py" %}
```python
from rustplus import RustSocket, CommandOptions, Command
from rustplus import RustSocket, CommandOptions, Command, ServerDetails, Command, ChatCommand

options = CommandOptions(prefix="!") # Use whatever prefix you want here
rust_socket = RustSocket("IP", "PORT", STEAMID, PLAYERTOKEN, command_options=options)
server_details = ServerDetails("IP", "PORT", STEAMID, PLAYERTOKEN)
socket = RustSocket(server_details)

@rust_socket.command
async def hi(command : Command):
@Command(server_details)
async def hi(command : ChatCommand):
await socket.send_team_message(f"Hi, {command.sender_name}")
```
{% endcode %}
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started/getting-player-details/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: This will show you how to get your personal player details using the RustCli
description: This will show you how to get your personal player details using the Web tool
---

# Getting Player Details
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ FCM(fcm_details).start()
```
{% endcode %}

The `on_notification` method will be called everytime a message is recieved from the game server.
The `on_notification` method will be called everytime a message is received from the game server.

The `rustplus.py.config.json` is the file created by the RustCli, when you register for FCM notifications. See:

Expand Down
7 changes: 4 additions & 3 deletions docs/getting-started/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ In order to access the API, you must first install the package using pip:
pip install rustplus
```

You must then get your Personal details using the RustCli, as shown here:
You must then get your Personal details using the web tool, as shown here:

{% content-ref url="getting-player-details/" %}
[getting-player-details](getting-player-details/)
Expand All @@ -15,10 +15,11 @@ You must then get your Personal details using the RustCli, as shown here:
{% code title="main.py" %}
```python
import asyncio
from rustplus import RustSocket
from rustplus import RustSocket, ServerDetails

async def main():
socket = RustSocket("IP", "PORT", STEAMID, PLAYERTOKEN)
server_details = ServerDetails("IP", "PORT", STEAMID, PLAYERTOKEN)
socket = RustSocket(server_details)
await socket.connect()

print(f"It is {(await socket.get_time()).time}")
Expand Down
21 changes: 8 additions & 13 deletions rustplus/remote/ratelimiter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,16 @@ def __init__(
self.refresh_per_second = self.refresh_amount / self.refresh_rate

def can_consume(self, amount) -> bool:
if (self.current - amount) >= 0:
return True

return False
return (self.current - amount) >= 0

def consume(self, amount: int = 1) -> None:
self.current -= amount

def refresh(self) -> None:
time_now = time.time()

time_delta = time_now - self.last_update
self.last_update = time_now

self.current = min([self.current + time_delta * self.refresh_amount, self.max])
self.current = min(self.current + time_delta * self.refresh_per_second, self.max)


class RateLimiter:
Expand Down Expand Up @@ -73,17 +68,14 @@ async def can_consume(self, server_details: ServerDetails, amount: int = 1) -> b
Returns whether the user can consume the amount of tokens provided
"""
async with self.lock:
can_consume = True

for bucket in [
self.socket_buckets.get(server_details),
self.server_buckets.get(server_details.get_server_string()),
]:
bucket.refresh()
if not bucket.can_consume(amount):
can_consume = False

return can_consume
return False
return True

async def consume(self, server_details: ServerDetails, amount: int = 1) -> None:
"""
Expand All @@ -96,8 +88,11 @@ async def consume(self, server_details: ServerDetails, amount: int = 1) -> None:
]:
bucket.refresh()
if not bucket.can_consume(amount):
self.lock.release()
raise RateLimitError("Not Enough Tokens")
for bucket in [
self.socket_buckets.get(server_details),
self.server_buckets.get(server_details.get_server_string()),
]:
bucket.consume(amount)

async def get_estimated_delay_time(
Expand Down
13 changes: 10 additions & 3 deletions rustplus/remote/websocket/ws.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import shlex
import base64
import betterproto
from websockets.exceptions import InvalidURI, InvalidHandshake
from websockets.exceptions import InvalidURI, InvalidHandshake, ConnectionClosedError
from websockets.legacy.client import WebSocketClientProtocol
from websockets.client import connect
from asyncio import TimeoutError, Task, AbstractEventLoop
Expand Down Expand Up @@ -110,9 +110,16 @@ async def run(self) -> None:
app_message = AppMessage()
app_message.parse(data)

except ConnectionClosedError as e:
if self.debug:
self.logger.exception("Connection Interrupted: %s", e)
else:
self.logger.warning("Connection Interrupted: %s", e)
break

except Exception as e:
self.logger.exception(
"An Error occurred whilst parsing the message from the server", e
"An Error occurred whilst parsing the message from the server: %s", e
)
continue

Expand Down Expand Up @@ -215,7 +222,7 @@ async def handle_message(self, app_message: AppMessage) -> None:
self.server_details
).get(str(app_message.broadcast.entity_changed.entity_id), [])
for handler in handlers:
handler.get_coro()(
await handler.get_coro()(
EntityEventPayload(
entity_changed=app_message.broadcast.entity_changed,
)
Expand Down

0 comments on commit ee78d8f

Please sign in to comment.