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")
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")
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)))
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)))
def onObjectUpdateSingle(self, packet, ObjectData_block): out_queue = self.out_queue if ObjectData_block['ProfileHollow'] in self._creating_cb: # we use ProfileHollow as a key for our object creation since # its the only way I found to keep some transaction id around and # we dont use the value anyways. self._creating_cb[ObjectData_block["ProfileHollow"]](ObjectData_block["FullID"]) return objdata = ObjectData_block["ObjectData"] obj_uuid = uuid_to_s(ObjectData_block["FullID"]) obj = self.client.region.objects.get_object_from_store(FullID=obj_uuid) if obj and self._eatupdates[obj.LocalID]: self._eatupdates[obj.LocalID]-= 1 return pars = { "OwnerID": str(ObjectData_block["OwnerID"]), "PCode":ObjectData_block["PCode"]} pars['PathBegin'] = ObjectData_block['PathBegin'] * CUT_QUANTA pars['PathEnd'] = (50000-ObjectData_block['PathEnd']) * CUT_QUANTA pars['PathScaleX'] = (200-ObjectData_block['PathScaleX']) * SCALE_QUANTA pars['PathScaleY'] = (200-ObjectData_block['PathScaleY']) * SCALE_QUANTA pars['PathShearX'] = (ObjectData_block['PathShearX']) * SHEAR_QUANTA pars['PathShearY'] = (ObjectData_block['PathShearY']) * SHEAR_QUANTA pars['PathSkew'] = (ObjectData_block['PathSkew']) * SCALE_QUANTA pars['ProfileBegin'] = ObjectData_block['ProfileBegin'] * CUT_QUANTA pars['ProfileEnd'] = (50000-ObjectData_block['ProfileEnd']) * CUT_QUANTA pars['PathCurve'] = ObjectData_block['PathCurve'] pars['ProfileCurve'] = ObjectData_block['ProfileCurve'] pars['ProfileHollow'] = ObjectData_block['ProfileHollow'] * HOLLOW_QUANTA pars['PathRadiusOffset'] = ObjectData_block['PathRadiusOffset'] * SCALE_QUANTA pars['PathRevolutions'] = (ObjectData_block['PathRevolutions']) * REV_QUANTA+1.0 pars['PathTaperX'] = (ObjectData_block['PathTaperX']) * TAPER_QUANTA pars['PathTaperY'] = (ObjectData_block['PathTaperY']) * TAPER_QUANTA pars['PathTwist'] = ObjectData_block['PathTwist'] * SCALE_QUANTA pars['PathTwistBegin'] = ObjectData_block['PathTwistBegin'] * SCALE_QUANTA namevalue = NameValueList(ObjectData_block['NameValue']) if namevalue._dict: pars['NameValues'] = namevalue._dict if "Scale" in ObjectData_block.var_list: scale = ObjectData_block["Scale"] if obj: obj.scale = v3_to_list(scale) out_queue.put(['scale', obj_uuid, v3_to_list(scale)]) parent_id = ObjectData_block["ParentID"] args = (obj_uuid, pars, objdata, parent_id) if parent_id: parent = self.client.region.objects.get_object_from_store(LocalID=parent_id) if parent: pars["ParentID"] = str(parent.FullID) else: self._parent_cb[parent_id].append((self.finishObjectUpdate, args)) return else: pars["ParentID"] = "" self.finishObjectUpdate(*args) if obj: for cb, cb_args in self._parent_cb[obj.LocalID]: cb(*cb_args) del self._parent_cb[obj.LocalID]