Hi!

I was going through legacy-login.py today and tried to convert it into 
some example how a message system could be used. This is probably not how 
the existing interface looks like right now but I tried to think of how I 
personlly would use one. Of course this is not the best or only way and I 
am also not sure in certain cases how to model it best. I especially 
dislike that the Region object now has the agent id and not the agent. 
But I guess we have to talk about the id and how this might look like in 
a global virtual world anyway.

We maybe can use this as the start of some discussion. One issue might be 
to get everything thread safe and be as stateless as possible.

The general idea here was to start with the central thing we have, a 
Message. This might be put into a Packet which basically adds the header 
and has some state about it. It might store whether it got an ack or not.
Then there is the event_queue which basically is the sim endpoint. It 
stores socket etc. and knows about the next sequence number so you don't 
have to. It might also know which packet needs acks and so on.
But this is state and thus problematic if you share this between threads.

But anyway, here is the example code:
 
def loopit(region):
    # event_queue takes care of sequence numbers etc. This is it's state.
    event_queue = UDPEventQueue(region)
    #Alternative: udpeventqueue = IUDPEventQueue(region)
 
    # send UseCircuitCode to sim (region object has everything)
    # it also sends the CompleteAgentMovement
    event_queue.init()
    
    # now we need to send an AgentUpdate packet
    # we do it the raw way here:
    
    
    message = IAgentUpdateMessage(event_queue) # get the message
    # agent_id, session_id will be put in automatically as well
    # as sensible defaults for these properties so you don't have
    # to give them all. Here they are as an example though,
    # I am not sure if this needs to give the types already, we might
    # give tuples etc. and convert it during the packing maybe.
    # some flags might also be modelled higher level like 
    # message.flag_whatever = True
    # but for this one would need to know more about them ;-)
    message.body_rotation = Vector4(0,0,0,0)
    message.head_rotation = Vector4(0,0,0,0)
    message.state(0)
    message.camera_center = Vector3(0,0,0)
    message.camera_at_axis = Vector3(0,0,0)
    message.camera_left_axis = Vector3(0,0,0)
    message.camera_up_axis = Vector3(0,0,0)
    message.far = F32(256)
    message.control_flags = U32(0)
    message.flags = U8(0)
    
    # now we need to put this message into a packet:
    packet = IPacket(message)
    # this will automatically put in message type and sequence
    # number which can be obtained via message -> event_queue
    
    """
    The original code for this:
    
    data_header = pack('>BLB', flags,currentsequence,0x00)
    packed_data_message_ID = pack('>B',0x04)
    packed_data_ID = uuid.UUID(result["agent_id"]).bytes + uuid.UUID
(result["session_id"]).bytes
    packed_data_QuatRots = pack('<ffff', 0.0,0.0,0.0,0.0)+pack('<ffff', 
0.0,0.0,0.0,0.0)  
    packed_data_State = pack('<B', 0x00)
    packed_data_Camera = pack('<fff', 0.0,0.0,0.0)+pack('<fff', 
0.0,0.0,0.0)+pack('<fff', 0.0,0.0,0.0)+pack('<fff', 0.0,0.0,0.0)
    packed_data_Flags = pack('<fLB', 0.0,0x00,0x00)
    """
    
    # it makes sense to actually send the packet.
    # we can maybe do it like this as the event_queue is known:
    packet.send()
    
    # or we can do it like this:
    event_queue.send(packet)
    
    # without too much ZCA we can maybe also do the above like follows:
    message = AgentUpdate(far=512) # fill in message details
    packet = Packet(message)       # create a packet out of this
    event_queue.send(packet)       # send it to the sim
    
    # in this case the send method can only add sequence number etc. 
    # as it's the only instance which knows about it.
    # We can implement it like this though:
    def send(self, packet):
        """send a funky packet"""
        packet.sequence_number = self.sequence_number
        data = packet.serialize() # or ISerialization(packet).serialize()
        self.sock.sendto(data, self.address)
    
    # now we need to send a NameRequest, the original code is:
    """
    packed_data = ""
    fix_ID = int("0xffff0000",16)+ 235
    data_header = pack('>BLB', 0x00,currentsequence,0x00) 
 
 
    for i in range(len(aUUID)):
        packed_data = packed_data+uuid.UUID(aUUID[i]).bytes
 
    packed_data = data_header + pack("L",fix_ID) + pack(">B",len(aUUID)) 
+ packed_data
 
    sock.sendto(packed_data, (host, port)) 
    """
    
    # We can write it as:
    message = NameRequestMessage(uuids=[region.agent_id,])
    # region.agent_id is what we have but it's not nice looking as it
    #  should be agent.id so this needs thinking to be clean. Maybe it
    # even needs thinking inside the protocol ;-)
    # In this case it's also not a direct mapping from message to message
    # object as it needs to deal with variable blocks in this case.
    
    packet = Packet(message)
    event_queue.send(packet)
    
    # now let's wait for packets
    while 1:
        # we might need a different method here as we might get
        # events from the outside to send some packets.
        # Then again there should be enough packets coming in to
        # not endlessly sit in this read_packet() call.
        packet = event_queue.read_packet()
        message = packet.message
        message_id = message.id
        # get some handler for handling this lovely message
        handlers = getUtilitiesFor(IMessageHandler, name=str(message_id))
        for handler in handlers:
            # we give it the message of course but also the event_queue
            # so it maybe can send other packets out.
            handler.handle(event_queue, message)
        
        # now do some bookkeeping like acking messages etc.
        # actually this could also be done in read_packet maybe
        
        # we might need a way to get out of this loop.
        
    
 
    





 
 
 
 
 
 
 """
 
 ORIGINAL CODE:
 
 
 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#Sending packet UseCircuitCode <-- Inits the connection to the sim.
    data = pack('>BLBL',0x00,0x01,00,0xffff0003) + pack
('<L',circuit_code) + uuid.UUID(result["session_id"]).bytes+uuid.UUID
(result["agent_id"]).bytes
    sock.sendto(data, (host, port))
 
#ISending packet CompleteAgentMovement <-- establishes the agent's 
presence
    data = pack('>BLBL',0x00,0x02,00,0xffff00f9) + uuid.UUID(result
["agent_id"]).bytes + uuid.UUID(result["session_id"]).bytes + pack('<L', 
circuit_code)
    sock.sendto(data, (host, port))
 
    sendAgentUpdate(sock, port, host, 3, result)
    aUUID = [result["agent_id"]]
    sendUUIDNameRequest(sock, port, host, 4,aUUID)
#
 
    buf = 100
    i = 0
    trusted_count = 0
    ackable = 0
    trusted_and_ackable = 0
    ack_need_list_changed = False
    seqnum = 5
    lastPingSent = 0 
    trusted = 0
    while 1:
        if ack_need_list_changed:
            ack_need_list_changed = False
            seqnum = seqnum + 1
            sendPacketAck(sock, port, host,seqnum)
            #sendAgentUpdate(sock, port, host, seqnum, result)
            seqnum += 1
        #sendacks()
        i = i + 1
        data,addr = sock.recvfrom(buf)
        t = datetime.now()
        t.strftime("%H:%M:%S")
 """

_______________________________________________
Click here to unsubscribe or manage your list subscription:
https://lists.secondlife.com/cgi-bin/mailman/listinfo/pyogp

Reply via email to