예제 #1
0
    def _set_value(self, value):
        if self.value_type in (NameValueType.Asset, NameValueType.String):
            self.value = value

        elif self.value_type == NameValueType.F32:
            try:
                self.value = float(value)
            except ValueError:
                logger.warn("Unparsable float in NameValue: %s", value)
                self.value = 0

        elif self.value_type in (NameValueType.S32, NameValueType.U32,
                                 NameValueType.U64):
            try:
                self.value = int(value)
            except ValueError:
                logger.warn("Unparsable int in NameValue: %s", value)
                self.value = 0

        elif self.value_type == NameValueType.Vector3:
            try:
                self.value = Vector3.parse(value)
            except ValueError:
                self.value = Vector3(X=0, Y=0, Z=0)

        else:
            self.value = None
            logger.warn("Unknown value type in NameValue: %s", self.value_type)
예제 #2
0
    def request_join_group_chat(self):
        """ sends an ImprovedInstantMessage packet with the atributes necessary to join a group chat """

        logger.info("Requesting to join group chat session for \'%s\'" %
                    (self.GroupName))

        _AgentID = self.agent.agent_id
        _SessionID = self.agent.session_id
        _FromGroup = False
        _ToAgentID = self.GroupID
        _ParentEstateID = 0
        _RegionID = UUID()
        _Position = Vector3()
        _Offline = 0
        _Dialog = ImprovedIMDialogue.SessionGroupStart
        _ID = self.GroupID
        _Timestamp = 0
        _FromAgentName = self.agent.Name()
        _Message = 'Message' ''
        _BinaryBucket = ''

        self.agent.send_ImprovedInstantMessage(_AgentID, _SessionID,
                                               _FromGroup, _ToAgentID,
                                               _ParentEstateID, _RegionID,
                                               _Position, _Offline, _Dialog,
                                               _ID, _Timestamp, _FromAgentName,
                                               _Message, _BinaryBucket)
예제 #3
0
def unpack_v3(data, offset, min, max):
    vector3 = Vector3(X=Helpers.packed_u16_to_float(data, offset, min, max),
                      Y=Helpers.packed_u16_to_float(data, offset + 2, min,
                                                    max),
                      Z=Helpers.packed_u16_to_float(data, offset + 4, min,
                                                    max))
    return vector3
예제 #4
0
 def sendLocalTeleport(self, agent, pos):
     client = self.manager.client
     if not agent.FullID == client.agent_id:
         print("Trying to move an agent for other user")
     t_id = uuid.uuid4()
     invoice_id = UUID()
     client.teleport(region_handle=client.region.RegionHandle,
                     position=Vector3(X=pos[0], Y=pos[1], Z=pos[2]))
예제 #5
0
 def onImprovedTerseObjectUpdate(self, packet):
     client = self.manager.client
     for packet_ObjectData in packet['ObjectData']:
         data = packet_ObjectData['Data']
         localID = struct.unpack("<I", data[0:4])[0]
         naaliProto = False
         if len(data) == 30:
             is_avatar = True
             naaliProto = True
             idx = 4
         else:
             attachPoint = struct.unpack("<b", data[4])[0]
             is_avatar = struct.unpack("<?", data[5])[0]
             idx = 6
             if is_avatar:
                 collisionPlane = Quaternion(data[idx:idx + 16])
                 idx += 16
             minlen = idx + 12 + 6 + 6 + 6 + 8
             if is_avatar:
                 minlen += 16
             if len(data) < minlen:
                 data = data + ('\0' * (minlen - len(data)))
         pos = Vector3(data[idx:idx + 12])
         idx += 12
         vel = unpack_v3(data, idx, -128.0, 128.0)
         idx += 6
         if not naaliProto:
             accel = unpack_v3(data, idx, -64.0, 64.0)
             idx += 6
         rot = unpack_q(data, idx)
         idx += 8
         if not naaliProto:
             angular_vel = unpack_v3(data, idx, -64.0, 64.0)
         if is_avatar:
             obj = client.region.objects.get_avatar_from_store(
                 LocalID=localID)
             if not obj:
                 print("cant find avatar!!")
         else:
             obj = client.region.objects.get_object_from_store(
                 LocalID=localID)
         # print("onImprovedTerseObjectUpdate", localID, pos, vel, accel, obj)
         if obj:
             if self._eatupdates[obj.LocalID]:
                 self._eatupdates[obj.LocalID] -= 1
                 return
             obj_uuid = str(obj.FullID)
             obj.pos = v3_to_list(pos)
             obj.rot = q_to_list(rot)
             if obj_uuid and obj.pos and obj.rot:
                 self.out_queue.put(
                     ['pos', obj_uuid,
                      v3_to_list(pos),
                      q_to_list(rot)])
             else:
                 print("not avatar update")
         else:
             print("cant find object")
