95 lines
3.7 KiB
Python
95 lines
3.7 KiB
Python
|
|
"""
|
||
|
|
Try and diagnose very slow avatar appearance loads when the avatars first come on the scene
|
||
|
|
|
||
|
|
I guess use LEAP or something to detect when things _actually_ declouded.
|
||
|
|
"""
|
||
|
|
from typing import *
|
||
|
|
|
||
|
|
import dataclasses
|
||
|
|
import datetime as dt
|
||
|
|
|
||
|
|
from hippolyzer.lib.base.datatypes import UUID
|
||
|
|
from hippolyzer.lib.base.message.message import Message
|
||
|
|
from hippolyzer.lib.base.objects import Object
|
||
|
|
from hippolyzer.lib.base.templates import PCode
|
||
|
|
from hippolyzer.lib.proxy.addon_utils import BaseAddon, GlobalProperty
|
||
|
|
from hippolyzer.lib.proxy.http_flow import HippoHTTPFlow
|
||
|
|
from hippolyzer.lib.proxy.region import ProxiedRegion
|
||
|
|
from hippolyzer.lib.proxy.sessions import Session, SessionManager
|
||
|
|
|
||
|
|
|
||
|
|
@dataclasses.dataclass
|
||
|
|
class AvatarBakeRequest:
|
||
|
|
requested: dt.datetime
|
||
|
|
received: Optional[dt.datetime] = None
|
||
|
|
|
||
|
|
|
||
|
|
@dataclasses.dataclass
|
||
|
|
class AvatarAppearanceRecord:
|
||
|
|
object_received: dt.datetime
|
||
|
|
"""When we learned about the agent as an object"""
|
||
|
|
appearance_received: Optional[dt.datetime] = None
|
||
|
|
"""When AvatarAppearance was first received"""
|
||
|
|
bake_requests: Dict[str, AvatarBakeRequest] = dataclasses.field(default_factory=dict)
|
||
|
|
"""Layer name -> request / response details"""
|
||
|
|
|
||
|
|
|
||
|
|
class AppearanceDelayTrackerAddon(BaseAddon):
|
||
|
|
# Should be able to access this in the REPL
|
||
|
|
# Normally we'd use a session property, but we may not have a proper session context for some requests
|
||
|
|
av_appearance_data: Dict[UUID, AvatarAppearanceRecord] = GlobalProperty(dict)
|
||
|
|
|
||
|
|
def handle_object_updated(self, session: Session, region: ProxiedRegion,
|
||
|
|
obj: Object, updated_props: Set[str], msg: Optional[Message]):
|
||
|
|
if obj.PCode == PCode.AVATAR and obj.FullID not in self.av_appearance_data:
|
||
|
|
self.av_appearance_data[obj.FullID] = AvatarAppearanceRecord(object_received=dt.datetime.now())
|
||
|
|
|
||
|
|
def handle_lludp_message(self, session: Session, region: ProxiedRegion, message: Message):
|
||
|
|
if message.name != "AvatarAppearance":
|
||
|
|
return
|
||
|
|
agent_id = message["Sender"]["ID"]
|
||
|
|
appearance_data = self.av_appearance_data.get(agent_id)
|
||
|
|
if not appearance_data:
|
||
|
|
print(f"Got appearance for {agent_id} without knowing about object?")
|
||
|
|
return
|
||
|
|
|
||
|
|
if appearance_data.appearance_received:
|
||
|
|
return
|
||
|
|
appearance_data.appearance_received = dt.datetime.now()
|
||
|
|
|
||
|
|
def handle_http_request(self, session_manager: SessionManager, flow: HippoHTTPFlow):
|
||
|
|
if not flow.cap_data:
|
||
|
|
return
|
||
|
|
if flow.cap_data.cap_name != "AppearanceService":
|
||
|
|
return
|
||
|
|
|
||
|
|
agent_id = UUID(flow.request.url.split('/')[-3])
|
||
|
|
slot_name = flow.request.url.split('/')[-2]
|
||
|
|
appearance_data = self.av_appearance_data.get(agent_id)
|
||
|
|
if not appearance_data:
|
||
|
|
print(f"Got AppearanceService req for {agent_id} without knowing about object?")
|
||
|
|
return
|
||
|
|
if slot_name in appearance_data.bake_requests:
|
||
|
|
# We already requested this slot before
|
||
|
|
return
|
||
|
|
appearance_data.bake_requests[slot_name] = AvatarBakeRequest(requested=dt.datetime.now())
|
||
|
|
|
||
|
|
def handle_http_response(self, session_manager: SessionManager, flow: HippoHTTPFlow):
|
||
|
|
if not flow.cap_data:
|
||
|
|
return
|
||
|
|
if flow.cap_data.cap_name != "AppearanceService":
|
||
|
|
return
|
||
|
|
|
||
|
|
agent_id = UUID(flow.request.url.split('/')[-3])
|
||
|
|
slot_name = flow.request.url.split('/')[-2]
|
||
|
|
appearance_data = self.av_appearance_data.get(agent_id)
|
||
|
|
if not appearance_data:
|
||
|
|
return
|
||
|
|
slot_details = appearance_data.bake_requests.get(slot_name)
|
||
|
|
if not slot_details:
|
||
|
|
return
|
||
|
|
slot_details.received = dt.datetime.now()
|
||
|
|
|
||
|
|
|
||
|
|
addons = [AppearanceDelayTrackerAddon()]
|