diff --git a/addon_examples/deformer_helper.py b/addon_examples/deformer_helper.py index 1d225ae..b2456bc 100644 --- a/addon_examples/deformer_helper.py +++ b/addon_examples/deformer_helper.py @@ -152,7 +152,7 @@ class DeformerAddon(BaseAddon): local_anim.LocalAnimAddon.apply_local_anim(session, region, "deformer_addon", anim_data) def handle_rlv_command(self, session: Session, region: ProxiedRegion, source: UUID, - cmd: str, options: List[str], param: str): + behaviour: str, options: List[str], param: str): # An object in-world can also tell the client how to deform itself via # RLV-style commands. @@ -160,9 +160,9 @@ class DeformerAddon(BaseAddon): if param != "force": return - if cmd == "stop_deforming": + if behaviour == "stop_deforming": self.deform_joints.clear() - elif cmd == "deform_joints": + elif behaviour == "deform_joints": self.deform_joints.clear() for joint_data in options: joint_split = joint_data.split("|") diff --git a/addon_examples/local_anim.py b/addon_examples/local_anim.py index 06824b3..4c90c25 100644 --- a/addon_examples/local_anim.py +++ b/addon_examples/local_anim.py @@ -114,15 +114,15 @@ class LocalAnimAddon(BaseAddon): await asyncio.sleep(1.0) def handle_rlv_command(self, session: Session, region: ProxiedRegion, source: UUID, - cmd: str, options: List[str], param: str): + behaviour: str, options: List[str], param: str): # We only handle commands if param != "force": return - if cmd == "stop_local_anim": + if behaviour == "stop_local_anim": self.apply_local_anim(session, region, options[0], new_data=None) return True - elif cmd == "start_local_anim": + elif behaviour == "start_local_anim": self.apply_local_anim_from_file(session, region, options[0]) return True diff --git a/hippolyzer/lib/client/rlv.py b/hippolyzer/lib/client/rlv.py new file mode 100644 index 0000000..c91c94e --- /dev/null +++ b/hippolyzer/lib/client/rlv.py @@ -0,0 +1,51 @@ +from typing import NamedTuple, List, Sequence + +from hippolyzer.lib.base.message.message import Message +from hippolyzer.lib.base.templates import ChatType + + +class RLVCommand(NamedTuple): + behaviour: str + param: str + options: List[str] + + +class RLVParser: + @staticmethod + def is_rlv_message(msg: Message) -> bool: + chat: str = msg["ChatData"]["Message"] + chat_type: int = msg["ChatData"]["ChatType"] + return chat and chat.startswith("@") and chat_type == ChatType.OWNER + + @staticmethod + def parse_chat(chat: str) -> List[RLVCommand]: + assert chat.startswith("@") + chat = chat.lstrip("@") + commands = [] + for command_str in chat.split(","): + if not command_str: + continue + # RLV-style command, `(:;)?(=)?` + # Roughly (?[^:=]+)(:(?