예제 #6
0
 def get_size(self):
     """
     Computes the size of the avatar, bases off of libomv's implementation for now.
     """
     height = 1.706 + (self.visualParams[692].value*0.1918) + (self.visualParams[842].value*0.0375) + \
              (self.visualParams[33].value*0.12022) + (self.visualParams[682].value*0.01117) + \
              (self.visualParams[756].value*0.038) + (self.visualParams[198].value*0.08) + \
              (self.visualParams[503].value*0.07)
     return Vector3(X=0.45, Y=0.60, Z=height)
예제 #7
0
    def degrab(self, objectID,  
             uvCoord = Vector3(), stCoord = Vector3(), faceIndex=0,
             position=Vector3(), normal=Vector3(), binormal=Vector3()):
            
        packet = Message('ObjectDeGrab',
                        Block('AgentData',
                            AgentID = self.agent_id,
                            SessionID = self.session_id),
                        Block('ObjectData',
                            LocalID = objectID),
                        [Block('SurfaceInfo',
                              UVCoord = uvCoord,
                              STCoord = stCoord,
                              FaceIndex = faceIndex,
                              Position = position,
                              Normal = normal,
                              Binormal = binormal)])

        self.region.enqueue_message(packet)      
예제 #8
0
    def test_can_teleport(self):
        """
        Tests teleport by teleporting to a new location and verifying position
        has changed
        """
        old_pos = Vector3(X=client.Position.X,
                          Y=client.Position.Y,
                          Z=client.Position.Z)
        new_pos = Vector3(X=client.Position.X + 5,
                          Y=client.Position.Y + 5,
                          Z=client.Position.Z)
        client.teleport(region_handle=client.region.RegionHandle,
                        position=new_pos)
        api.sleep(5)  # wait for object update
        self.assertFalse(client.Position.X == old_pos.X and \
                         client.Position.Y == old_pos.Y and \
                         client.Position.Z == old_pos.Z)

        client.teleport(region_handle=client.region.RegionHandle,
                        position=old_pos)
예제 #9
0
 def test_physics(self):
     """
     Physics by flying up, stopping, and verify avatar's position changes
     every second over 5 seconds.
     """
     client.fly()
     client.up()
     api.sleep(3)
     old_pos = Vector3(X=client.Position.X,
                       Y=client.Position.Y,
                       Z=client.Position.Z)
     client.up(False)
     client.fly(False)
     api.sleep(5)
     new_pos = Vector3(X=client.Position.X,
                       Y=client.Position.Y,
                       Z=client.Position.Z)
     self.assertFalse(new_pos.X == old_pos.X and \
                      new_pos.Y == old_pos.Y and \
                      new_pos.Z == old_pos.Z)
