Add ParcelManager to HippoClient

This commit is contained in:
Salad Dais
2024-01-04 21:45:54 +00:00
parent 67db8110a1
commit 9d2087a0fb
4 changed files with 19 additions and 3 deletions

View File

@@ -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

View File

@@ -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():

View File

@@ -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",

View File

@@ -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)