diff --git a/pyogp/lib/base/examples/sample_appearance_management.py b/pyogp/lib/base/examples/sample_appearance_management.py new file mode 100644 index 0000000..f71f932 --- /dev/null +++ b/pyogp/lib/base/examples/sample_appearance_management.py @@ -0,0 +1,125 @@ +#!/usr/bin/python +""" +@file sample_appearance_management.py +@date 2009-03-06 +Contributors can be viewed at: +http://svn.secondlife.com/svn/linden/projects/2008/pyogp/CONTRIBUTORS.txt + +$LicenseInfo:firstyear=2008&license=apachev2$ + +Copyright 2008, Linden Research, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"). +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 +or in +http://svn.secondlife.com/svn/linden/projects/2008/pyogp/LICENSE.txt + +$/LicenseInfo$ +""" + +# standard +import re +import getpass, sys, logging +from optparse import OptionParser + +# related +from eventlet import api + +# pyogp +from pyogp.lib.base.agent import Agent +from pyogp.lib.base.settings import Settings + + +def login(): + """ login an to a login endpoint """ + + parser = OptionParser() + + logger = logging.getLogger("pyogp.lib.base.example") + + parser.add_option("-l", "--loginuri", dest="loginuri", default="https://login.aditi.lindenlab.com/cgi-bin/login.cgi", + help="specified the target loginuri") + parser.add_option("-r", "--region", dest="region", default=None, + help="specifies the region to connect to") +#http://ec2-75-101-203-98.compute-1.amazonaws.com:9000 + parser.add_option("-q", "--quiet", dest="verbose", default=True, action="store_false", + help="enable verbose mode") + + + (options, args) = parser.parse_args() + + if options.verbose: + console = logging.StreamHandler() + console.setLevel(logging.DEBUG) # seems to be a no op, set it for the logger + formatter = logging.Formatter('%(asctime)-30s%(name)-30s: %(levelname)-8s %(message)s') + console.setFormatter(formatter) + logging.getLogger('').addHandler(console) + + # setting the level for the handler above seems to be a no-op + # it needs to be set for the logger, here the root logger + # otherwise it is NOTSET(=0) which means to log nothing. + logging.getLogger('').setLevel(logging.DEBUG) + else: + print "Attention: This script will print nothing if you use -q. So it might be boring to use it like that ;-)" + + # example from a pure agent perspective + + #grab a password! + password = getpass.getpass() + + # let's disable inventory handling and object tracking for this example + settings = Settings() + settings.ENABLE_INVENTORY_MANAGEMENT = False + settings.ENABLE_OBJECT_TRACKING = False + + #First, initialize the agent + client = Agent(settings = settings) + + # Now let's log it in + api.spawn(client.login, options.loginuri, args[0], args[1], password, start_location = options.region, connect_region = True) + + # wait for the agent to connect to it's region + while client.connected == False: + api.sleep(0) + + while client.region.connected == False: + api.sleep(0) + + # do sample script specific stuff here + print "This is not at all working yet, please come back later. (Hint. Ctrl-C)" + client.logout() + + # Not yet working it seems, what's up? + # client.appearance.request_agent_wearables() + + while client.running: + api.sleep(0) + + print '' + print '' + print 'At this point, we have an Agent object, Inventory dirs, and with a Region attribute' + print 'Agent attributes:' + for attr in client.__dict__: + print attr, ':\t\t\t', client.__dict__[attr] + print '' + print '' + ''' + print 'Objects being tracked: %s' % len(client.region.objects.object_store) + print '' + print '' + for _object in client.region.objects.object_store: + print 'ID:', _object.ID, '\tUUID: ', _object.FullID + print '' + print '' + print 'Region attributes:' + for attr in client.region.__dict__: + print attr, ':\t\t\t', client.region.__dict__[attr] + ''' + +def main(): + return login() + +if __name__=="__main__": + main() diff --git a/pyogp/lib/base/examples/sample_inventory_handling.py b/pyogp/lib/base/examples/sample_inventory_handling.py index 9ca8862..6f31ede 100644 --- a/pyogp/lib/base/examples/sample_inventory_handling.py +++ b/pyogp/lib/base/examples/sample_inventory_handling.py @@ -23,6 +23,7 @@ $/LicenseInfo$ import re import getpass, sys, logging from optparse import OptionParser +import time # related from eventlet import api @@ -89,8 +90,35 @@ def login(): # for folders whose parent = root folder aka My Inventory, request their contents [client.inventory._request_folder_contents(folder.FolderID) for folder in client.inventory.folders if folder.ParentID == client.inventory.inventory_root.FolderID] - while client.running: - api.sleep(0) + #while client.running: + #api.sleep(0) + + # next, let's wait 30 seconds and FetchInventory for items we know about + now = time.time() + start = now + while now - start < 30 and client.running: + api.sleep() + now = time.time() + + ''' + folders = [folder for folder in client.inventory.folders if len(folder.inventory) > 0] + + for inventory in folders: + print str(type(inventory)) + + known_inventory_ids = [inventory.ItemID for inventory in folders if str(type(inventory)) == ''] + + # let's just grab the first five (because that's not an unreasonable number) + client.inventory.request_inventory_by_id(known_inventory_ids[0-4]) + ''' + + # next, let's wait another 30 seconds then bail + now = time.time() + start = now + while now - start < 30 and client.running: + api.sleep() + + client.logout() print '' print '' diff --git a/pyogp/lib/base/inventory.py b/pyogp/lib/base/inventory.py index 2c26915..29e1cad 100644 --- a/pyogp/lib/base/inventory.py +++ b/pyogp/lib/base/inventory.py @@ -76,6 +76,9 @@ class Inventory(object): onInventoryDescendents_received = self.packet_handler._register('InventoryDescendents') onInventoryDescendents_received.subscribe(onInventoryDescendents, self) + onFetchInventoryReply_received = self.packet_handler._register('FetchInventoryReply') + onFetchInventoryReply_received.subscribe(onFetchInventoryReply, self) + if self.settings.LOG_VERBOSE: log(INFO, "Initializing inventory storage") def _parse_folders_from_login_response(self): @@ -104,10 +107,14 @@ class Inventory(object): self.folders[index[0]].inventory[inventory_index[0]] = inventory_item + if self.settings.LOG_VERBOSE: log(DEBUG, 'Replacing a stored inventory item: %s for agent \'%s\'' % (inventory_item.ItemID, self.agent.agent_id)) + except: self.folders[index[0]].inventory.append(inventory_item) + if self.settings.LOG_VERBOSE: log(DEBUG, 'Storing a new inventory item: %s in agent \'%s\'' % (inventory_item.ItemID, self.agent.agent_id)) + def search_inventory_by_id(self, item_id): """ search through all inventory folders for a uuid, return the match, or None if no match """ @@ -117,11 +124,11 @@ class Inventory(object): def _add_inventory_folder(self, folder_data): """ inventory folder data comes from either packets or login """ - if self.settings.LOG_VERBOSE: log(DEBUG, "Adding inventory folder %s" % (folder_data['name'])) - # if it's a dict, we are parsing login response data if type(folder_data) == dict: + if self.settings.LOG_VERBOSE: log(DEBUG, "Adding inventory folder %s" % (folder_data['name'])) + folder = InventoryFolder(folder_data['name'], folder_data['folder_id'], folder_data['parent_id'], folder_data['version'], folder_data['type_default']) self.folders.append(folder) @@ -135,7 +142,9 @@ class Inventory(object): # otherwise, we are adding an InventoryFolder() instance else: - self.folders.append(folder) + if self.settings.LOG_VERBOSE: log(DEBUG, "Adding inventory folder %s" % (folder_data.Name)) + + self.folders.append(folder_data) def display_folder_contents(self, folder_id = None, name = None): """ returns a list of the local representation of a folder's contents """ @@ -163,6 +172,28 @@ class Inventory(object): self.sendFetchInventoryDescendentsPacket(folder_id = folder_id) + def request_inventory_by_id(self, id_list = None): + """ ask for inventory data by id via a list """ + + if id_list != None: + + packet = FetchInventoryPacket() + + # AgentData block + packet.AgentData['AgentID'] = uuid.UUID(str(self.agent.agent_id)) # MVT_LLUUID + packet.AgentData['SessionID'] = uuid.UUID(str(self.agent.session_id)) # MVT_LLUUID + + for inventory_id in id_list: + + InventoryData = {} + InventoryData['OwnerID'] = uuid.UUID(str(self.agent.agent_id)) # MVT_LLUUID + InventoryData['ItemID'] = uuid.UUID(str(inventory_id)) # MVT_LLUUID + + packet.InventoryDataBlocks.append(InventoryData) + + # enqueue the message + self.region.enqueue_message(packet()) + def sendFetchInventoryDescendentsPacket(self, folder_id = None, name = None): """ send a request to the server for folder contents """ @@ -299,3 +330,36 @@ def onInventoryDescendents(packet, inventory): folder = InventoryFolder( _Name, _FolderID, _ParentID, None, _Type) inventory._add_inventory_folder(folder) + +def onFetchInventoryReply(packet, inventory): + + _agent_id = packet.message_data.blocks['AgentData'][0].get_variable('AgentID') + + for InventoryData_block in packet.message_data.blocks['InventoryData']: + + _ItemID = InventoryData_block.get_variable('ItemID').data + _FolderID = InventoryData_block.get_variable('FolderID').data + _CreatorID = InventoryData_block.get_variable('CreatorID').data + _OwnerID = InventoryData_block.get_variable('OwnerID').data + _GroupID = InventoryData_block.get_variable('GroupID').data + _BaseMask = InventoryData_block.get_variable('BaseMask').data + _OwnerMask = InventoryData_block.get_variable('OwnerMask').data + _GroupMask = InventoryData_block.get_variable('GroupMask').data + _EveryoneMask = InventoryData_block.get_variable('EveryoneMask').data + _NextOwnerMask = InventoryData_block.get_variable('NextOwnerMask').data + _GroupOwned = InventoryData_block.get_variable('GroupOwned').data + _AssetID = InventoryData_block.get_variable('AssetID').data + _Type = InventoryData_block.get_variable('Type').data + _InvType = InventoryData_block.get_variable('InvType').data + _Flags = InventoryData_block.get_variable('Flags').data + _SaleType = InventoryData_block.get_variable('SaleType').data + _SalePrice = InventoryData_block.get_variable('SalePrice').data + _Name = InventoryData_block.get_variable('Name').data + _Description = InventoryData_block.get_variable('Description').data + _CreationDate = InventoryData_block.get_variable('CreationDate').data + _CRC = InventoryData_block.get_variable('CRC').data + + inventory_item = InventoryItem(_ItemID, _FolderID, _CreatorID, _OwnerID, _GroupID, _BaseMask, _OwnerMask, _GroupMask, _EveryoneMask, _NextOwnerMask, _GroupOwned, _AssetID, _Type, _InvType, _Flags, _SaleType, _SalePrice, _Name, _Description, _CreationDate, _CRC) + + inventory._add_inventory_item(inventory_item) + diff --git a/pyogp/lib/base/objects.py b/pyogp/lib/base/objects.py index f277588..225547b 100644 --- a/pyogp/lib/base/objects.py +++ b/pyogp/lib/base/objects.py @@ -34,106 +34,106 @@ logger = getLogger('pyogp.lib.base.inventory') log = logger.log class Objects(object): - """ is an Object Manager + """ is an Object Manager - Initialize the event queue client class - >>> objects = Objects() + Initialize the event queue client class + >>> objects = Objects() - Sample implementations: region.py - Tests: tests/test_objects.py - """ + Sample implementations: region.py + Tests: tests/test_objects.py + """ - def __init__(self, agent = None, region = None, settings = None, packet_handler = None): - """ set up the inventory manager """ + def __init__(self, agent = None, region = None, settings = None, packet_handler = None): + """ set up the inventory manager """ - # allow the settings to be passed in - # otherwise, grab the defaults - if settings != None: - self.settings = settings - else: - from pyogp.lib.base.settings import Settings - self.settings = Settings() + # allow the settings to be passed in + # otherwise, grab the defaults + if settings != None: + self.settings = settings + else: + from pyogp.lib.base.settings import Settings + self.settings = Settings() - self.agent = agent - self.region = region + self.agent = agent + self.region = region - # the object store consists of a list - # of Object() instances - self.object_store = [] + # the object store consists of a list + # of Object() instances + self.object_store = [] - # other useful things - self.helpers = Helpers() + # other useful things + self.helpers = Helpers() - # set up callbacks - if self.settings.HANDLE_PACKETS: - if packet_handler != None: - self.packet_handler = packet_handler - else: - self.packet_handler = PacketHandler() + # set up callbacks + if self.settings.HANDLE_PACKETS: + if packet_handler != None: + self.packet_handler = packet_handler + else: + self.packet_handler = PacketHandler() - ''' - onObjectUpdateCached_log = self.packet_handler._register('ObjectUpdateCached') - onObjectUpdateCached_log.subscribe(self.helpers.log_packet, self) - ''' + ''' + onObjectUpdateCached_log = self.packet_handler._register('ObjectUpdateCached') + onObjectUpdateCached_log.subscribe(self.helpers.log_packet, self) + ''' - onObjectUpdate_received = self.packet_handler._register('ObjectUpdate') - onObjectUpdate_received.subscribe(onObjectUpdate, self) + onObjectUpdate_received = self.packet_handler._register('ObjectUpdate') + onObjectUpdate_received.subscribe(onObjectUpdate, self) - onObjectUpdateCached_log = self.packet_handler._register('ObjectUpdateCached') - onObjectUpdateCached_log.subscribe(onObjectUpdateCached, self) + onObjectUpdateCached_log = self.packet_handler._register('ObjectUpdateCached') + onObjectUpdateCached_log.subscribe(onObjectUpdateCached, self) - if self.settings.LOG_VERBOSE: log(INFO, "Initializing object storage") + if self.settings.LOG_VERBOSE: log(INFO, "Initializing object storage") - def store_object(self, _object): - """ append to or replace an object in self.objects """ + def store_object(self, _object): + """ append to or replace an object in self.objects """ - # replace an existing list member, else, append + # replace an existing list member, else, append - try: + try: - index = [self.object_store.index(_object_) for _object_ in self.object_store if _object_.ID == _object.ID] + index = [self.object_store.index(_object_) for _object_ in self.object_store if _object_.ID == _object.ID] - self.object_store[index[0]] = _object + self.object_store[index[0]] = _object - if self.settings.LOG_VERBOSE: log(DEBUG, 'Replacing a stored object: %s in region \'%s\'' % (_object.ID, self.region.SimName)) + if self.settings.LOG_VERBOSE: log(DEBUG, 'Replacing a stored object: %s in region \'%s\'' % (_object.ID, self.region.SimName)) - except: + except: - self.object_store.append(_object) + self.object_store.append(_object) - if self.settings.LOG_VERBOSE: log(DEBUG, 'Stored a new object: %s in region \'%s\'' % (_object.ID, self.region.SimName)) + if self.settings.LOG_VERBOSE: log(DEBUG, 'Stored a new object: %s in region \'%s\'' % (_object.ID, self.region.SimName)) - def get_object_from_store(self, ID = None, FullID = None): - """ searches the store and returns object if stored, None otherwise """ + def get_object_from_store(self, ID = None, FullID = None): + """ searches the store and returns object if stored, None otherwise """ - if ID != None: - _object = [_object for _object in self.object_store if _object.ID == ID] - return _object - elif FullID != None: - [_object for _object in self.object_store if _object.FullID == FullID] - return _object - else: - return None + if ID != None: + _object = [_object for _object in self.object_store if _object.ID == ID] + return _object + elif FullID != None: + [_object for _object in self.object_store if _object.FullID == FullID] + return _object + else: + return None - def request_object_update(self, ID = None, ID_list = None): - """ requests object updates from the simulator + def request_object_update(self, ID = None, ID_list = None): + """ requests object updates from the simulator - accepts a tuple of (ID, CacheMissType), or a list of such tuples - """ + accepts a tuple of (ID, CacheMissType), or a list of such tuples + """ - packet = RequestMultipleObjectsPacket() - packet.AgentData['AgentID'] = uuid.UUID(self.agent.agent_id) - packet.AgentData['SessionID'] = uuid.UUID(self.agent.session_id) + packet = RequestMultipleObjectsPacket() + packet.AgentData['AgentID'] = uuid.UUID(self.agent.agent_id) + packet.AgentData['SessionID'] = uuid.UUID(self.agent.session_id) - if ID != None: + if ID != None: - ObjectData = {} - ObjectData['CacheMissType'] = ID[0] - ObjectData['ID'] = ID[1] + ObjectData = {} + ObjectData['CacheMissType'] = ID[0] + ObjectData['ID'] = ID[1] - packet.ObjectDataBlocks.append(ObjectData) + packet.ObjectDataBlocks.append(ObjectData) - else: + else: for ID in ID_list: @@ -143,78 +143,142 @@ class Objects(object): packet.ObjectDataBlocks.append(ObjectData) - # enqueue the message, send as reliable - self.region.enqueue_message(packet(), True) + # enqueue the message, send as reliable + self.region.enqueue_message(packet(), True) - def create_default_box(self, GroupID = uuid.UUID('00000000-0000-0000-0000-000000000000'), relative_position = (1, 0, 0)): - """ creates the default box, defaulting as 1m to the east, with an option GroupID to set the prim to""" + def create_default_box(self, GroupID = uuid.UUID('00000000-0000-0000-0000-000000000000'), relative_position = (1, 0, 0)): + """ creates the default box, defaulting as 1m to the east, with an option GroupID to set the prim to""" - # self.agent.Position holds where we are. we need to add this tuple to the incoming tuple (vector to a vector) - location_to_rez_x = self.agent.Position.data[0] + relative_position[0] - location_to_rez_y = self.agent.Position.data[1] + relative_position[1] - location_to_rez_z = self.agent.Position.data[2] + relative_position[2] + # self.agent.Position holds where we are. we need to add this tuple to the incoming tuple (vector to a vector) + location_to_rez_x = self.agent.Position.data[0] + relative_position[0] + location_to_rez_y = self.agent.Position.data[1] + relative_position[1] + location_to_rez_z = self.agent.Position.data[2] + relative_position[2] - location_to_rez = (location_to_rez_x, location_to_rez_y, location_to_rez_z) + location_to_rez = (location_to_rez_x, location_to_rez_y, location_to_rez_z) - # not sure what RayTargetID is, send as uuid of zeros - RayTargetID = uuid.UUID('00000000-0000-0000-0000-000000000000') + # not sure what RayTargetID is, send as uuid of zeros + RayTargetID = uuid.UUID('00000000-0000-0000-0000-000000000000') - self.object_add(GroupID = GroupID, PCode = 9, Material = 3, AddFlags = 2, PathCurve = 16, ProfileCurve = 1, PathBegin = 0, PathEnd = 0, PathScaleX = 100, PathScaleY = 100, PathShearX = 0, PathShearY = 0, PathTwist = 0, PathTwistBegin = 0, PathRadiusOffset = 0, PathTaperX = 0, PathTaperY = 0, PathRevolutions = 0, PathSkew = 0, ProfileBegin = 0, ProfileEnd = 0, ProfileHollow = 0, BypassRaycast = 1, RayStart = location_to_rez, RayEnd = location_to_rez, RayTargetID = RayTargetID, RayEndIsIntersection = 0, Scale = (0.5, 0.5, 0.5), Rotation = (0, 0, 0, 1), State = 0) + self.object_add(GroupID = GroupID, PCode = 9, Material = 3, AddFlags = 2, PathCurve = 16, ProfileCurve = 1, PathBegin = 0, PathEnd = 0, PathScaleX = 100, PathScaleY = 100, PathShearX = 0, PathShearY = 0, PathTwist = 0, PathTwistBegin = 0, PathRadiusOffset = 0, PathTaperX = 0, PathTaperY = 0, PathRevolutions = 0, PathSkew = 0, ProfileBegin = 0, ProfileEnd = 0, ProfileHollow = 0, BypassRaycast = 1, RayStart = location_to_rez, RayEnd = location_to_rez, RayTargetID = RayTargetID, RayEndIsIntersection = 0, Scale = (0.5, 0.5, 0.5), Rotation = (0, 0, 0, 1), State = 0) - def object_add(self, PCode, Material, AddFlags, PathCurve, ProfileCurve, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, PathTwist, PathTwistBegin, PathRadiusOffset, PathTaperX, PathTaperY, PathRevolutions, PathSkew, ProfileBegin, ProfileEnd, ProfileHollow, BypassRaycast, RayStart, RayEnd, RayTargetID, RayEndIsIntersection, Scale, Rotation, State, GroupID = uuid.UUID('00000000-0000-0000-0000-000000000000')): - ''' - ObjectAdd - create new object in the world - Simulator will assign ID and send message back to signal - object actually created. + def object_add(self, PCode, Material, AddFlags, PathCurve, ProfileCurve, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, PathTwist, PathTwistBegin, PathRadiusOffset, PathTaperX, PathTaperY, PathRevolutions, PathSkew, ProfileBegin, ProfileEnd, ProfileHollow, BypassRaycast, RayStart, RayEnd, RayTargetID, RayEndIsIntersection, Scale, Rotation, State, GroupID = uuid.UUID('00000000-0000-0000-0000-000000000000')): + ''' + ObjectAdd - create new object in the world + Simulator will assign ID and send message back to signal + object actually created. - AddFlags (see also ObjectUpdate) - 0x01 - use physics - 0x02 - create selected + AddFlags (see also ObjectUpdate) + 0x01 - use physics + 0x02 - create selected - GroupID defaults to (No group active) - ''' + GroupID defaults to (No group active) + ''' - packet = ObjectAddPacket() + packet = ObjectAddPacket() - # build the AgentData block - packet.AgentData['AgentID'] = uuid.UUID(str(self.agent.agent_id)) - packet.AgentData['SessionID'] = uuid.UUID(str(self.agent.session_id)) - packet.AgentData['GroupID'] = uuid.UUID(str(GroupID)) + # build the AgentData block + packet.AgentData['AgentID'] = uuid.UUID(str(self.agent.agent_id)) + packet.AgentData['SessionID'] = uuid.UUID(str(self.agent.session_id)) + packet.AgentData['GroupID'] = uuid.UUID(str(GroupID)) - # build the ObjactData block (it's a Single) - packet.ObjectData['PCode'] = PCode - packet.ObjectData['Material'] = Material - packet.ObjectData['AddFlags'] = AddFlags - packet.ObjectData['PathCurve'] = PathCurve - packet.ObjectData['ProfileCurve'] = ProfileCurve - packet.ObjectData['PathBegin'] = PathBegin - packet.ObjectData['PathEnd'] = PathEnd - packet.ObjectData['PathScaleX'] = PathScaleX - packet.ObjectData['PathScaleY'] = PathScaleY - packet.ObjectData['PathShearX'] = PathShearX - packet.ObjectData['PathShearY'] = PathShearY - packet.ObjectData['PathTwist'] = PathTwist - packet.ObjectData['PathTwistBegin'] = PathTwistBegin - packet.ObjectData['PathRadiusOffset'] = PathRadiusOffset - packet.ObjectData['PathTaperX'] = PathTaperX - packet.ObjectData['PathTaperY'] = PathTaperY - packet.ObjectData['PathRevolutions'] = PathRevolutions - packet.ObjectData['PathSkew'] = PathSkew - packet.ObjectData['ProfileBegin'] = ProfileBegin - packet.ObjectData['ProfileEnd'] = ProfileEnd - packet.ObjectData['ProfileHollow'] = ProfileHollow - packet.ObjectData['BypassRaycast'] = BypassRaycast - packet.ObjectData['RayStart'] = RayStart - packet.ObjectData['RayEnd'] = RayEnd - packet.ObjectData['RayTargetID'] = uuid.UUID(str(RayTargetID)) - packet.ObjectData['RayEndIsIntersection'] = RayEndIsIntersection - packet.ObjectData['Scale'] = Scale - packet.ObjectData['Rotation'] = Rotation - packet.ObjectData['State'] = State + # build the ObjactData block (it's a Single) + packet.ObjectData['PCode'] = PCode + packet.ObjectData['Material'] = Material + packet.ObjectData['AddFlags'] = AddFlags + packet.ObjectData['PathCurve'] = PathCurve + packet.ObjectData['ProfileCurve'] = ProfileCurve + packet.ObjectData['PathBegin'] = PathBegin + packet.ObjectData['PathEnd'] = PathEnd + packet.ObjectData['PathScaleX'] = PathScaleX + packet.ObjectData['PathScaleY'] = PathScaleY + packet.ObjectData['PathShearX'] = PathShearX + packet.ObjectData['PathShearY'] = PathShearY + packet.ObjectData['PathTwist'] = PathTwist + packet.ObjectData['PathTwistBegin'] = PathTwistBegin + packet.ObjectData['PathRadiusOffset'] = PathRadiusOffset + packet.ObjectData['PathTaperX'] = PathTaperX + packet.ObjectData['PathTaperY'] = PathTaperY + packet.ObjectData['PathRevolutions'] = PathRevolutions + packet.ObjectData['PathSkew'] = PathSkew + packet.ObjectData['ProfileBegin'] = ProfileBegin + packet.ObjectData['ProfileEnd'] = ProfileEnd + packet.ObjectData['ProfileHollow'] = ProfileHollow + packet.ObjectData['BypassRaycast'] = BypassRaycast + packet.ObjectData['RayStart'] = RayStart + packet.ObjectData['RayEnd'] = RayEnd + packet.ObjectData['RayTargetID'] = uuid.UUID(str(RayTargetID)) + packet.ObjectData['RayEndIsIntersection'] = RayEndIsIntersection + packet.ObjectData['Scale'] = Scale + packet.ObjectData['Rotation'] = Rotation + packet.ObjectData['State'] = State - # print str(type(packet)) + self.region.enqueue_message(packet(), True) - self.region.enqueue_message(packet(), True) + def update_object_permissions(self, ObjectLocalID_list, Field, Set, Mask, Override = False): + """ update permissions for a list of objects + + This will update a specific bit to a specific value. + """ + + packet = ObjectPermissionsPacket() + + # build the AgentData block + packet.AgentData['AgentID'] = uuid.UUID(str(self.agent.agent_id)) + packet.AgentData['SessionID'] = uuid.UUID(str(self.agent.session_id)) + + packet.HeaderData['Override'] = Override # BOOL, God-bit. + + for _ID in ObjectLocalID_list: + + ObjectData = {} + ObjectData['ObjectLocalID'] = _ID + ObjectData['Field'] = Field # U32 + ObjectData['Set'] = Set # U8 + ObjectData['Mask'] = Mask # S32 + + packet.ObjectDataBlocks.append(ObjectData) + + self.region.enqueue_message(packet()) + + def set_object_name(self, ObjectID_NameMap): + """ update the name of objects + + Accepts a dictionary mapping LocalID to Name. + """ + + packet = ObjectPermissionsPacket() + + # build the AgentData block + packet.AgentData['AgentID'] = uuid.UUID(str(self.agent.agent_id)) + packet.AgentData['SessionID'] = uuid.UUID(str(self.agent.session_id)) + + for ObjectID in ObjectID_NameMap: + + ObjectData = {} + ObjectData['LocalID'] = ObjectID + ObjectData['Name'] = ObjectID_NameMap['ObjectID'] + + packet.ObjectDataBlocks.append(ObjectData) + + def set_object_description(self, ObjectID_DescriptionMap): + """ update the description of objects + + Accepts a dictionary mapping LocalID to Description. + """ + + packet = ObjectPermissionsPacket() + + # build the AgentData block + packet.AgentData['AgentID'] = uuid.UUID(str(self.agent.agent_id)) + packet.AgentData['SessionID'] = uuid.UUID(str(self.agent.session_id)) + + for ObjectID in ObjectID_DescriptionMap: + + ObjectData = {} + ObjectData['LocalID'] = ObjectID + ObjectData['Description'] = ObjectID_NameMap['Description'] + + packet.ObjectDataBlocks.append(ObjectData) class Object(object): """ represents an Object diff --git a/pyogp/lib/base/tests/test_region.py b/pyogp/lib/base/tests/test_region.py index 397a887..afe61cb 100644 --- a/pyogp/lib/base/tests/test_region.py +++ b/pyogp/lib/base/tests/test_region.py @@ -24,6 +24,8 @@ import unittest # pyogp from pyogp.lib.base.exc import * from pyogp.lib.base.region import Region +from pyogp.lib.base.message.packets import AgentDataUpdateRequestPacket, SetStartLocationPacket + # pyogp tests import pyogp.lib.base.tests.config @@ -51,8 +53,8 @@ class TestRegion(unittest.TestCase): def test_enqueue_message(self): - fake_packet = 'fake_packet' - fake_packet2 = 'fake_packet' + fake_packet = AgentDataUpdateRequestPacket() + fake_packet2 = AgentDataUpdateRequestPacket() self.region.enqueue_message(fake_packet) self.region.enqueue_message(fake_packet2) @@ -60,21 +62,21 @@ class TestRegion(unittest.TestCase): self.assertEquals(len(self.region.packet_queue), 2) for data in self.region.packet_queue: - self.assertEquals(('fake_packet', False), data) + self.assertEquals(('', False), (str(type(data[0])), False)) def test_enqueue_urgent_message(self): - fake_packet = 'fake_packet' - fake_packet2 = 'fake_packet' + fake_packet = AgentDataUpdateRequestPacket() + fake_packet2 = AgentDataUpdateRequestPacket() - fake_urgent_packet = 'fake_urgent_packet' + fake_urgent_packet = SetStartLocationPacket() self.region.enqueue_message(fake_packet) self.region.enqueue_message(fake_packet2) self.region.send_message_next(fake_urgent_packet) self.assertEquals(len(self.region.packet_queue), 3) - self.assertEquals(self.region.packet_queue[0], (fake_urgent_packet, False)) + self.assertEquals(self.region.packet_queue[0][0].name, 'SetStartLocation') def test_suite(): from unittest import TestSuite, makeSuite