From d555f369edb414992bd6ba8c94002fe46fbdb917 Mon Sep 17 00:00:00 2001 From: Ollie <69084614+olijeffers0n@users.noreply.github.com> Date: Mon, 24 Apr 2023 19:07:36 +0100 Subject: [PATCH] Revert "Format code with black" This reverts commit 34ec24de21203677792f3230a4ffc8bfe385d007. --- rustplus/__init__.py | 19 +++--- rustplus/api/base_rust_api.py | 34 ++++++---- rustplus/api/remote/__init__.py | 10 +-- rustplus/api/remote/camera/__init__.py | 2 +- rustplus/api/remote/camera/camera_manager.py | 16 +++-- rustplus/api/remote/camera/camera_parser.py | 22 +++++-- rustplus/api/remote/camera/structures.py | 2 +- rustplus/api/remote/events/__init__.py | 7 +-- rustplus/api/remote/events/event_handler.py | 12 ++-- .../api/remote/events/event_loop_manager.py | 1 + rustplus/api/remote/events/events.py | 10 ++- rustplus/api/remote/events/handler_list.py | 6 +- .../api/remote/events/map_event_listener.py | 4 ++ .../api/remote/events/registered_listener.py | 1 + rustplus/api/remote/expo_bundle_handler.py | 6 +- rustplus/api/remote/fcm_listener.py | 4 +- rustplus/api/remote/heartbeat.py | 7 +++ rustplus/api/remote/ratelimiter.py | 3 +- rustplus/api/remote/rust_remote_interface.py | 38 +++++++---- rustplus/api/remote/rustws.py | 19 ++++-- rustplus/api/remote/server_checker.py | 5 +- rustplus/api/rust_api.py | 63 ++++++++++++++----- rustplus/api/structures/__init__.py | 10 +-- rustplus/api/structures/rust_marker.py | 3 +- rustplus/api/structures/rust_team_info.py | 3 +- rustplus/api/structures/util.py | 1 + rustplus/commands/__init__.py | 2 +- rustplus/commands/command_handler.py | 8 ++- rustplus/commands/command_options.py | 1 + rustplus/conversation/__init__.py | 2 +- rustplus/conversation/conversation.py | 4 +- rustplus/conversation/conversation_factory.py | 1 + rustplus/exceptions/__init__.py | 17 +++-- rustplus/exceptions/exceptions.py | 11 ++++ rustplus/utils/__init__.py | 2 +- rustplus/utils/deprecated.py | 1 + rustplus/utils/grab_items.py | 2 +- rustplus/utils/rust_utils.py | 5 +- setup.py | 20 +++--- 39 files changed, 256 insertions(+), 128 deletions(-) diff --git a/rustplus/__init__.py b/rustplus/__init__.py index 214c9c9..dbee633 100644 --- a/rustplus/__init__.py +++ b/rustplus/__init__.py @@ -3,16 +3,21 @@ """ from .api import RustSocket -from .api.remote.camera import (CameraManager, CameraMovementOptions, - MovementControls) -from .api.remote.events import (ChatEvent, EntityEvent, MarkerEvent, - ProtobufEvent, RegisteredListener, TeamEvent) +from .api.remote.events import ( + EntityEvent, + TeamEvent, + ChatEvent, + MarkerEvent, + ProtobufEvent, + RegisteredListener, +) +from .api.structures import RustMarker, Vector from .api.remote.fcm_listener import FCMListener from .api.remote.ratelimiter import RateLimiter -from .api.structures import RustMarker, Vector -from .commands import Command, CommandOptions -from .conversation import Conversation, ConversationFactory, ConversationPrompt +from .api.remote.camera import CameraManager, MovementControls, CameraMovementOptions +from .commands import CommandOptions, Command from .exceptions import * +from .conversation import ConversationFactory, Conversation, ConversationPrompt from .utils import * __name__ = "rustplus" diff --git a/rustplus/api/base_rust_api.py b/rustplus/api/base_rust_api.py index e1866cc..8bdd120 100644 --- a/rustplus/api/base_rust_api.py +++ b/rustplus/api/base_rust_api.py @@ -1,21 +1,25 @@ import asyncio -from typing import Callable, List, Union - +from typing import List, Callable, Union from PIL import Image -from ..commands import CommandHandler, CommandOptions -from ..commands.command_data import CommandData -from ..conversation import ConversationFactory -from ..exceptions import * -from ..utils import ServerID, deprecated -from .remote import (HeartBeat, MapEventListener, RateLimiter, RustRemote, - ServerChecker) -from .remote.camera import CameraManager -from .remote.events import (ChatEvent, EntityEvent, ProtobufEvent, - RegisteredListener, TeamEvent) from .remote.events.event_loop_manager import EventLoopManager -from .remote.rustplus_proto import AppEmpty, AppRequest from .structures import * +from .remote.rustplus_proto import AppEmpty, AppRequest +from .remote import RustRemote, HeartBeat, MapEventListener, ServerChecker, RateLimiter +from .remote.camera import CameraManager +from ..commands import CommandOptions, CommandHandler +from ..commands.command_data import CommandData +from ..exceptions import * +from .remote.events import ( + RegisteredListener, + EntityEvent, + TeamEvent, + ChatEvent, + ProtobufEvent, +) +from ..utils import deprecated +from ..conversation import ConversationFactory +from ..utils import ServerID class BaseRustSocket: @@ -35,6 +39,7 @@ def __init__( event_loop: asyncio.AbstractEventLoop = None, rate_limiter: RateLimiter = None, ) -> None: + if ip is None: raise ValueError("Ip cannot be None") if steam_id is None: @@ -75,6 +80,7 @@ async def _handle_ratelimit(self, amount=1) -> None: :return: None """ while True: + if self.remote.ratelimiter.can_consume(self.server_id, amount): self.remote.ratelimiter.consume(self.server_id, amount) break @@ -278,6 +284,7 @@ def command( return RegisteredListener(coro.__name__, cmd_data.coro) def wrap_func(coro): + if self.command_options is None: raise CommandsNotEnabledError("Not enabled") @@ -334,6 +341,7 @@ def entity_event(self, eid): """ def wrap_func(coro) -> RegisteredListener: + if isinstance(coro, RegisteredListener): coro = coro.get_coro() diff --git a/rustplus/api/remote/__init__.py b/rustplus/api/remote/__init__.py index d6fe77e..3a622b8 100644 --- a/rustplus/api/remote/__init__.py +++ b/rustplus/api/remote/__init__.py @@ -1,8 +1,8 @@ -from ..remote.events.event_handler import EventHandler -from ..remote.events.map_event_listener import MapEventListener -from .heartbeat import HeartBeat -from .ratelimiter import RateLimiter -from .rust_remote_interface import RustRemote from .rustplus_proto import * from .rustws import RustWebsocket +from .ratelimiter import RateLimiter +from .rust_remote_interface import RustRemote +from .heartbeat import HeartBeat from .server_checker import ServerChecker +from ..remote.events.event_handler import EventHandler +from ..remote.events.map_event_listener import MapEventListener diff --git a/rustplus/api/remote/camera/__init__.py b/rustplus/api/remote/camera/__init__.py index 605ee53..b39ec70 100644 --- a/rustplus/api/remote/camera/__init__.py +++ b/rustplus/api/remote/camera/__init__.py @@ -1,3 +1,3 @@ -from .camera_constants import CameraMovementOptions, MovementControls from .camera_manager import CameraManager +from .camera_constants import CameraMovementOptions, MovementControls from .structures import CameraInfo diff --git a/rustplus/api/remote/camera/camera_manager.py b/rustplus/api/remote/camera/camera_manager.py index 832fb8f..265cf1a 100644 --- a/rustplus/api/remote/camera/camera_manager.py +++ b/rustplus/api/remote/camera/camera_manager.py @@ -1,13 +1,18 @@ import time -from typing import Coroutine, Iterable, List, Set, TypeVar, Union +from typing import Iterable, Union, List, Coroutine, TypeVar, Set from PIL import Image -from ...structures import Vector -from ..events import EventHandler, EventLoopManager -from ..rustplus_proto import (AppCameraInfo, AppCameraInput, AppEmpty, - AppRequest, Vector2) from .camera_parser import Parser +from ..events import EventLoopManager, EventHandler +from ..rustplus_proto import ( + AppCameraInput, + Vector2, + AppEmpty, + AppRequest, + AppCameraInfo, +) +from ...structures import Vector from .structures import CameraInfo, Entity, LimitedQueue RS = TypeVar("RS", bound="RustSocket") @@ -110,6 +115,7 @@ async def send_mouse_movement(self, mouse_delta: Vector) -> None: async def send_combined_movement( self, movements: Iterable[int] = None, joystick_vector: Vector = None ) -> None: + if joystick_vector is None: joystick_vector = Vector() diff --git a/rustplus/api/remote/camera/camera_parser.py b/rustplus/api/remote/camera/camera_parser.py index dec901d..ea353aa 100644 --- a/rustplus/api/remote/camera/camera_parser.py +++ b/rustplus/api/remote/camera/camera_parser.py @@ -1,12 +1,11 @@ import math -import random from importlib import resources from math import radians, tan -from typing import Any, Dict, List, Tuple, Union - +import random +from typing import Union, Tuple, List, Any, Dict import numpy as np -from PIL import Image, ImageDraw, ImageFont from scipy.spatial import ConvexHull +from PIL import Image, ImageDraw, ImageFont from .camera_constants import LOOKUP_CONSTANTS from .structures import Entity, Vector3 @@ -55,6 +54,7 @@ def reset_output(self) -> None: ) def handle_camera_ray_data(self, data) -> None: + if data is None: return @@ -66,6 +66,7 @@ def handle_camera_ray_data(self, data) -> None: self._ray_lookback = [[0 for _ in range(3)] for _ in range(64)] def step(self) -> None: + if self._rays is None: return @@ -79,6 +80,7 @@ def process_rays_batch(self) -> bool: return True for h in range(100): + if self.data_pointer >= len(self._rays.ray_data) - 1: return True @@ -105,6 +107,7 @@ def process_rays_batch(self) -> bool: not (distance == 1 and alignment == 0 and material == 0) and material != 7 ): + self.colour_output[ x : x + self.scale_factor, y : y + self.scale_factor ] = MathUtils._convert_colour( @@ -150,6 +153,7 @@ def next_ray(self, ray_data) -> List[Union[float, int]]: self._ray_lookback[u][2] = i else: + c = 192 & byte if c == 0: @@ -213,6 +217,7 @@ def handle_entities( entity_render_distance: float, max_entity_amount: int, ) -> Any: + image_data = np.array(image_data) players = [player for player in entities if player.type == 2] @@ -260,6 +265,7 @@ def handle_entities( text = set() for entity in entities: + if entity.position.z > entity_render_distance and entity.type == 1: continue @@ -301,6 +307,7 @@ def handle_entity( aspect_ratio, text, ) -> None: + entity.size.x = min(entity.size.x, 5) entity.size.y = min(entity.size.y, 5) entity.size.z = min(entity.size.z, 5) @@ -411,6 +418,7 @@ def render( entity_render_distance: float, max_entity_amount: int, ) -> Image.Image: + # We have the output array filled with RayData objects # We can get the material at each pixel and use that to get the colour # We can then use the alignment to get the alpha value @@ -548,6 +556,7 @@ def _convert_colour( cls, colour: Tuple[float, float, float, float], ) -> Tuple[int, int, int]: + if colour in cls.COLOUR_CACHE: return cls.COLOUR_CACHE[colour] @@ -580,6 +589,7 @@ def solve_quadratic(a: float, b: float, c: float, larger: bool) -> float: @classmethod def get_tree_vertices(cls, size) -> np.ndarray: + if size in cls.VERTEX_CACHE: return cls.VERTEX_CACHE[size] @@ -589,6 +599,7 @@ def get_tree_vertices(cls, size) -> np.ndarray: vertex_list = [] for x_value in [size.y / 8, -size.y / 8]: + for i in range(number_of_segments): angle = segment_angle * i @@ -605,6 +616,7 @@ def get_tree_vertices(cls, size) -> np.ndarray: @classmethod def get_player_vertices(cls, size) -> np.ndarray: + if size in cls.VERTEX_CACHE: return cls.VERTEX_CACHE[size] @@ -621,7 +633,9 @@ def get_player_vertices(cls, size) -> np.ndarray: x = 0 while x <= width: + for offset in range(-1, 2, 2): + x_value = x * offset # Use the quadratic formula to find the y values of the top and bottom of the pill diff --git a/rustplus/api/remote/camera/structures.py b/rustplus/api/remote/camera/structures.py index 2af1282..a04034c 100644 --- a/rustplus/api/remote/camera/structures.py +++ b/rustplus/api/remote/camera/structures.py @@ -1,6 +1,6 @@ from typing import Any -from ..rustplus_proto import AppCameraInfo, AppCameraRays, AppCameraRaysEntity +from ..rustplus_proto import AppCameraInfo, AppCameraRaysEntity, AppCameraRays class CameraInfo: diff --git a/rustplus/api/remote/events/__init__.py b/rustplus/api/remote/events/__init__.py index 77d4db5..e303ed1 100644 --- a/rustplus/api/remote/events/__init__.py +++ b/rustplus/api/remote/events/__init__.py @@ -1,5 +1,4 @@ -from .event_handler import EventHandler -from .event_loop_manager import EventLoopManager -from .events import (ChatEvent, EntityEvent, MarkerEvent, ProtobufEvent, - TeamEvent) from .registered_listener import RegisteredListener +from .events import EntityEvent, TeamEvent, ChatEvent, MarkerEvent, ProtobufEvent +from .event_loop_manager import EventLoopManager +from .event_handler import EventHandler diff --git a/rustplus/api/remote/events/event_handler.py b/rustplus/api/remote/events/event_handler.py index 7765623..1088437 100644 --- a/rustplus/api/remote/events/event_handler.py +++ b/rustplus/api/remote/events/event_handler.py @@ -1,13 +1,13 @@ import asyncio import logging from asyncio.futures import Future -from typing import Any, Coroutine, Set +from typing import Set, Coroutine, Any from ....utils import ServerID -from ..rustplus_proto import AppMessage -from .event_loop_manager import EventLoopManager -from .events import ChatEvent, EntityEvent, ProtobufEvent, TeamEvent +from .events import EntityEvent, TeamEvent, ChatEvent, ProtobufEvent from .registered_listener import RegisteredListener +from .event_loop_manager import EventLoopManager +from ..rustplus_proto import AppMessage class EventHandler: @@ -25,6 +25,7 @@ def callback(inner_future: Future): def run_entity_event( self, name: str, app_message: AppMessage, server_id: ServerID ) -> None: + handlers: Set[RegisteredListener] = EntityEvent.handlers.get_handlers( server_id ).get(str(name)) @@ -42,6 +43,7 @@ def run_entity_event( ) def run_team_event(self, app_message: AppMessage, server_id: ServerID) -> None: + handlers: Set[RegisteredListener] = TeamEvent.handlers.get_handlers(server_id) for handler in handlers.copy(): coro = handler.data @@ -51,6 +53,7 @@ def run_team_event(self, app_message: AppMessage, server_id: ServerID) -> None: ) def run_chat_event(self, app_message: AppMessage, server_id: ServerID) -> None: + handlers: Set[RegisteredListener] = ChatEvent.handlers.get_handlers(server_id) for handler in handlers.copy(): coro = handler.data @@ -60,6 +63,7 @@ def run_chat_event(self, app_message: AppMessage, server_id: ServerID) -> None: ) def run_proto_event(self, byte_data: bytes, server_id: ServerID) -> None: + handlers: Set[RegisteredListener] = ProtobufEvent.handlers.get_handlers( server_id ) diff --git a/rustplus/api/remote/events/event_loop_manager.py b/rustplus/api/remote/events/event_loop_manager.py index 16392cd..63e3cb1 100644 --- a/rustplus/api/remote/events/event_loop_manager.py +++ b/rustplus/api/remote/events/event_loop_manager.py @@ -5,6 +5,7 @@ class EventLoopManager: + _loop: Dict[ServerID, asyncio.AbstractEventLoop] = {} @staticmethod diff --git a/rustplus/api/remote/events/events.py b/rustplus/api/remote/events/events.py index 2d96d8e..76b4052 100644 --- a/rustplus/api/remote/events/events.py +++ b/rustplus/api/remote/events/events.py @@ -1,10 +1,10 @@ from typing import List +from ..rustplus_proto import AppMessage, AppEntityPayloadItem from ...structures import RustChatMessage -from ...structures.rust_marker import RustMarker from ...structures.rust_team_info import RustTeamInfo -from ..rustplus_proto import AppEntityPayloadItem, AppMessage -from .handler_list import EntityHandlerList, HandlerList +from ...structures.rust_marker import RustMarker +from .handler_list import HandlerList, EntityHandlerList class Item: @@ -27,6 +27,7 @@ def item_is_blueprint(self) -> bool: class TeamEvent: + handlers = HandlerList() def __init__(self, app_message: AppMessage) -> None: @@ -43,6 +44,7 @@ def team_info(self) -> RustTeamInfo: class ChatEvent: + handlers = HandlerList() def __init__(self, app_message: AppMessage) -> None: @@ -54,6 +56,7 @@ def message(self) -> RustChatMessage: class EntityEvent: + handlers = EntityHandlerList() def __init__(self, app_message: AppMessage, entity_type) -> None: @@ -116,6 +119,7 @@ def is_new(self) -> bool: class ProtobufEvent: + handlers = HandlerList() def __init__(self, byte_data) -> None: diff --git a/rustplus/api/remote/events/handler_list.py b/rustplus/api/remote/events/handler_list.py index c6b5ce7..dfd9257 100644 --- a/rustplus/api/remote/events/handler_list.py +++ b/rustplus/api/remote/events/handler_list.py @@ -1,8 +1,7 @@ from collections import defaultdict -from typing import Dict, Set - -from ....utils import ServerID +from typing import Set, Dict from .registered_listener import RegisteredListener +from ....utils import ServerID class HandlerList: @@ -38,6 +37,7 @@ def unregister(self, listener: RegisteredListener, server_id: ServerID) -> None: self._handlers.get(server_id).get(listener.listener_id).remove(listener) def register(self, listener: RegisteredListener, server_id: ServerID) -> None: + if server_id not in self._handlers: self._handlers[server_id] = defaultdict(set) diff --git a/rustplus/api/remote/events/map_event_listener.py b/rustplus/api/remote/events/map_event_listener.py index 412ff52..5166c5d 100644 --- a/rustplus/api/remote/events/map_event_listener.py +++ b/rustplus/api/remote/events/map_event_listener.py @@ -36,14 +36,18 @@ def start(self, delay) -> None: self.gc.start() def _run(self) -> None: + while True: + try: + future = asyncio.run_coroutine_threadsafe( self.api.get_markers(), EventLoopManager.get_loop(self.api.server_id), ) new_highest_id = 0 for marker in future.result(): + new = False if marker.id in self.persistent_ids: diff --git a/rustplus/api/remote/events/registered_listener.py b/rustplus/api/remote/events/registered_listener.py index a0c83a5..8e7ce17 100644 --- a/rustplus/api/remote/events/registered_listener.py +++ b/rustplus/api/remote/events/registered_listener.py @@ -10,6 +10,7 @@ def get_coro(self): def __eq__(self, other) -> bool: if isinstance(other, RegisteredListener): + coro = self.data if isinstance(self.data, tuple): coro = self.data[0] diff --git a/rustplus/api/remote/expo_bundle_handler.py b/rustplus/api/remote/expo_bundle_handler.py index f8d2f7a..0eac80d 100644 --- a/rustplus/api/remote/expo_bundle_handler.py +++ b/rustplus/api/remote/expo_bundle_handler.py @@ -1,13 +1,13 @@ -import json +import requests import logging +import json from datetime import datetime -import requests - class MagicValueGrabber: @staticmethod def get_magic_value() -> int: + try: data = requests.get( "https://exp.host/@facepunch/RustCompanion", diff --git a/rustplus/api/remote/fcm_listener.py b/rustplus/api/remote/fcm_listener.py index 1c7c7fa..dcded55 100644 --- a/rustplus/api/remote/fcm_listener.py +++ b/rustplus/api/remote/fcm_listener.py @@ -1,6 +1,5 @@ -from threading import Thread - from push_receiver import PushReceiver +from threading import Thread class FCMListener: @@ -16,6 +15,7 @@ def start(self, daemon=False) -> None: self.thread = Thread(target=self.__fcm_listen, daemon=daemon).start() def __fcm_listen(self) -> None: + if self.data is None: raise ValueError("Data is None") diff --git a/rustplus/api/remote/heartbeat.py b/rustplus/api/remote/heartbeat.py index bedf410..9e3118c 100644 --- a/rustplus/api/remote/heartbeat.py +++ b/rustplus/api/remote/heartbeat.py @@ -4,11 +4,13 @@ class HeartBeat: def __init__(self, rust_api) -> None: + self.rust_api = rust_api self.next_run = time.time() self.running = False async def start_beat(self) -> None: + if self.running: return @@ -17,16 +19,21 @@ async def start_beat(self) -> None: asyncio.create_task(self._heart_beat()) async def _heart_beat(self) -> None: + while True: + if time.time() >= self.next_run: + await self.beat() else: await asyncio.sleep(1) async def beat(self) -> None: + if self.rust_api.remote.ws is not None and self.rust_api.remote.is_open(): await self.rust_api.send_wakeup_request() def reset_rhythm(self) -> None: + self.next_run = time.time() + 240 diff --git a/rustplus/api/remote/ratelimiter.py b/rustplus/api/remote/ratelimiter.py index 25cbe19..9d28ff6 100644 --- a/rustplus/api/remote/ratelimiter.py +++ b/rustplus/api/remote/ratelimiter.py @@ -1,6 +1,6 @@ import math -import threading import time +import threading from typing import Dict from ...exceptions.exceptions import RateLimitError @@ -37,6 +37,7 @@ def refresh(self) -> None: class RateLimiter: + SERVER_LIMIT = 50 SERVER_REFRESH_AMOUNT = 15 diff --git a/rustplus/api/remote/rust_remote_interface.py b/rustplus/api/remote/rust_remote_interface.py index 86da9ae..7dd972b 100644 --- a/rustplus/api/remote/rust_remote_interface.py +++ b/rustplus/api/remote/rust_remote_interface.py @@ -1,21 +1,22 @@ import asyncio import logging from asyncio import Future - -from ...commands import CommandHandler -from ...conversation import ConversationFactory -from ...exceptions import (ClientNotConnectedError, RequestError, - ResponseNotReceivedError, - SmartDeviceRegistrationError) -from ...utils import ServerID from .camera.camera_manager import CameraManager -from .events import EntityEvent, EventLoopManager, RegisteredListener +from .events import EventLoopManager, EntityEvent, RegisteredListener from .events.event_handler import EventHandler -from .expo_bundle_handler import MagicValueGrabber +from .rustplus_proto import AppRequest, AppMessage, AppEmpty, AppCameraSubscribe +from .rustws import RustWebsocket, CONNECTED, PENDING_CONNECTION from .ratelimiter import RateLimiter -from .rustplus_proto import (AppCameraSubscribe, AppEmpty, AppMessage, - AppRequest) -from .rustws import CONNECTED, PENDING_CONNECTION, RustWebsocket +from .expo_bundle_handler import MagicValueGrabber +from ...utils import ServerID +from ...conversation import ConversationFactory +from ...commands import CommandHandler +from ...exceptions import ( + ClientNotConnectedError, + ResponseNotReceivedError, + RequestError, + SmartDeviceRegistrationError, +) class RustRemote: @@ -31,6 +32,7 @@ def __init__( use_test_server: bool = False, rate_limiter: RateLimiter = None, ) -> None: + self.server_id = server_id self.api = api self.command_options = command_options @@ -68,6 +70,7 @@ def __init__( self.camera_manager: CameraManager = None async def connect(self, retries, delay, on_failure=None) -> None: + self.ws = RustWebsocket( server_id=self.server_id, remote=self, @@ -83,6 +86,7 @@ async def connect(self, retries, delay, on_failure=None) -> None: self.handle_subscribing_entity(entity_id, coroutine) def close(self) -> None: + if self.ws is not None: self.ws.close() del self.ws @@ -99,6 +103,7 @@ def is_open(self) -> bool: return False async def send_message(self, request: AppRequest) -> None: + if self.ws is None: raise ClientNotConnectedError("No Current Websocket Connection") @@ -114,12 +119,16 @@ async def get_response( attempts = 0 while seq in self.pending_for_response and seq not in self.responses: + if seq in self.sent_requests: + if attempts <= 40: + attempts += 1 await asyncio.sleep(0.1) else: + await self.send_message(app_request) await asyncio.sleep(0.1) attempts = 0 @@ -158,6 +167,7 @@ async def get_response( cost = self.ws.get_proto_cost(app_request) while True: + if self.ratelimiter.can_consume(self.server_id, cost): self.ratelimiter.consume(self.server_id, cost) break @@ -175,11 +185,13 @@ async def get_response( return response def handle_subscribing_entity(self, entity_id: int, coroutine) -> None: + if not self.is_open(): self.pending_entity_subscriptions.append((entity_id, coroutine)) return async def get_entity_info(self: RustRemote, eid): + await self.api._handle_ratelimit() app_request: AppRequest = self.api._generate_protobuf() @@ -192,6 +204,7 @@ async def get_entity_info(self: RustRemote, eid): return await self.get_response(app_request.seq, app_request, False) def entity_event_callback(future_inner: Future) -> None: + entity_info = future_inner.result() if entity_info.response.HasField("error"): @@ -228,6 +241,7 @@ async def subscribe_to_camera( return app_request async def create_camera_manager(self, cam_id) -> CameraManager: + if self.camera_manager is not None: if self.camera_manager._cam_id == cam_id: return self.camera_manager diff --git a/rustplus/api/remote/rustws.py b/rustplus/api/remote/rustws.py index e542e65..a23db39 100644 --- a/rustplus/api/remote/rustws.py +++ b/rustplus/api/remote/rustws.py @@ -5,17 +5,16 @@ from datetime import datetime from threading import Thread from typing import Optional - import betterproto import websocket -from ...conversation import Conversation -from ...exceptions import ClientNotConnectedError -from ...utils import ServerID -from ..structures import RustChatMessage from .camera.structures import RayPacket from .events import EventLoopManager from .rustplus_proto import AppMessage, AppRequest +from ..structures import RustChatMessage +from ...exceptions import ClientNotConnectedError +from ...conversation import Conversation +from ...utils import ServerID CONNECTED = 1 PENDING_CONNECTION = 2 @@ -34,6 +33,7 @@ def __init__( on_failure, delay, ): + self.server_id = server_id self.thread: Thread = None self.connection_status = CLOSED @@ -52,12 +52,15 @@ def __init__( async def connect( self, retries=float("inf"), ignore_open_value: bool = False ) -> None: + if ( not self.connection_status == CONNECTED or ignore_open_value ) and not self.remote.is_pending(): + attempts = 0 while True: + if attempts >= retries: raise ConnectionAbortedError("Reached Retry Limit") @@ -82,6 +85,7 @@ async def connect( self.connected_time = time.time() break except Exception as exception: + print_error = True if not isinstance(exception, KeyboardInterrupt): @@ -116,6 +120,7 @@ async def connect( self.thread.start() def close(self) -> None: + self.connection_status = CLOSING self.shutdown() # super().close() @@ -135,12 +140,13 @@ async def send_message(self, message: AppRequest) -> None: else: self.send_binary(bytes(message)) self.remote.pending_for_response[message.seq] = message - except Exception: + except Exception as e: while self.remote.is_pending(): await asyncio.sleep(0.5) return await self.remote.send_message(message) def run(self) -> None: + while self.connection_status == CONNECTED: try: data = self.recv() @@ -176,6 +182,7 @@ def run(self) -> None: self.logger.error(e) def handle_message(self, app_message: AppMessage) -> None: + if app_message.response.seq in self.remote.ignored_responses: self.remote.ignored_responses.remove(app_message.response.seq) return diff --git a/rustplus/api/remote/server_checker.py b/rustplus/api/remote/server_checker.py index 7ed32e8..da2bdf1 100644 --- a/rustplus/api/remote/server_checker.py +++ b/rustplus/api/remote/server_checker.py @@ -1,6 +1,5 @@ import logging import threading - import requests @@ -22,6 +21,4 @@ def _check_server(self) -> None: if "does not match your outgoing IP address" not in msg: self.logger.warning(f"Error from server Checker: {msg}") except Exception: - self.logger.exception( - f"Unable to test connection to server - {self.ip}:{self.port}" - ) + self.logger.exception(f"Unable to test connection to server - {self.ip}:{self.port}") diff --git a/rustplus/api/rust_api.py b/rustplus/api/rust_api.py index 26373c8..41537bb 100644 --- a/rustplus/api/rust_api.py +++ b/rustplus/api/rust_api.py @@ -1,24 +1,42 @@ import asyncio -from collections import defaultdict -from datetime import datetime -from importlib import resources -from io import BytesIO -from typing import List - import requests +from typing import List from PIL import Image +from io import BytesIO +from datetime import datetime +from collections import defaultdict +from importlib import resources -from ..commands import CommandOptions -from ..exceptions import * -from ..utils import (RustTime, convert_marker, convert_monument, deprecated, - format_coord, format_time, translate_id_to_stack) from .base_rust_api import BaseRustSocket -from .remote import HeartBeat, RateLimiter from .remote.camera.camera_manager import CameraManager -from .remote.rustplus_proto import (AppEmpty, AppPromoteToLeader, - AppSendMessage, AppSetEntityValue) -from .structures import (RustChatMessage, RustContents, RustEntityInfo, - RustInfo, RustItem, RustMap, RustMarker, RustTeamInfo) +from .structures import ( + RustInfo, + RustMap, + RustMarker, + RustChatMessage, + RustTeamInfo, + RustEntityInfo, + RustContents, + RustItem, +) +from .remote.rustplus_proto import ( + AppEmpty, + AppSendMessage, + AppSetEntityValue, + AppPromoteToLeader, +) +from .remote import HeartBeat, RateLimiter +from ..commands import CommandOptions +from ..exceptions import * +from ..utils import ( + RustTime, + format_time, + format_coord, + convert_marker, + convert_monument, + translate_id_to_stack, + deprecated, +) class RustSocket(BaseRustSocket): @@ -54,6 +72,7 @@ def __init__( ) async def get_time(self) -> RustTime: + await self._handle_ratelimit() app_request = self._generate_protobuf() @@ -67,6 +86,7 @@ async def get_time(self) -> RustTime: return format_time(response) async def send_team_message(self, message: str) -> None: + await self._handle_ratelimit(2) app_send_message = AppSendMessage() @@ -80,6 +100,7 @@ async def send_team_message(self, message: str) -> None: await self.remote.send_message(app_request) async def get_info(self) -> RustInfo: + await self._handle_ratelimit() app_request = self._generate_protobuf() @@ -93,6 +114,7 @@ async def get_info(self) -> RustInfo: return RustInfo(response.response.info) async def get_team_chat(self) -> List[RustChatMessage]: + await self._handle_ratelimit() app_request = self._generate_protobuf() @@ -108,6 +130,7 @@ async def get_team_chat(self) -> List[RustChatMessage]: return [RustChatMessage(message) for message in messages] async def get_team_info(self) -> RustTeamInfo: + await self._handle_ratelimit() app_request = self._generate_protobuf() @@ -121,6 +144,7 @@ async def get_team_info(self) -> RustTeamInfo: return RustTeamInfo(app_message.response.team_info) async def get_markers(self) -> List[RustMarker]: + await self._handle_ratelimit() app_request = self._generate_protobuf() @@ -136,6 +160,7 @@ async def get_markers(self) -> List[RustMarker]: ] async def get_raw_map_data(self) -> RustMap: + await self._handle_ratelimit(5) app_request = self._generate_protobuf() @@ -156,6 +181,7 @@ async def get_map( override_images: dict = None, add_grid: bool = False, ) -> Image.Image: + if override_images is None: override_images = {} @@ -269,6 +295,7 @@ async def get_map( return game_map.resize((2000, 2000), Image.ANTIALIAS) async def get_entity_info(self, eid: int = None) -> RustEntityInfo: + await self._handle_ratelimit() if eid is None: @@ -286,6 +313,7 @@ async def get_entity_info(self, eid: int = None) -> RustEntityInfo: return RustEntityInfo(app_message.response.entity_info) async def _update_smart_device(self, eid: int, value: bool) -> None: + await self._handle_ratelimit() entity_value = AppSetEntityValue() @@ -301,18 +329,21 @@ async def _update_smart_device(self, eid: int, value: bool) -> None: await self.remote.send_message(app_request) async def turn_on_smart_switch(self, eid: int = None) -> None: + if eid is None: raise ValueError("EID cannot be None") await self._update_smart_device(eid, True) async def turn_off_smart_switch(self, eid: int = None) -> None: + if eid is None: raise ValueError("EID cannot be None") await self._update_smart_device(eid, False) async def promote_to_team_leader(self, steam_id: int = None) -> None: + if steam_id is None: raise ValueError("SteamID cannot be None") @@ -329,6 +360,7 @@ async def promote_to_team_leader(self, steam_id: int = None) -> None: await self.remote.send_message(app_request) async def get_current_events(self) -> List[RustMarker]: + return [ marker for marker in (await self.get_markers()) @@ -342,6 +374,7 @@ async def get_current_events(self) -> List[RustMarker]: async def get_contents( self, eid: int = None, combine_stacks: bool = False ) -> RustContents: + if eid is None: raise ValueError("EID cannot be None") diff --git a/rustplus/api/structures/__init__.py b/rustplus/api/structures/__init__.py index 7352558..5ac6b8f 100644 --- a/rustplus/api/structures/__init__.py +++ b/rustplus/api/structures/__init__.py @@ -1,10 +1,10 @@ -from .rust_chat_message import RustChatMessage -from .rust_contents import RustContents -from .rust_entity_info import RustEntityInfo +from .rust_time import RustTime from .rust_info import RustInfo -from .rust_item import RustItem from .rust_map import RustMap from .rust_marker import RustMarker +from .rust_chat_message import RustChatMessage from .rust_team_info import RustTeamInfo, RustTeamMember, RustTeamNote -from .rust_time import RustTime +from .rust_entity_info import RustEntityInfo +from .rust_contents import RustContents +from .rust_item import RustItem from .util import Vector diff --git a/rustplus/api/structures/rust_marker.py b/rustplus/api/structures/rust_marker.py index e1ac4ab..1a50317 100644 --- a/rustplus/api/structures/rust_marker.py +++ b/rustplus/api/structures/rust_marker.py @@ -1,6 +1,6 @@ from typing import List -from ..remote.rustplus_proto import AppMarker, AppMarkerSellOrder, Vector4 +from ..remote.rustplus_proto import Vector4, AppMarkerSellOrder, AppMarker class RustColour: @@ -85,6 +85,7 @@ def __str__(self) -> str: class RustMarker: + PlayerMarker = 1 ExplosionMarker = 2 VendingMachineMarker = 3 diff --git a/rustplus/api/structures/rust_team_info.py b/rustplus/api/structures/rust_team_info.py index a70d792..49c9ccc 100644 --- a/rustplus/api/structures/rust_team_info.py +++ b/rustplus/api/structures/rust_team_info.py @@ -1,7 +1,6 @@ from typing import List -from ..remote.rustplus_proto import (AppTeamInfo, AppTeamInfoMember, - AppTeamInfoNote) +from ..remote.rustplus_proto import AppTeamInfoMember, AppTeamInfoNote, AppTeamInfo class RustTeamMember: diff --git a/rustplus/api/structures/util.py b/rustplus/api/structures/util.py index 1dfac38..6ee683d 100644 --- a/rustplus/api/structures/util.py +++ b/rustplus/api/structures/util.py @@ -3,5 +3,6 @@ @dataclasses.dataclass class Vector: + x: float = 0 y: float = 0 diff --git a/rustplus/commands/__init__.py b/rustplus/commands/__init__.py index c0f018a..3cc2bff 100644 --- a/rustplus/commands/__init__.py +++ b/rustplus/commands/__init__.py @@ -1,3 +1,3 @@ +from .command_options import CommandOptions from .command import Command, CommandTime from .command_handler import CommandHandler -from .command_options import CommandOptions diff --git a/rustplus/commands/command_handler.py b/rustplus/commands/command_handler.py index 53f7332..2182688 100644 --- a/rustplus/commands/command_handler.py +++ b/rustplus/commands/command_handler.py @@ -2,11 +2,11 @@ from asyncio.futures import Future from datetime import datetime -from ..api.remote.events import EventLoopManager, RegisteredListener +from . import Command, CommandTime from ..api.structures import RustChatMessage -from ..commands.command_data import CommandData from ..commands.command_options import CommandOptions -from . import Command, CommandTime +from ..commands.command_data import CommandData +from ..api.remote.events import RegisteredListener, EventLoopManager class CommandHandler: @@ -16,6 +16,7 @@ def __init__(self, command_options: CommandOptions, api) -> None: self.api = api def register_command(self, data: CommandData) -> None: + if not asyncio.iscoroutinefunction(data.coro): raise TypeError("The event registered must be a coroutine") @@ -30,6 +31,7 @@ def callback(inner_future: Future): future.add_done_callback(callback) def run_command(self, message: RustChatMessage, prefix) -> None: + if prefix == self.command_options.prefix: command = message.message.split(" ")[0][len(prefix) :] else: diff --git a/rustplus/commands/command_options.py b/rustplus/commands/command_options.py index c12d463..3f56ac0 100644 --- a/rustplus/commands/command_options.py +++ b/rustplus/commands/command_options.py @@ -7,6 +7,7 @@ class CommandOptions: def __init__( self, prefix: str = None, overruling_commands: List[str] = None ) -> None: + if prefix is None: raise PrefixNotDefinedError("No prefix") diff --git a/rustplus/conversation/__init__.py b/rustplus/conversation/__init__.py index ff3ddf4..fb32bed 100644 --- a/rustplus/conversation/__init__.py +++ b/rustplus/conversation/__init__.py @@ -1,3 +1,3 @@ from .conversation import Conversation -from .conversation_factory import ConversationFactory from .conversation_prompt import ConversationPrompt +from .conversation_factory import ConversationFactory diff --git a/rustplus/conversation/conversation.py b/rustplus/conversation/conversation.py index de615e7..0d71544 100644 --- a/rustplus/conversation/conversation.py +++ b/rustplus/conversation/conversation.py @@ -1,8 +1,7 @@ import asyncio from typing import List - -from ..api.remote.events import EventLoopManager from .conversation_prompt import ConversationPrompt +from ..api.remote.events import EventLoopManager class Conversation: @@ -13,6 +12,7 @@ def __init__( prompts: List[ConversationPrompt] = None, register=None, ) -> None: + if target is None: raise ValueError("target must be specified") self._target = target diff --git a/rustplus/conversation/conversation_factory.py b/rustplus/conversation/conversation_factory.py index 33b3b85..1c011b0 100644 --- a/rustplus/conversation/conversation_factory.py +++ b/rustplus/conversation/conversation_factory.py @@ -13,6 +13,7 @@ def __init__(self, api) -> None: self.gc_thread.start() def create_conversation(self, steamid: int) -> Conversation: + if steamid in self.conversations: raise ValueError("Conversation already exists") diff --git a/rustplus/exceptions/__init__.py b/rustplus/exceptions/__init__.py index e6e628c..ea1088f 100644 --- a/rustplus/exceptions/__init__.py +++ b/rustplus/exceptions/__init__.py @@ -1,5 +1,12 @@ -from .exceptions import (ClientNotConnectedError, CommandsNotEnabledError, - ImageError, PrefixNotDefinedError, RateLimitError, - RequestError, ResponseNotReceivedError, - ServerNotResponsiveError, ServerSwitchDisallowedError, - SmartDeviceRegistrationError) +from .exceptions import ( + RateLimitError, + ServerNotResponsiveError, + CommandsNotEnabledError, + ResponseNotReceivedError, + PrefixNotDefinedError, + ImageError, + ClientNotConnectedError, + RequestError, + SmartDeviceRegistrationError, + ServerSwitchDisallowedError, +) diff --git a/rustplus/exceptions/exceptions.py b/rustplus/exceptions/exceptions.py index c356352..6f6ab68 100644 --- a/rustplus/exceptions/exceptions.py +++ b/rustplus/exceptions/exceptions.py @@ -1,53 +1,64 @@ class Error(Exception): """Base class for other exceptions""" + pass class RateLimitError(Error): """Raised When an issue with the ratelimit has occurred""" + pass class ServerNotResponsiveError(Error): """Raised when the target Server is not online / Unavailable""" + pass class CommandsNotEnabledError(Error): """Raised when events are not enabled""" + pass class ResponseNotReceivedError(Error): """Raised when a response has not been received from the server""" + pass class PrefixNotDefinedError(Error): """Raised when a prefix is not given""" + pass class ImageError(Error): """Raised when the bytes received are not valid""" + pass class ClientNotConnectedError(Error): """Raised when you are not connected to the Rust server""" + pass class RequestError(Error): """Raised when an error is received from the server""" + pass class SmartDeviceRegistrationError(Error): """Raised when the entity cannot be registered with""" + pass class ServerSwitchDisallowedError(Error): """Raised when you are using the test server and attempt to swap server""" + pass diff --git a/rustplus/utils/__init__.py b/rustplus/utils/__init__.py index 5f4ebfc..d99f665 100644 --- a/rustplus/utils/__init__.py +++ b/rustplus/utils/__init__.py @@ -1,4 +1,4 @@ +from .rust_utils import * from .deprecated import deprecated from .grab_items import translate_id_to_stack -from .rust_utils import * from .server_id import ServerID diff --git a/rustplus/utils/deprecated.py b/rustplus/utils/deprecated.py index 75f20f8..604ebef 100644 --- a/rustplus/utils/deprecated.py +++ b/rustplus/utils/deprecated.py @@ -11,6 +11,7 @@ def deprecated(reason): """ def decorator(func1): + if inspect.isclass(func1): fmt1 = "Call to deprecated class {name} ({reason})." else: diff --git a/rustplus/utils/grab_items.py b/rustplus/utils/grab_items.py index 3351242..b2183f3 100644 --- a/rustplus/utils/grab_items.py +++ b/rustplus/utils/grab_items.py @@ -1,7 +1,7 @@ -import json from typing import Union import requests +import json item_ids = { "-2139580305": "Auto Turret", diff --git a/rustplus/utils/rust_utils.py b/rustplus/utils/rust_utils.py index 1b0aacb..59d9959 100644 --- a/rustplus/utils/rust_utils.py +++ b/rustplus/utils/rust_utils.py @@ -1,9 +1,8 @@ -import logging -import string from importlib import resources from typing import Tuple - from PIL import Image +import logging +import string from ..api.remote.rustplus_proto import AppMessage from ..api.structures import RustTime diff --git a/setup.py b/setup.py index 3ef6e9e..6b3ac32 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -from setuptools import find_packages, setup +from setuptools import setup, find_packages version = "" with open("rustplus/__init__.py") as input_file: @@ -12,23 +12,23 @@ for line in input_file.readlines(): requirements.append(line.strip()) -with open("README.md", errors="ignore") as input_file: +with open("README.md", errors='ignore') as input_file: readme = input_file.read() setup( - name="rustplus", - author="olijeffers0n", - url="https://github.com/olijeffers0n/rustplus", + name='rustplus', + author='olijeffers0n', + url='https://github.com/olijeffers0n/rustplus', project_urls={ "Issue tracker": "https://github.com/olijeffers0n/rustplus/issues", }, version=version, - packages=find_packages(include=["rustplus", "rustplus.*"]), - license="MIT", - description="A python wrapper for the Rust Plus API", + packages=find_packages(include=['rustplus', 'rustplus.*']), + license='MIT', + description='A python wrapper for the Rust Plus API', long_description=readme, include_package_data=True, - long_description_content_type="text/markdown", + long_description_content_type='text/markdown', install_requires=requirements, - python_requires=">=3.8.0", + python_requires='>=3.8.0', )