예제 #10
0
    def __init__(self, params):
        """ initialize the Home object by parsing the data passed in """

        # eval(params) would be nice, but fails to parse the string the way one thinks it might
        items =  params.split(', \'')

        # this creates:
        #   self.region_handle
        #   self.look_at
        #   self.position
        for i in items:
            i = re.sub(r'[\"\{}\'"]', '', i)
            i = i.split(':')
            setattr(self, i[0], eval(re.sub('r', '', i[1])))

        self.global_x = self.region_handle[0]
        self.global_y = self.region_handle[1]

        # convert the position and lookat to a Vector3 instance
        self.look_at = Vector3(X=self.look_at[0], Y=self.look_at[1], Z=self.look_at[2])
        self.position = Vector3(X=self.position[0], Y=self.position[1], Z=self.position[2])
예제 #11
0
    def test_onObjectUpdate_selected(self):

        self.object_store.agent = Agent()
        fake_uuid = UUID()
        fake_uuid.random()
        packet = Message(
            'ObjectUpdate', Block('RegionData', RegionHandle=0,
                                  TimeDilation=0),
            Block('ObjectData',
                  ID=1,
                  State=1,
                  FullID=fake_uuid,
                  CRC=0,
                  PCode=0,
                  Material=0,
                  ClickAction=0,
                  Scale=Vector3(X=0.0, Y=0.0, Z=0.0),
                  ObjectData='',
                  ParentID=fake_uuid,
                  UpdateFlags=0,
                  ProfileCurve=0,
                  PathBegin=0.0,
                  PathEnd=0.0,
                  PathScaleX=0.0,
                  PathScaleY=0.0,
                  PathShearX=0.0,
                  PathShearY=0.0,
                  PathTwist=-1,
                  PathTwistBegin=-1,
                  PathRadiusOffset=-1,
                  PathTaperX=-1,
                  PathTaperY=-1,
                  PathRevolutions=0,
                  PathSkew=-1,
                  ProfileBegin=0,
                  ProfileEnd=0,
                  ProfileHollow=0,
                  TextureEntry='',
                  TextureAnim='',
                  NameValue='Test',
                  Data='',
                  Text='',
                  TextColor=0x0,
                  MedialURL=''))

        def callback(payload):
            self.data.append("foo")

        object_handler = self.object_store.agent.events_handler.register(
            "ObjectSelected")
        object_handler.subscribe(callback)
        self.object_store.region.message_handler.handle(packet)
        self.assertTrue(self.data.pop, "foo")
예제 #12
0
    def finishObjectUpdate(self, obj_uuid, pars, objdata, parent_id):
        if not 'ParentID' in pars:
            parent = self.client.region.objects.get_object_from_store(
                LocalID=parent_id)
            pars["ParentID"] = str(parent.FullID)

        obj = self.client.region.objects.get_object_from_store(FullID=obj_uuid)
        out_queue = self.out_queue
        out_queue.put(['props', obj_uuid, pars])
        if len(objdata) == 48:
            pos_vector = Vector3(objdata)
            vel = Vector3(objdata[12:])
            acc = Vector3(objdata[24:])
            rot = Quaternion(objdata[36:])
            if obj:
                obj.pos = v3_to_list(pos_vector)
                obj.rot = q_to_list(rot)
            out_queue.put(
                ['pos', obj_uuid,
                 v3_to_list(pos_vector),
                 q_to_list(rot)])
        elif len(objdata) == 12:
            if True:
                # position only packed as 3 floats
                pos = Vector3(objdata)
                if obj:
                    obj.pos = v3_to_list(pos)
                out_queue.put(['pos', obj_uuid, v3_to_list(pos)])
            elif ObjectData_block.Type in [4, 20, 12, 28]:
                # position only packed as 3 floats
                scale = Vector3(objdata)
                out_queue.put(['scale', obj_uuid, v3_to_list(scale)])
            elif ObjectData_block.Type in [2, 10]:
                # rotation only packed as 3 floats
                rot = Quaternion(objdata)
                out_queue.put(['rot', obj_uuid, q_to_list(rot)])

        else:
            # missing sizes: 28, 40, 44, 64
            self.logger.debug("Unparsed update of size " + str(len(objdata)))
