rustplus 6.0.11__tar.gz → 6.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.
- {rustplus-6.0.11/rustplus.egg-info → rustplus-6.1.0}/PKG-INFO +3 -1
- {rustplus-6.0.11 → rustplus-6.1.0}/README.md +2 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/__init__.py +10 -2
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/annotations/__init__.py +1 -0
- rustplus-6.1.0/rustplus/annotations/clan_event.py +21 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/events/__init__.py +1 -0
- rustplus-6.1.0/rustplus/events/chat_event.py +27 -0
- rustplus-6.1.0/rustplus/events/clan_info_event.py +13 -0
- rustplus-6.1.0/rustplus/remote/camera/camera_constants.py +32 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/camera/camera_manager.py +4 -4
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/camera/camera_parser.py +86 -3
- rustplus-6.1.0/rustplus/remote/nexus/__init__.py +1 -0
- rustplus-6.1.0/rustplus/remote/nexus/nexus_interface.py +45 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/websocket/ws.py +39 -25
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/rust_api.py +106 -8
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/__init__.py +2 -1
- rustplus-6.1.0/rustplus/structs/clans/__init__.py +2 -0
- rustplus-6.1.0/rustplus/structs/clans/rust_clan_info.py +247 -0
- rustplus-6.1.0/rustplus/structs/clans/rust_clan_message.py +30 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/rust_chat_message.py +8 -3
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/rust_info.py +19 -1
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/rust_marker.py +9 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/util.py +6 -0
- {rustplus-6.0.11 → rustplus-6.1.0/rustplus.egg-info}/PKG-INFO +3 -1
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus.egg-info/SOURCES.txt +7 -0
- rustplus-6.0.11/rustplus/events/chat_event.py +0 -13
- rustplus-6.0.11/rustplus/remote/camera/camera_constants.py +0 -35
- {rustplus-6.0.11 → rustplus-6.1.0}/LICENSE +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/MANIFEST.in +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/requirements.txt +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/annotations/chat_event.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/annotations/command.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/annotations/entity_event.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/annotations/protobuf_event.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/annotations/team_event.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/commands/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/commands/chat_command.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/commands/chat_command_data.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/commands/command_options.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/events/entity_event.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/events/protobuf_event.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/events/team_event.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/exceptions/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/exceptions/exceptions.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/airfield.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/arctic_base.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/bandit.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/barn.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/cargo.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/chinook.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/chinook_blades.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/crate.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/desert_base.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/dome.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/excavator.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/explosion.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/ferryterminal.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/fishing.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/harbour.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/icon.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/jungle_ziggurat.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/junkyard.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/large_oil_rig.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/launchsite.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/lighthouse.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/military_tunnels.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/mining_outpost.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/mining_quarry_hqm.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/mining_quarry_stone.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/mining_quarry_sulfur.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/missile_silo.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/outpost.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/oxums.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/patrol.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/power_plant.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/radtown.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/satellite.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/sewer.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/small_oil_rig.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/stables.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/supermarket.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/swamp.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/train.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/train_yard.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/underwater_lab.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/vending_machine.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/icons/water_treatment.png +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/identification/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/identification/handler_list.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/identification/registered_listener.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/identification/server_details.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/camera/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/camera/structures.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/fcm/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/fcm/fcm_listener.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/proxy/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/proxy/proxy_value_grabber.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/ratelimiter/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/rustplus_proto/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/rustplus_proto/rustplus.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/remote/websocket/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/rust_contents.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/rust_entity_info.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/rust_error.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/rust_item.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/rust_map.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/rust_team_info.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/rust_time.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/structs/serialization.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/utils/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/utils/deprecated.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/utils/emojis.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/utils/fonts/PermanentMarker.ttf +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/utils/fonts/__init__.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/utils/grab_items.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/utils/utils.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus/utils/yielding_event.py +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus.egg-info/dependency_links.txt +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus.egg-info/requires.txt +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/rustplus.egg-info/top_level.txt +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/setup.cfg +0 -0
- {rustplus-6.0.11 → rustplus-6.1.0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rustplus
|
|
3
|
-
Version: 6.0
|
|
3
|
+
Version: 6.1.0
|
|
4
4
|
Summary: A python wrapper for the Rust Plus API
|
|
5
5
|
Home-page: https://github.com/olijeffers0n/rustplus
|
|
6
6
|
Author: olijeffers0n
|
|
@@ -60,6 +60,8 @@ pip install rustplus
|
|
|
60
60
|
- Getting the time
|
|
61
61
|
- Using Smart Devices
|
|
62
62
|
- Camera Handling
|
|
63
|
+
- Interacting with clans
|
|
64
|
+
- Getting nexus information
|
|
63
65
|
|
|
64
66
|
# For information on all the above methods, see the [Wiki](https://rplus.ollieee.xyz)
|
|
65
67
|
|
|
@@ -4,9 +4,17 @@ RustPlus, An API wrapper for interfacing with the Rust+ App API
|
|
|
4
4
|
|
|
5
5
|
from .rust_api import RustSocket
|
|
6
6
|
from .identification import ServerDetails
|
|
7
|
-
from .annotations import
|
|
7
|
+
from .annotations import (
|
|
8
|
+
Command,
|
|
9
|
+
ChatEvent,
|
|
10
|
+
ProtobufEvent,
|
|
11
|
+
TeamEvent,
|
|
12
|
+
EntityEvent,
|
|
13
|
+
ClanEvent,
|
|
14
|
+
)
|
|
8
15
|
from .remote.fcm import FCMListener
|
|
9
16
|
from .remote.camera import MovementControls, CameraMovementOptions
|
|
17
|
+
from .remote.nexus import NexusInterface, Realm
|
|
10
18
|
from .commands import CommandOptions, ChatCommand
|
|
11
19
|
from .events import ChatEventPayload, TeamEventPayload, EntityEventPayload
|
|
12
20
|
from .utils import convert_event_type_to_name, Emoji, convert_coordinates
|
|
@@ -14,5 +22,5 @@ from .structs import RustError, RustMarker, Vector
|
|
|
14
22
|
|
|
15
23
|
__name__ = "rustplus"
|
|
16
24
|
__author__ = "olijeffers0n"
|
|
17
|
-
__version__ = "6.0
|
|
25
|
+
__version__ = "6.1.0"
|
|
18
26
|
__support__ = "Discord: https://discord.gg/nQqJe8qvP8"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from typing import Callable
|
|
2
|
+
|
|
3
|
+
from .. import ServerDetails
|
|
4
|
+
from ..identification import RegisteredListener
|
|
5
|
+
from ..events import ClanInfoEventPayload as ClanInfoEventManager
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def ClanEvent(server_details: ServerDetails) -> Callable:
|
|
9
|
+
|
|
10
|
+
def wrapper(func) -> RegisteredListener:
|
|
11
|
+
|
|
12
|
+
if isinstance(func, RegisteredListener):
|
|
13
|
+
func = func.get_coro()
|
|
14
|
+
|
|
15
|
+
listener = RegisteredListener(func.__name__, func)
|
|
16
|
+
|
|
17
|
+
ClanInfoEventManager.HANDLER_LIST.register(listener, server_details)
|
|
18
|
+
|
|
19
|
+
return listener
|
|
20
|
+
|
|
21
|
+
return wrapper
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from rustplus.identification.handler_list import HandlerList
|
|
2
|
+
from ..structs import RustChatMessage
|
|
3
|
+
|
|
4
|
+
from typing import Union
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ChatEventPayload:
|
|
8
|
+
HANDLER_LIST = HandlerList()
|
|
9
|
+
|
|
10
|
+
def __init__(
|
|
11
|
+
self, message: RustChatMessage, is_clan: bool, clan_id: Union[int, None]
|
|
12
|
+
) -> None:
|
|
13
|
+
self._message = message
|
|
14
|
+
self._is_clan = is_clan
|
|
15
|
+
self._clan_id = clan_id
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def message(self) -> RustChatMessage:
|
|
19
|
+
return self._message
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def is_clan(self) -> bool:
|
|
23
|
+
return self._is_clan
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def clan_id(self) -> Union[int, None]:
|
|
27
|
+
return self._clan_id
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from rustplus.identification.handler_list import HandlerList
|
|
2
|
+
from ..structs import RustClanInfo
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ClanInfoEventPayload:
|
|
6
|
+
HANDLER_LIST = HandlerList()
|
|
7
|
+
|
|
8
|
+
def __init__(self, clan_info: RustClanInfo) -> None:
|
|
9
|
+
self._clan_info = clan_info
|
|
10
|
+
|
|
11
|
+
@property
|
|
12
|
+
def clan_info(self) -> RustClanInfo:
|
|
13
|
+
return self._clan_info
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class MovementControls:
|
|
2
|
+
"""
|
|
3
|
+
Possible inputs for the camera movement.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
FORWARD = 2
|
|
7
|
+
BACKWARD = 4
|
|
8
|
+
LEFT = 8
|
|
9
|
+
RIGHT = 16
|
|
10
|
+
JUMP = 32
|
|
11
|
+
DUCK = 64
|
|
12
|
+
SPRINT = 128
|
|
13
|
+
USE = 256
|
|
14
|
+
FIRE_PRIMARY = 1024
|
|
15
|
+
FIRE_SECONDARY = 2048
|
|
16
|
+
RELOAD = 8192
|
|
17
|
+
FIRE_THIRD = 134217728
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CameraMovementOptions:
|
|
21
|
+
"""
|
|
22
|
+
Indicate which camera controls are active for the camera.
|
|
23
|
+
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
NONE = 0
|
|
27
|
+
MOVEMENT = 1
|
|
28
|
+
MOUSE = 2
|
|
29
|
+
SPRINT_AND_DUCK = 4
|
|
30
|
+
FIRE = 8
|
|
31
|
+
RELOAD = 16
|
|
32
|
+
CROSSHAIR = 32
|
|
@@ -58,8 +58,8 @@ class CameraManager:
|
|
|
58
58
|
async def _create_frame(
|
|
59
59
|
self,
|
|
60
60
|
render_entities: bool = True,
|
|
61
|
-
entity_render_distance: float = float("inf"),
|
|
62
|
-
max_entity_amount: int = float("inf"),
|
|
61
|
+
entity_render_distance: float | int = float("inf"),
|
|
62
|
+
max_entity_amount: float | int = float("inf"),
|
|
63
63
|
) -> Union[Image.Image, None]:
|
|
64
64
|
if self._last_packets is None:
|
|
65
65
|
return None
|
|
@@ -95,8 +95,8 @@ class CameraManager:
|
|
|
95
95
|
async def get_frame(
|
|
96
96
|
self,
|
|
97
97
|
render_entities: bool = True,
|
|
98
|
-
entity_render_distance: float = float("inf"),
|
|
99
|
-
max_entity_amount: int = float("inf"),
|
|
98
|
+
entity_render_distance: float | int = float("inf"),
|
|
99
|
+
max_entity_amount: float | int = float("inf"),
|
|
100
100
|
) -> Union[Image.Image, None]:
|
|
101
101
|
return await self._create_frame(
|
|
102
102
|
render_entities, entity_render_distance, max_entity_amount
|
|
@@ -7,7 +7,6 @@ import numpy as np
|
|
|
7
7
|
from scipy.spatial import ConvexHull
|
|
8
8
|
from PIL import Image, ImageDraw, ImageFont
|
|
9
9
|
|
|
10
|
-
from .camera_constants import LOOKUP_CONSTANTS
|
|
11
10
|
from .structures import Entity, Vector3
|
|
12
11
|
|
|
13
12
|
SCIENTIST_COLOUR = "#3098f2"
|
|
@@ -44,6 +43,8 @@ class Parser:
|
|
|
44
43
|
self.entities = []
|
|
45
44
|
self.last_fov = 0
|
|
46
45
|
|
|
46
|
+
self.lookup_constants = self._generate_lookup_constants(self.width, self.height)
|
|
47
|
+
|
|
47
48
|
def reset_output(self) -> None:
|
|
48
49
|
self.colour_output = np.full(
|
|
49
50
|
(self.width * self.scale_factor, self.height * self.scale_factor, 3),
|
|
@@ -53,6 +54,42 @@ class Parser:
|
|
|
53
54
|
(self.width * self.scale_factor, self.height * self.scale_factor)
|
|
54
55
|
)
|
|
55
56
|
|
|
57
|
+
@staticmethod
|
|
58
|
+
def _generate_lookup_constants(width: int, height: int) -> List[int]:
|
|
59
|
+
instance_count = width * height
|
|
60
|
+
|
|
61
|
+
sample_position_buffer = [0] * (instance_count * 2)
|
|
62
|
+
|
|
63
|
+
buffer_index = 0
|
|
64
|
+
|
|
65
|
+
for y in range(height):
|
|
66
|
+
for x in range(width):
|
|
67
|
+
sample_position_buffer[buffer_index] = RNGSource.int32(x)
|
|
68
|
+
buffer_index += 1
|
|
69
|
+
|
|
70
|
+
sample_position_buffer[buffer_index] = RNGSource.int32(y)
|
|
71
|
+
buffer_index += 1
|
|
72
|
+
|
|
73
|
+
rng = RNGSource(1337)
|
|
74
|
+
|
|
75
|
+
for current_position in range(instance_count - 1, 0, -1):
|
|
76
|
+
current_index = 2 * current_position
|
|
77
|
+
random_position = 2 * rng.next_int(current_position + 1)
|
|
78
|
+
|
|
79
|
+
current_x = sample_position_buffer[current_index]
|
|
80
|
+
current_y = sample_position_buffer[current_index + 1]
|
|
81
|
+
|
|
82
|
+
random_x = sample_position_buffer[random_position]
|
|
83
|
+
random_y = sample_position_buffer[random_position + 1]
|
|
84
|
+
|
|
85
|
+
sample_position_buffer[random_position] = current_x
|
|
86
|
+
sample_position_buffer[random_position + 1] = current_y
|
|
87
|
+
|
|
88
|
+
sample_position_buffer[current_index] = random_x
|
|
89
|
+
sample_position_buffer[current_index + 1] = random_y
|
|
90
|
+
|
|
91
|
+
return sample_position_buffer
|
|
92
|
+
|
|
56
93
|
def handle_camera_ray_data(self, data) -> None:
|
|
57
94
|
if data is None:
|
|
58
95
|
return
|
|
@@ -90,9 +127,11 @@ class Parser:
|
|
|
90
127
|
alignment = ray[1]
|
|
91
128
|
material = ray[2]
|
|
92
129
|
|
|
93
|
-
index1 =
|
|
130
|
+
index1 = self.lookup_constants[self._sample_offset]
|
|
94
131
|
self._sample_offset += 1
|
|
95
|
-
index2 = int(
|
|
132
|
+
index2 = int(
|
|
133
|
+
self.lookup_constants[self._sample_offset] * self.width + index1
|
|
134
|
+
)
|
|
96
135
|
self._sample_offset += 1
|
|
97
136
|
|
|
98
137
|
x = (index2 % self.width) * self.scale_factor
|
|
@@ -786,3 +825,47 @@ class MathUtils:
|
|
|
786
825
|
|
|
787
826
|
# Return the vertices that correspond to the non-zero indices
|
|
788
827
|
return np.array(list(zip(x, y)))
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
class RNGSource:
|
|
831
|
+
def __init__(self, seed):
|
|
832
|
+
self.state = self.int32(seed)
|
|
833
|
+
self.next_state()
|
|
834
|
+
|
|
835
|
+
def next_int(self, e):
|
|
836
|
+
t = self.int32((self.next_state() * self.int32(e)) / 4294967295)
|
|
837
|
+
|
|
838
|
+
if t < 0:
|
|
839
|
+
t = e + t - 1
|
|
840
|
+
|
|
841
|
+
return self.int32(t)
|
|
842
|
+
|
|
843
|
+
def next_state(self):
|
|
844
|
+
e = self.state
|
|
845
|
+
t = e
|
|
846
|
+
|
|
847
|
+
e = self.int32(e ^ self.int32(e << 13))
|
|
848
|
+
e = self.int32(e ^ (self.uint32(e) >> 17))
|
|
849
|
+
e = self.int32(e ^ self.int32(e << 5))
|
|
850
|
+
|
|
851
|
+
self.state = e
|
|
852
|
+
|
|
853
|
+
return self.clamp(t)
|
|
854
|
+
|
|
855
|
+
@staticmethod
|
|
856
|
+
def clamp(e):
|
|
857
|
+
return e if e >= 0 else 4294967295 + e - 1
|
|
858
|
+
|
|
859
|
+
@staticmethod
|
|
860
|
+
def int32(value):
|
|
861
|
+
value = int(value)
|
|
862
|
+
value &= 0xFFFFFFFF
|
|
863
|
+
|
|
864
|
+
if value >= 0x80000000:
|
|
865
|
+
value -= 0x100000000
|
|
866
|
+
|
|
867
|
+
return value
|
|
868
|
+
|
|
869
|
+
@staticmethod
|
|
870
|
+
def uint32(value):
|
|
871
|
+
return value & 0xFFFFFFFF
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .nexus_interface import NexusInterface, Realm
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
import enum
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Realm(enum.Enum):
|
|
8
|
+
Development = 0
|
|
9
|
+
Staging = 1
|
|
10
|
+
Production = 2
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class NexusInterface:
|
|
14
|
+
def __init__(self, endpoint: str):
|
|
15
|
+
self.session = requests.Session()
|
|
16
|
+
self.endpoint = endpoint
|
|
17
|
+
|
|
18
|
+
def get_all_nexus(self, public_key: str, realm: Realm) -> Any | None:
|
|
19
|
+
|
|
20
|
+
res = self.session.get(
|
|
21
|
+
f"{self.endpoint}?publicKey={public_key}&realm={realm.value}"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
if res.status_code == 200:
|
|
25
|
+
return res.json()
|
|
26
|
+
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
def get_nexus_info(self, nexus_id: int) -> Any | None:
|
|
30
|
+
|
|
31
|
+
res = self.session.get(f"{self.endpoint}/{nexus_id}")
|
|
32
|
+
|
|
33
|
+
if res.status_code == 200:
|
|
34
|
+
return res.json()
|
|
35
|
+
|
|
36
|
+
return None
|
|
37
|
+
|
|
38
|
+
def get_nexus_map(self, nexus_id: int) -> Any | None:
|
|
39
|
+
|
|
40
|
+
res = self.session.get(f"{self.endpoint}/{nexus_id}/map")
|
|
41
|
+
|
|
42
|
+
if res.status_code == 200:
|
|
43
|
+
return res.content
|
|
44
|
+
|
|
45
|
+
return None
|
|
@@ -19,9 +19,10 @@ from ...events import (
|
|
|
19
19
|
TeamEventPayload,
|
|
20
20
|
ChatEventPayload,
|
|
21
21
|
)
|
|
22
|
+
from ...events.clan_info_event import ClanInfoEventPayload
|
|
22
23
|
from ...exceptions import RequestError
|
|
23
24
|
from ...identification import ServerDetails, RegisteredListener
|
|
24
|
-
from ...structs import RustChatMessage, RustTeamInfo
|
|
25
|
+
from ...structs import RustChatMessage, RustTeamInfo, RustClanInfo
|
|
25
26
|
from ...utils import YieldingEvent, convert_time
|
|
26
27
|
from ...utils.utils import error_present
|
|
27
28
|
|
|
@@ -274,14 +275,40 @@ class RustWebsocket:
|
|
|
274
275
|
for handler in handlers:
|
|
275
276
|
await handler.get_coro()(team_event)
|
|
276
277
|
|
|
277
|
-
elif self.
|
|
278
|
+
elif self.is_clan_broadcast(app_message):
|
|
279
|
+
# Clan Event
|
|
280
|
+
if self.debug:
|
|
281
|
+
self.logger.info(f"Running Clan Event: {app_message}")
|
|
282
|
+
|
|
283
|
+
# This means that the clan of the current player has changed
|
|
284
|
+
handlers = ClanInfoEventPayload.HANDLER_LIST.get_handlers(
|
|
285
|
+
self.server_details
|
|
286
|
+
)
|
|
287
|
+
clan_event = ClanInfoEventPayload(
|
|
288
|
+
RustClanInfo(app_message.broadcast.clan_changed.clan_info)
|
|
289
|
+
)
|
|
290
|
+
for handler in handlers:
|
|
291
|
+
await handler.get_coro()(clan_event)
|
|
292
|
+
|
|
293
|
+
elif self.is_message(app_message) or self.is_clan_message(app_message):
|
|
278
294
|
# Chat message event
|
|
295
|
+
|
|
296
|
+
is_clan = self.is_clan_message(app_message)
|
|
297
|
+
|
|
279
298
|
if self.debug:
|
|
280
|
-
self.logger.info(
|
|
299
|
+
self.logger.info(
|
|
300
|
+
f"Running Chat Event: {app_message}, is_clan={is_clan}"
|
|
301
|
+
)
|
|
281
302
|
|
|
282
303
|
handlers = ChatEventPayload.HANDLER_LIST.get_handlers(self.server_details)
|
|
283
304
|
chat_event = ChatEventPayload(
|
|
284
|
-
RustChatMessage(
|
|
305
|
+
RustChatMessage(
|
|
306
|
+
app_message.broadcast.clan_message.message
|
|
307
|
+
if is_clan
|
|
308
|
+
else app_message.broadcast.team_message.message
|
|
309
|
+
),
|
|
310
|
+
is_clan,
|
|
311
|
+
app_message.broadcast.clan_message.clan_id if is_clan else None,
|
|
285
312
|
)
|
|
286
313
|
for handler in handlers:
|
|
287
314
|
await handler.get_coro()(chat_event)
|
|
@@ -321,6 +348,12 @@ class RustWebsocket:
|
|
|
321
348
|
app_message.broadcast.team_message.message
|
|
322
349
|
)
|
|
323
350
|
|
|
351
|
+
@staticmethod
|
|
352
|
+
def is_clan_message(app_message: AppMessage) -> bool:
|
|
353
|
+
return betterproto.serialized_on_wire(
|
|
354
|
+
app_message.broadcast.clan_message.message
|
|
355
|
+
)
|
|
356
|
+
|
|
324
357
|
@staticmethod
|
|
325
358
|
def is_camera_broadcast(app_message: AppMessage) -> bool:
|
|
326
359
|
return betterproto.serialized_on_wire(app_message.broadcast.camera_rays)
|
|
@@ -334,27 +367,8 @@ class RustWebsocket:
|
|
|
334
367
|
return betterproto.serialized_on_wire(app_message.broadcast.team_changed)
|
|
335
368
|
|
|
336
369
|
@staticmethod
|
|
337
|
-
def
|
|
338
|
-
|
|
339
|
-
Gets the cost of an AppRequest
|
|
340
|
-
"""
|
|
341
|
-
costs = [
|
|
342
|
-
(app_request.get_time, 1),
|
|
343
|
-
(app_request.send_team_message, 2),
|
|
344
|
-
(app_request.get_info, 1),
|
|
345
|
-
(app_request.get_team_chat, 1),
|
|
346
|
-
(app_request.get_team_info, 1),
|
|
347
|
-
(app_request.get_map_markers, 1),
|
|
348
|
-
(app_request.get_map, 5),
|
|
349
|
-
(app_request.set_entity_value, 1),
|
|
350
|
-
(app_request.get_entity_info, 1),
|
|
351
|
-
(app_request.promote_to_leader, 1),
|
|
352
|
-
]
|
|
353
|
-
for request, cost in costs:
|
|
354
|
-
if betterproto.serialized_on_wire(request):
|
|
355
|
-
return cost
|
|
356
|
-
|
|
357
|
-
raise ValueError()
|
|
370
|
+
def is_clan_broadcast(app_message: AppMessage) -> bool:
|
|
371
|
+
return betterproto.serialized_on_wire(app_message.broadcast.clan_changed)
|
|
358
372
|
|
|
359
373
|
@staticmethod
|
|
360
374
|
async def run_coroutine_non_blocking(coroutine: Coroutine) -> Task:
|
|
@@ -19,6 +19,7 @@ from .remote.rustplus_proto import (
|
|
|
19
19
|
AppCameraSubscribe,
|
|
20
20
|
AppMapMonument,
|
|
21
21
|
AppFlag,
|
|
22
|
+
AppGetNexusAuth,
|
|
22
23
|
)
|
|
23
24
|
from .remote.websocket import RustWebsocket
|
|
24
25
|
from .structs import (
|
|
@@ -31,6 +32,9 @@ from .structs import (
|
|
|
31
32
|
RustEntityInfo,
|
|
32
33
|
RustContents,
|
|
33
34
|
RustItem,
|
|
35
|
+
RustClanInfo,
|
|
36
|
+
RustClanMessage,
|
|
37
|
+
RustAuthDetails,
|
|
34
38
|
)
|
|
35
39
|
from .structs.rust_error import RustError
|
|
36
40
|
from .utils import (
|
|
@@ -61,13 +65,16 @@ class RustSocket:
|
|
|
61
65
|
self.command_options = command_options
|
|
62
66
|
self.logger = logging.getLogger("rustplus.py")
|
|
63
67
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
if not self.logger.handlers:
|
|
69
|
+
console_handler = logging.StreamHandler()
|
|
70
|
+
console_handler.setLevel(logging.DEBUG)
|
|
71
|
+
console_handler.setFormatter(
|
|
72
|
+
logging.Formatter(
|
|
73
|
+
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
self.logger.addHandler(console_handler)
|
|
77
|
+
self.logger.setLevel(logging.DEBUG)
|
|
71
78
|
|
|
72
79
|
self.ws = RustWebsocket(
|
|
73
80
|
self.server_details,
|
|
@@ -337,7 +344,7 @@ class RustSocket:
|
|
|
337
344
|
|
|
338
345
|
for marker in map_markers:
|
|
339
346
|
if add_events:
|
|
340
|
-
if marker.type in
|
|
347
|
+
if marker.type in RustMarker.Events:
|
|
341
348
|
icon = convert_marker(int(marker.type), marker.rotation)
|
|
342
349
|
if marker.type == 6:
|
|
343
350
|
x, y = marker.x, marker.y
|
|
@@ -563,3 +570,94 @@ class RustSocket:
|
|
|
563
570
|
return RustError("get_camera_manager", response.response.error.error)
|
|
564
571
|
|
|
565
572
|
return CameraManager(self, cam_id, response.response.camera_subscribe_info)
|
|
573
|
+
|
|
574
|
+
async def get_clan_info(self) -> Union[RustClanInfo, RustError]:
|
|
575
|
+
"""
|
|
576
|
+
Gets the clan information for the player's current clan.
|
|
577
|
+
|
|
578
|
+
:return RustClanInfo: The clan information
|
|
579
|
+
"""
|
|
580
|
+
packet = await self._generate_request(tokens=1)
|
|
581
|
+
packet.get_clan_info = AppEmpty()
|
|
582
|
+
response = await self.ws.send_and_get(packet)
|
|
583
|
+
|
|
584
|
+
if response is None:
|
|
585
|
+
return RustError("get_clan_info", "No response received")
|
|
586
|
+
|
|
587
|
+
if error_present(response):
|
|
588
|
+
return RustError("get_clan_info", response.response.error.error)
|
|
589
|
+
|
|
590
|
+
return RustClanInfo(response.response.clan_info.clan_info)
|
|
591
|
+
|
|
592
|
+
async def get_clan_chat(self) -> Union[List[RustClanMessage], RustError]:
|
|
593
|
+
"""
|
|
594
|
+
Gets the clan chat for the player's current clan.
|
|
595
|
+
|
|
596
|
+
:return List[RustClanMessage]: The clan chat
|
|
597
|
+
"""
|
|
598
|
+
packet = await self._generate_request(tokens=1)
|
|
599
|
+
packet.get_clan_chat = AppEmpty()
|
|
600
|
+
response = await self.ws.send_and_get(packet)
|
|
601
|
+
|
|
602
|
+
if response is None:
|
|
603
|
+
return RustError("get_clan_chat", "No response received")
|
|
604
|
+
|
|
605
|
+
if error_present(response):
|
|
606
|
+
return RustError("get_clan_chat", response.response.error.error)
|
|
607
|
+
|
|
608
|
+
return [
|
|
609
|
+
RustClanMessage(message) for message in response.response.clan_chat.messages
|
|
610
|
+
]
|
|
611
|
+
|
|
612
|
+
async def send_clan_message(self, message: str) -> None:
|
|
613
|
+
"""
|
|
614
|
+
Sends a message to the in-game clan chat
|
|
615
|
+
|
|
616
|
+
:param message: The string message to send
|
|
617
|
+
"""
|
|
618
|
+
|
|
619
|
+
packet = await self._generate_request(tokens=2)
|
|
620
|
+
send_message = AppSendMessage()
|
|
621
|
+
send_message.message = message
|
|
622
|
+
packet.send_clan_message = send_message
|
|
623
|
+
|
|
624
|
+
await self.ws.send_message(packet, True)
|
|
625
|
+
|
|
626
|
+
async def set_clan_motd(self, message: str) -> None:
|
|
627
|
+
"""
|
|
628
|
+
Sets the clan's message of the day
|
|
629
|
+
|
|
630
|
+
:param message: The string message to set as the clan's message of the day
|
|
631
|
+
"""
|
|
632
|
+
|
|
633
|
+
packet = await self._generate_request()
|
|
634
|
+
send_message = AppSendMessage()
|
|
635
|
+
send_message.message = message
|
|
636
|
+
packet.set_clan_motd = send_message
|
|
637
|
+
|
|
638
|
+
await self.ws.send_message(packet, True)
|
|
639
|
+
|
|
640
|
+
async def get_nexus_auth(self, app_key: str) -> Union[RustAuthDetails, RustError]:
|
|
641
|
+
"""
|
|
642
|
+
Gets the auth for a server. Does not require that the player token of this RustSocket is set correctly.
|
|
643
|
+
|
|
644
|
+
:param app_key: The app key to use. I do not know how you would get this currently, without owning the server.
|
|
645
|
+
"""
|
|
646
|
+
|
|
647
|
+
packet = await self._generate_request()
|
|
648
|
+
send_message = AppGetNexusAuth()
|
|
649
|
+
send_message.app_key = app_key
|
|
650
|
+
packet.get_nexus_auth = send_message
|
|
651
|
+
|
|
652
|
+
response = await self.ws.send_and_get(packet)
|
|
653
|
+
|
|
654
|
+
if response is None:
|
|
655
|
+
return RustError("get_nexus_auth", "No response received")
|
|
656
|
+
|
|
657
|
+
if error_present(response):
|
|
658
|
+
return RustError("get_nexus_auth", response.response.error.error)
|
|
659
|
+
|
|
660
|
+
return RustAuthDetails(
|
|
661
|
+
response.response.nexus_auth.server_id,
|
|
662
|
+
response.response.nexus_auth.player_token,
|
|
663
|
+
)
|
|
@@ -7,5 +7,6 @@ from .rust_team_info import RustTeamInfo, RustTeamMember, RustTeamNote
|
|
|
7
7
|
from .rust_entity_info import RustEntityInfo
|
|
8
8
|
from .rust_contents import RustContents
|
|
9
9
|
from .rust_item import RustItem
|
|
10
|
-
from .util import Vector
|
|
10
|
+
from .util import Vector, RustAuthDetails
|
|
11
11
|
from .rust_error import RustError
|
|
12
|
+
from .clans import *
|