Skip to content

Commit

Permalink
Clans Implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
olijeffers0n committed Aug 3, 2023
1 parent 618023a commit 2a36a42
Show file tree
Hide file tree
Showing 12 changed files with 448 additions and 42 deletions.
58 changes: 29 additions & 29 deletions rustplus.proto
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ message Ray {
optional Vector3 direction = 2;
}

message ClanActionResult {
required int32 requestId = 1;
required int32 result = 2;
required bool hasClanInfo = 3;
optional ClanInfo clanInfo = 4;
}
// message ClanActionResult {
// required int32 requestId = 1;
// required int32 result = 2;
// required bool hasClanInfo = 3;
// optional ClanInfo clanInfo = 4;
// }

message ClanInfo {
required int64 clanId = 1;
Expand Down Expand Up @@ -89,29 +89,29 @@ message ClanInfo {
}
}

message ClanLog {
required int64 clanId = 1;
repeated ClanLog.Entry logEntries = 2;

message Entry {
required int64 timestamp = 1;
required string eventKey = 2;
optional string arg1 = 3;
optional string arg2 = 4;
optional string arg3 = 5;
optional string arg4 = 6;
}
}

message ClanInvitations {
repeated ClanInvitations.Invitation invitations = 1;

message Invitation {
required int64 clanId = 1;
required uint64 recruiter = 2;
required int64 timestamp = 3;
}
}
// message ClanLog {
// required int64 clanId = 1;
// repeated ClanLog.Entry logEntries = 2;
//
// message Entry {
// required int64 timestamp = 1;
// required string eventKey = 2;
// optional string arg1 = 3;
// optional string arg2 = 4;
// optional string arg3 = 5;
// optional string arg4 = 6;
// }
// }

// message ClanInvitations {
// repeated ClanInvitations.Invitation invitations = 1;
//
// message Invitation {
// required int64 clanId = 1;
// required uint64 recruiter = 2;
// required int64 timestamp = 3;
// }
// }

enum AppEntityType {
Switch = 1;
Expand Down
48 changes: 48 additions & 0 deletions rustplus/api/base_rust_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
TeamEvent,
ChatEvent,
ProtobufEvent,
ClanInfoEvent,
)
from ..utils import deprecated
from ..conversation import ConversationFactory
Expand Down Expand Up @@ -404,6 +405,21 @@ def protobuf_received(self, coro) -> RegisteredListener:
ProtobufEvent.handlers.register(listener, self.server_id)
return listener

def clan_info_event(self, coro) -> RegisteredListener:
"""
A Decorator to register an event listener for clan info being received on the websocket
:param coro: The coroutine to call when the command is called
:return: RegisteredListener - The listener object
"""

if isinstance(coro, RegisteredListener):
coro = coro.get_coro()

listener = RegisteredListener("clan_info_received", coro)
ClanInfoEvent.handlers.register(listener, self.server_id)
return listener

def remove_listener(self, listener) -> bool:
"""
This will remove a listener, command or event. Takes a RegisteredListener instance
Expand Down Expand Up @@ -612,3 +628,35 @@ async def get_camera_manager(self, cam_id: str) -> CameraManager:
:raises RequestError: If the camera is not found, or you cannot access it. See reason for more info
"""
raise NotImplementedError("Not Implemented")

async def get_clan_info(self) -> RustClanInfo:
"""
Gets the clan info from the server
:return RustClanInfo: The clan info. Will be None if not in a clan
"""
raise NotImplementedError("Not Implemented")

async def get_clan_chat(self) -> List[RustClanMessage]:
"""
Gets the clan chat from the server
:return List[RustClanMessage]: The clan chat messages
"""
raise NotImplementedError("Not Implemented")

async def send_clan_message(self, message: str) -> None:
"""
Sends a message to the clan chat
:param message: The message to send
"""
raise NotImplementedError("Not Implemented")

