From 9d2087a0fb85299932f6e3b4b08b75dda8db6de4 Mon Sep 17 00:00:00 2001 From: Salad Dais Date: Thu, 4 Jan 2024 21:45:54 +0000 Subject: [PATCH] Add ParcelManager to HippoClient --- client_examples/hello_client.py | 6 ++++++ hippolyzer/lib/client/hippo_client.py | 7 +++++++ hippolyzer/lib/client/parcel_manager.py | 7 +++++-- tests/client/test_parcel_manager.py | 2 +- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/client_examples/hello_client.py b/client_examples/hello_client.py index 4512f3c..4a6688c 100644 --- a/client_examples/hello_client.py +++ b/client_examples/hello_client.py @@ -3,6 +3,7 @@ A simple client that just says hello to people """ import asyncio +import pprint from contextlib import aclosing import os @@ -30,6 +31,11 @@ async def amain(): start_location=os.environ.get("HIPPO_START_LOCATION", "last"), ) print("I'm here") + + # Wait until we have details about parcels and print them + await client.main_region.parcel_manager.parcels_downloaded.wait() + pprint.pprint(client.main_region.parcel_manager.parcels) + await client.send_chat("Hello World!", chat_type=ChatType.SHOUT) client.session.message_handler.subscribe("ChatFromSimulator", _respond_to_chat) # Example of how to work with caps diff --git a/hippolyzer/lib/client/hippo_client.py b/hippolyzer/lib/client/hippo_client.py index 25c719a..bd196ad 100644 --- a/hippolyzer/lib/client/hippo_client.py +++ b/hippolyzer/lib/client/hippo_client.py @@ -29,6 +29,7 @@ from hippolyzer.lib.base.xfer_manager import XferManager from hippolyzer.lib.client.asset_uploader import AssetUploader from hippolyzer.lib.client.inventory_manager import InventoryManager from hippolyzer.lib.client.object_manager import ClientObjectManager, ClientWorldObjectManager +from hippolyzer.lib.client.parcel_manager import ParcelManager from hippolyzer.lib.client.state import BaseClientSession, BaseClientRegion, BaseClientSessionManager @@ -47,6 +48,8 @@ class ClientSettings(Settings): USER_AGENT: str = SettingDescriptor(f"Hippolyzer/v{version('hippolyzer')}") SEND_AGENT_UPDATES: bool = SettingDescriptor(True) """Generally you want to send these, lots of things will break if you don't send at least one.""" + AUTO_REQUEST_PARCELS: bool = SettingDescriptor(True) + """Automatically request all parcel details when connecting to a region""" class HippoCapsClient(CapsClient): @@ -121,6 +124,7 @@ class HippoClientRegion(BaseClientRegion): self.xfer_manager = XferManager(proxify(self), self.session().secure_session_id) self.transfer_manager = TransferManager(proxify(self), session.agent_id, session.id) self.asset_uploader = AssetUploader(proxify(self)) + self.parcel_manager = ParcelManager(proxify(self)) self.objects = ClientObjectManager(self) self._llsd_serializer = LLSDMessageSerializer() self._eq_task: Optional[asyncio.Task] = None @@ -226,6 +230,9 @@ class HippoClientRegion(BaseClientRegion): self.update_caps(await seed_resp.read_llsd()) self._eq_task = asyncio.create_task(self._poll_event_queue()) + + if self.session().session_manager.settings.AUTO_REQUEST_PARCELS: + _ = asyncio.create_task(self.parcel_manager.request_dirty_parcels()) except Exception as e: # Let consumers who were `await`ing the connected signal know there was an error if not self.connected.done(): diff --git a/hippolyzer/lib/client/parcel_manager.py b/hippolyzer/lib/client/parcel_manager.py index 7cb8aa4..44baaf6 100644 --- a/hippolyzer/lib/client/parcel_manager.py +++ b/hippolyzer/lib/client/parcel_manager.py @@ -138,12 +138,13 @@ class ParcelManager: # Append the grid to the neighbour testing queue neighbor_test_queue.append(new_pos) - async def request_parcels_if_dirty(self) -> Tuple[Parcel, ...]: + async def request_dirty_parcels(self) -> Tuple[Parcel, ...]: if self._parcels_dirty: return await self.request_all_parcels() return tuple(self.parcels) async def request_all_parcels(self) -> Tuple[Parcel, ...]: + await self.overlay_complete.wait() # Because of how we build up the parcel index map, it's safe for us to # do this instead of keeping track of seen IDs in a set or similar last_seen_parcel_index = 0 @@ -164,9 +165,11 @@ class ParcelManager: # Wait for all parcel properties to come in await asyncio.gather(*futs) self.parcels_downloaded.set() + self._parcels_dirty = False return tuple(self.parcels) async def request_parcel_properties(self, pos: Vector2) -> Parcel: + await self.overlay_complete.wait() seq_id = self._next_seq # Register a wait on a ParcelProperties matching this seq parcel_props_fut = self._region.message_handler.wait_for( @@ -176,7 +179,7 @@ class ParcelManager: ) # We don't care about when we receive an ack, we only care about when we receive the parcel props _ = self._region.circuit.send_reliable(Message( - "RequestParcelProperties", + "ParcelPropertiesRequest", Block("AgentData", AgentID=self._region.session().agent_id, SessionID=self._region.session().id), Block( "ParcelData", diff --git a/tests/client/test_parcel_manager.py b/tests/client/test_parcel_manager.py index 23eecef..faa6a40 100644 --- a/tests/client/test_parcel_manager.py +++ b/tests/client/test_parcel_manager.py @@ -253,7 +253,7 @@ class TestParcelOverlay(unittest.IsolatedAsyncioTestCase): async def test_request_parcel_properties(self): for msg in self.test_msgs: self.handler.handle(msg) - req_task = asyncio.create_task(self.parcel_manager.request_parcels_if_dirty()) + req_task = asyncio.create_task(self.parcel_manager.request_dirty_parcels()) # HACK: Wait for requests to be sent out await asyncio.sleep(0.01)