예제 #13
0
 def test_fly(self):
     """
     Tests flying by flying for 5 seconds and verifying position change
     """
     old_pos = Vector3(X=client.Position.X,
                       Y=client.Position.Y,
                       Z=client.Position.Z)
     client.fly()
     api.sleep(5)
     self.assertFalse(client.Position.X == old_pos.X and \
                      client.Position.Y == old_pos.Y and \
                      client.Position.Z == old_pos.Z)
     client.fly(False)
예제 #14
0
    def chat(self, Message=None):
        """ sends an instant message to another avatar

        wraps send_ImprovedInstantMessage with some handy defaults """

        if self.session_id == None:
            self.request_join_group_chat()

            Wait(5)

        if self.session_id == None:
            logger.warning(
                "Failed to start chat session with group %s. Please try again later."
                % (self.GroupName))
            return

        if Message != None:

            _ID = self.GroupID
            _AgentID = self.agent.agent_id
            _SessionID = self.agent.session_id
            _FromGroup = False
            _ToAgentID = self.GroupID
            _ParentEstateID = 0
            _RegionID = UUID()
            _Position = Vector3()  # don't send position, send uuid zero
            _Offline = 0
            _Dialog = ImprovedIMDialogue.SessionSend
            _ID = self.GroupID
            _Timestamp = 0
            _FromAgentName = self.agent.Name(
            ) + "\x00"  #struct.pack(">" + str(len(self.agent.Name)) + "c", *(self.agent.Name()))
            _Message = Message + "\x00"  #struct.pack(">" + str(len(Message)) + "c", *(Message))
            _BinaryBucket = "\x00"  # self.GroupName #struct.pack(">" + str(len(self.GroupName)) + "c", *(self.GroupName))

            self.agent.send_ImprovedInstantMessage(
                _AgentID, _SessionID, _FromGroup, _ToAgentID, _ParentEstateID,
                _RegionID, _Position, _Offline, _Dialog, _ID, _Timestamp,
                _FromAgentName, _Message, _BinaryBucket)
예제 #15
0
    def grabUpdate(self, objectID, grabPosition = Vector3(), grabOffset = Vector3(),
             uvCoord = Vector3(), stCoord = Vector3(), faceIndex=0,
             position=Vector3(), normal=Vector3(), binormal=Vector3()):
             
        packet = Message('ObjectGrabUpdate',
                        Block('AgentData',
                            AgentID = self.agent_id,
                            SessionID = self.session_id),
                        Block('ObjectData',
                            LocalID = objectID,
                            GrabOffsetInitial = grabOffset,
                            GrabPostion = grabPosition),
                         [Block('SurfaceInfo',
                              UVCoord = uvCoord,
                              STCoord = stCoord,
                              FaceIndex = faceIndex,
                              Position = position,
                              Normal = normal,
                              Binormal = binormal)])

        self.region.enqueue_message(packet) 