async def set_clan_motd(self, message: str) -> None:
"""
Sets the clan MOTD
:param message: The message to set
"""
raise NotImplementedError("Not Implemented")
9 changes: 8 additions & 1 deletion rustplus/api/remote/events/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
from .registered_listener import RegisteredListener
from .events import EntityEvent, TeamEvent, ChatEvent, MarkerEvent, ProtobufEvent
from .events import (
EntityEvent,
TeamEvent,
ChatEvent,
MarkerEvent,
ProtobufEvent,
ClanInfoEvent,
)
from .event_loop_manager import EventLoopManager
from .event_handler import EventHandler
27 changes: 25 additions & 2 deletions rustplus/api/remote/events/event_handler.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from typing import Set, Union

from ...structures import RustChatMessage, RustClanInfo
from ....utils import ServerID
from .events import EntityEvent, TeamEvent, ChatEvent, ProtobufEvent
from .events import EntityEvent, TeamEvent, ChatEvent, ProtobufEvent, ClanInfoEvent
from .registered_listener import RegisteredListener
from ..rustplus_proto import AppMessage

Expand Down Expand Up @@ -33,7 +34,29 @@ async def run_team_event(app_message: AppMessage, server_id: ServerID) -> None:
async def run_chat_event(app_message: AppMessage, server_id: ServerID) -> None:
handlers: Set[RegisteredListener] = ChatEvent.handlers.get_handlers(server_id)
for handler in handlers.copy():
await handler.get_coro()(ChatEvent(app_message))
message = RustChatMessage(app_message.broadcast.team_message.message)
await handler.get_coro()(ChatEvent(message, False, None))

@staticmethod
async def run_clan_chat_event(app_message: AppMessage, server_id: ServerID) -> None:
handlers: Set[RegisteredListener] = ChatEvent.handlers.get_handlers(server_id)
for handler in handlers.copy():
message = RustChatMessage(app_message.broadcast.clan_message.message)
await handler.get_coro()(
ChatEvent(message, True, app_message.broadcast.clan_message.clan_id)
)

@staticmethod
async def run_clan_info_event(app_message: AppMessage, server_id: ServerID) -> None:
handlers: Set[RegisteredListener] = ClanInfoEvent.handlers.get_handlers(
server_id
)
for handler in handlers.copy():
await handler.get_coro()(
ClanInfoEvent(
RustClanInfo(app_message.broadcast.clan_changed.clan_info)
)
)

@staticmethod
async def run_proto_event(byte_data: bytes, server_id: ServerID) -> None:
Expand Down
31 changes: 27 additions & 4 deletions rustplus/api/remote/events/events.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import List
from typing import List, Union

from ..rustplus_proto import AppMessage, AppEntityPayloadItem
from ...structures import RustChatMessage
from ...structures import RustChatMessage, RustClanInfo
from ...structures.rust_team_info import RustTeamInfo
from ...structures.rust_marker import RustMarker
from .handler_list import HandlerList, EntityHandlerList
Expand Down Expand Up @@ -45,13 +45,25 @@ def team_info(self) -> RustTeamInfo:
class ChatEvent:
handlers = HandlerList()

def __init__(self, app_message: AppMessage) -> None:
self._message = RustChatMessage(app_message.broadcast.team_message.message)
def __init__(
self, message: RustChatMessage, is_clan: bool, clan_id: Union[int, None]
) -> None:
self._message = message
self._is_clan = is_clan
self._clan_id = clan_id

@property
def message(self) -> RustChatMessage:
return self._message

@property
def is_clan(self) -> bool:
return self._is_clan

@property
def clan_id(self) -> Union[int, None]:
return self._clan_id


class EntityEvent:
handlers = EntityHandlerList()
Expand Down Expand Up @@ -124,3 +136,14 @@ def __init__(self, byte_data) -> None:
@property
def byte_data(self) -> bytes:
return self._byte_data


class ClanInfoEvent:
handlers = HandlerList()

def __init__(self, clan_info: RustClanInfo) -> None:
self._clan_info = clan_info

@property
def clan_info(self) -> RustClanInfo:
return self._clan_info
2 changes: 1 addition & 1 deletion rustplus/api/remote/rustplus_proto/rustplus.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 23 additions & 2 deletions rustplus/api/remote/rustws.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ async def connect(
)
address += f"?v={str(self.magic_value)}"
self.connection = await connect(
address, close_timeout=0, ping_interval=None, max_size=1_000_000_000
address,
close_timeout=0,
ping_interval=None,
max_size=1_000_000_000,
)
self.connected_time = time.time()

Expand Down Expand Up @@ -228,6 +231,12 @@ async def handle_message(self, app_message: AppMessage) -> None:
# This means that the team of the current player has changed
await EventHandler.run_team_event(app_message, self.server_id)

elif self.is_clan_message(app_message):
await EventHandler.run_clan_chat_event(app_message, self.server_id)

elif self.is_clan_change_info(app_message):
await EventHandler.run_clan_info_event(app_message, self.server_id)

elif self.is_message(app_message):
# This means that a message has been sent to the team chat

Expand Down Expand Up @@ -289,6 +298,18 @@ def is_message(app_message: AppMessage) -> bool:
app_message.broadcast.team_message.message
)

@staticmethod
def is_clan_message(app_message: AppMessage) -> bool:
return betterproto.serialized_on_wire(
app_message.broadcast.clan_message.message
)

@staticmethod
def is_clan_change_info(app_message: AppMessage) -> bool:
return betterproto.serialized_on_wire(
app_message.broadcast.clan_changed.clan_info
)

@staticmethod
def is_camera_broadcast(app_message: AppMessage) -> bool:
return betterproto.serialized_on_wire(app_message.broadcast.camera_rays)
Expand Down Expand Up @@ -329,7 +350,7 @@ def error_present(message) -> bool:
"""
Checks message for error
"""
return message != ""
return message != "" and "clan" not in message

@staticmethod
async def run_coroutine_non_blocking(coroutine: Coroutine) -> Task:
Expand Down
58 changes: 58 additions & 0 deletions rustplus/api/rust_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
RustEntityInfo,
RustContents,
RustItem,
RustClanInfo,
RustClanMessage,
)
from .remote.rustplus_proto import (
AppEmpty,
Expand Down Expand Up @@ -407,3 +409,59 @@ async def get_tc_storage_contents(

async def get_camera_manager(self, cam_id: str) -> CameraManager:
return await self.remote.create_camera_manager(cam_id)

async def get_clan_info(self) -> RustClanInfo:
await self._handle_ratelimit()

app_request = self._generate_protobuf()
app_request.get_clan_info = AppEmpty()

await self.remote.send_message(app_request)

app_message = await self.remote.get_response(app_request.seq, app_request)

if app_message.response.error.error != "":
return None

return RustClanInfo(app_message.response.clan_info)

async def get_clan_chat(self) -> List[RustClanMessage]:
await self._handle_ratelimit()

app_request = self._generate_protobuf()
app_request.get_clan_chat = AppEmpty()

await self.remote.send_message(app_request)

app_message = await self.remote.get_response(app_request.seq, app_request)

return [
RustClanMessage(message)
for message in app_message.response.clan_chat.messages
]

async def send_clan_message(self, message: str) -> None:
await self._handle_ratelimit(2)

app_send_message = AppSendMessage()
app_send_message.message = str(message)

app_request = self._generate_protobuf()
app_request.send_clan_message = app_send_message

await self.remote.add_ignored_response(app_request.seq)

await self.remote.send_message(app_request)

async def set_clan_motd(self, message: str) -> None:
await self._handle_ratelimit()

app_send_message = AppSendMessage()
app_send_message.message = str(message)

app_request = self._generate_protobuf()
app_request.set_clan_motd = app_send_message

await self.remote.add_ignored_response(app_request.seq)

await self.remote.send_message(app_request)
2 changes: 2 additions & 0 deletions rustplus/api/structures/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
from .rust_contents import RustContents
from .rust_item import RustItem
from .util import Vector
from .rust_clan_info import RustClanInfo
from .rust_clan_message import RustClanMessage
Loading

0 comments on commit 2a36a42

Please sign in to comment.