예제 #16
0
    def teleport(self,
                 region_name=None,
                 region_handle=None,
                 region_id=None,
                 landmark_id=None,
                 position=Vector3(X=128, Y=128, Z=128),
                 look_at=Vector3(X=128, Y=128, Z=128)):
        """Initiate a teleport to the specified location. When passing a region name
        it may be necessary to request the destination region handle from the current sim
        before the teleport can start."""

        logger.info('teleport name=%s handle=%s id=%s', str(region_name), str(region_handle), str(region_id))

        # Landmarks are easy, get those out of the way
        if landmark_id:
            logger.info('sending landmark TP request packet')
            packet = Message('TeleportLandmarkRequest',
                             Block('Info',
                                   AgentID = self.agent_id,
                                   SessionID = self.session_id,
                                   LandmarkID = UUID(landmark_id)))
            self.region.enqueue_message(packet)
            return

        # Handle intra-region teleports even by name
        if not region_id and region_name and region_name.lower() == self.region.SimName.lower():
            region_id = self.region.RegionID

        if region_id:

            logger.info('sending TP request packet')

            packet = Message('TeleportRequest', 
                            Block('AgentData', 
                                AgentID = self.agent_id, 
                                SessionID = self.session_id),
                            Block('Info',
                                RegionID = region_id,
                                Position = position,
                                LookAt = look_at))

            self.region.enqueue_message(packet)

        elif region_handle:

            logger.info('sending TP location request packet')

            packet = Message('TeleportLocationRequest', 
                            Block('AgentData', 
                                AgentID = self.agent_id, 
                                SessionID = self.session_id),
                            Block('Info',
                                RegionHandle = region_handle,
                                Position = position,
                                LookAt = look_at))

            self.region.enqueue_message(packet)

        else:
            logger.info("Target region's handle not known, sending map name request")
            # do a region_name to region_id lookup and then request the teleport
            self.map_service.request_handle(
                region_name,
                lambda handle: self.teleport(region_handle=handle, position=position, look_at=look_at))
예제 #17
0
    def __init__(self, settings = None, firstname = '', lastname = '', password = '', agent_id = None, events_handler = None, handle_signals=True):
        """ initialize this agent """

        # allow the settings to be passed in
        # otherwise, grab the defaults
        if settings != None:
            self.settings = settings
        else:
            from pyogp.lib.client.settings import Settings
            self.settings = Settings()

        # allow the eventhandler to be passed in
        # so that applications running multiple avatars
        # may use the same eventhandler

        # otherwise, let's just use our own
        if events_handler != None:
            self.events_handler = events_handler
        else:
            self.events_handler = AppEventsHandler()

        # signal handler to capture erm signals
        if handle_signals:
            self.signal_handler = signal.signal(signal.SIGINT, self.sigint_handler)

        # storage containers for agent attributes
        # we overwrite with what the grid tells us, rather than what
        # is passed in and stored in Login()
        self.firstname = firstname
        self.lastname = lastname
        self.password = password
        self.agent_id = None
        self.session_id = None
        self.local_id = None
        self.secure_session_id = None
        self.name = self.Name()
        self.active_group_powers = None
        self.active_group_name = None
        self.active_group_title = None
        self.active_group_id = None
        self.health = None
        self._login_params = None
        self.circuit_code = None

        # other storage containers
        self.inventory_host = None
        self.agent_access = None
        self.udp_blacklist = None
        self.home = None
        self.inventory = None
        self.start_location = None
        self.group_manager = GroupManager(self, self.settings)
        self.asset_manager = AssetManager(self, self.settings)
        self.map_service = MapService(self, self.settings)

        # additional attributes
        self.login_response = None
        self.connected = False
        self.grid_type = None
        self.running = True
        self.helpers = Helpers()

        # data we store as it comes in from the grid
        self.Position = Vector3()     # this will get updated later, but seed it with 000
        self.LookAt = Vector3()
        self.ActiveGroupID = UUID()

        # populated via ObjectUpdates
        self.FootCollisionPlane = Quaternion() 
        self.Velocity = Vector3()
        self.Acceleration = Vector3()
        self.Rotation = Vector3()
        self.AngularVelocity = Vector3()

        # movement
        self.state = AgentState.Null # typing, editing
        self.control_flags = 0
        self.agent_update_flags = AgentUpdateFlags.Null


        # should we include these here?
        self.agentdomain = None     # the agent domain the agent is connected to if an OGP context
        self.child_regions = []     # all neighboring regions
        self._pending_child_regions = []    # neighbor regions an agent may connect to
        self.region = None          # the host simulation for the agent

        # init AppearanceManager()
        self.appearance = AppearanceManager(self, self.settings)

        # Cache of agent_id->(first_name, last_name); per agent to prevent info leaks
        self.agent_id_map = {}

        if self.settings.LOG_VERBOSE: 
            logger.debug('Initializing agent: %s' % (self))