Difference between revisions of "Presence Code Python"

From Second Life Wiki
Jump to navigation Jump to search
(changed endian from big to little on AgentUpdate)
(Added reference to used code.)
 
(5 intermediate revisions by 3 users not shown)
Line 1: Line 1:
Extremely incomplete example of how to log an avatar in and establish a presence. So far it only sends enough to temporarily show in-world. More to come....
Extremely incomplete example of how to log an avatar in and establish a presence. So far it only sends enough to temporarily show in-world.


N.B.: the packet ID number of a zero encoded pack is encoded and must be decoded before you can know what packet you are actually dealing with (Thanks John Hurliman/Eddy Stryker).
N.B.: the packet ID number of a zero encoded pack is encoded and must be decoded before you can know what packet you are actually dealing with (Thanks John Hurliman/Eddy Stryker).
Line 5: Line 5:
(based on a sample login script found at [http://www.libsecondlife.org/wiki/Login libsl login].)
(based on a sample login script found at [http://www.libsecondlife.org/wiki/Login libsl login].)


<python>from struct import *
The <code>zerocode</code> Python 2 module used here can be found in [[Zerocode]].
<syntaxhighlight lang="python">from struct import *
from zerocode import  *
from zerocode import  *
import md5
import md5
Line 17: Line 18:
import uuid
import uuid
from makepacketdict import makepacketdict
from makepacketdict import makepacketdict
from datetime import datetime




Line 23: Line 28:
ack_need_list = []
ack_need_list = []


logoutputflag = True
logoutputflag = False


if logoutputflag:
if logoutputflag:
Line 86: Line 91:
    
    
def scheduleacknowledgemessage(data):
def scheduleacknowledgemessage(data):
     if not (ord(data[0])&0x40):
     if not ord(data[0])&0x40:
         print "OOOPS! Got asked to ack a message that shouldn't be acked"
         print "OOOPS! Got asked to ack a message that shouldn't be acked"
          
          
Line 92: Line 97:
     else:
     else:
         ID = data[1:5]
         ID = data[1:5]
         if (ord(data[0])&0x40) & 0x80: ID = zero_decode_ID(ID)
         if (ord(data[0])&0x40) & 0x80: ID = zero_decode_ID(ID) #impossible
         ack_need_list.append(unpack(">L",ID)[0])
         ack_need_list.append(unpack(">L",ID)[0])
         #ack_need_list.append(unpack(">L",data[1:5])[0])
         #ack_need_list.append(unpack(">L",data[1:5])[0])
Line 103: Line 108:
     acksequence = ""
     acksequence = ""
     for msgnum in ack_need_list:
     for msgnum in ack_need_list:
         acksequence = acksequence + pack(">L", msgnum)
         acksequence += pack("<L", msgnum)
      
      
      
      
Line 110: Line 115:
#def sendacks():
#def sendacks():
  #  if len(ack_need_list)>0:
  #  if len(ack_need_list)>0:
#===============================================================================
# {
#    UUIDNameRequest Low NotTrusted Unencoded
#    {
#        UUIDNameBlock    Variable
#        {    ID            LLUUID    }
#    }
# }
#===============================================================================
def sendUUIDNameRequest(sock, port, host, currentsequence,aUUID):
   
    packed_data = ""
    fix_ID = int("ffff0000",16)+ 235
    data_header = pack('>BLB', 0x00,currentsequence,0x00)
   
   
    for x in aUUID:
        packed_data += uuid.UUID(x).bytes
       
    packed_data += pack("L",fix_ID) + pack(">B",len(aUUID)) + packed_data
       
    sock.sendto(packed_data, (host, port))
    return             
 
def sendRegionHandshakeReply(sock, port, host, currentsequence,agentUUID,sessionUUID):
    packed_data = ""
   
    low_ID = "ffff00%2x" % 149
    data_header = pack('>BLB', 0x00,currentsequence,0x00)
    packed_data += uuid.UUID(agentUUID).bytes+uuid.UUID(sessionUUID).bytes+ pack(">L",0x00)
    packed_data = data_header + pack(">L",int(low_ID,16))+packed_data
    sock.sendto(packed_data, (host, port))
    #print "RegionHandshakeReply", ByteToHex(packed_data)
    return
   
 
          
          
def sendAgentUpdate(sock, port, host, currentsequence, result):
def sendAgentUpdate(sock, port, host, currentsequence, result):


#AgentUpdate
#AgentUpdate
     tempacks = packacks()
     tempacks = packacks()
     del ack_need_list[0:]
     del ack_need_list[:]
   
     if tempacks == "":  
     if tempacks == "":  
         flags = 0x00
         flags = 0x00
Line 124: Line 168:
     #print "tempacks is:", ByteToHex(tempacks)   
     #print "tempacks is:", ByteToHex(tempacks)   
          
          
     packed_data_header = pack('>BLB', flags,currentsequence,0x00)
     data_header = pack('>BLB', flags,currentsequence,0x00)
     packed_data_message_ID = pack('>B',0x04)
     packed_data_message_ID = pack('>B',0x04)
     packed_data_ID = uuid.UUID(result["agent_id"]).bytes + uuid.UUID(result["session_id"]).bytes
     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_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_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_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)
     packed_data_Flags = pack('<fLB', 0.0,0x00,0x00)


     encoded_packed_data = zero_encode(packed_data_message_ID+packed_data_ID+packed_data_QuatRots+packed_data_State+packed_data_Camera+packed_data_Flags)
     encoded_packed_data = zero_encode(packed_data_message_ID+packed_data_ID+packed_data_QuatRots+packed_data_State+packed_data_Camera+packed_data_Flags)


     packed_data = packed_data_header + encoded_packed_data+tempacks
     packed_data = data_header + encoded_packed_data+tempacks


  # print "sending AgentUpdate to server",ByteToHex(packed_data_header+zero_decode(encoded_packed_data)+ tempacks)
   
    sock.sendto(packed_data, (host, port))
    return


def sendCompletePingCheck(sock, port, host, currentsequence,data,lastPingSent):
#    print "data from PingCHeck", ByteToHex(data)
   
    data_header = pack('>BLB', 0x00,currentsequence,0x00)
    packed_data_message_ID = pack('>B',0x02)
    packed_data = data_header + packed_data_message_ID+pack('>B', lastPingSent)
    print "CompletePingCheck packet sent:", ByteToHex(packed_data)
    sock.sendto(packed_data, (host, port))
   
    return
   
def sendPacketAck(sock, port, host,currentsequence):


   # print "sending AgentUpdate to server",ByteToHex(packed_data_header+zero_decode(encoded_packed_data)+ tempacks)
    tempacks = packacks()
    templen = len(ack_need_list)
    del ack_need_list[:]
    data_header = pack('>BLB',0x00,currentsequence,0x00)
    packed_data_message_ID = pack('>L',0xFFFFFFFB)
    packed_ack_len = pack('>B',templen)
   
    packed_data = data_header + packed_data_message_ID + packed_ack_len + tempacks
#===============================================================================
#    t = datetime.now()
#    t.strftime("%H:%M:%S")
#   ti = "%02d:%02d:%02d.%06d" % (t.hour,t.minute,t.second,t.microsecond)
#   print ti, "PacketAck packet sent:", ByteToHex(packed_data)
#===============================================================================
    sock.sendto(packed_data, (host, port))
    return
 
def sendLogoutRequest(sock, port, host,seqnum,aUUID,sUUID):
    packed_data = ""
    packed_data_message_ID = pack('>L',0xffff00fc)
    data_header = pack('>BLB', 0x00,seqnum,0x00)
    packed_data += uuid.UUID(aUUID).bytes+uuid.UUID(sUUID).bytes+ pack(">L",0x00)
      
      
    packed_data = data_header + packed_data_message_ID + packed_data
     sock.sendto(packed_data, (host, port))
     sock.sendto(packed_data, (host, port))
     return
     return


def establishpresence(host, port, circuit_code):
def establishpresence(host, port, circuit_code):
Line 156: Line 239:


     sendAgentUpdate(sock, port, host, 3, result)
     sendAgentUpdate(sock, port, host, 3, result)
    aUUID = [result["agent_id"]]
    sendUUIDNameRequest(sock, port, host, 4,aUUID)
#
#


Line 164: Line 249:
     trusted_and_ackable = 0
     trusted_and_ackable = 0
     ack_need_list_changed = False
     ack_need_list_changed = False
     seqnum = 3
     seqnum = 5
     while 1:
    lastPingSent = 0
    trusted = 0
     while True:
         if ack_need_list_changed:
         if ack_need_list_changed:
             ack_need_list_changed = False
             ack_need_list_changed = False
             seqnum = seqnum + 1
             seqnum += 1
             sendAgentUpdate(sock, port, host, seqnum, result)
            sendPacketAck(sock, port, host,seqnum)
              
             #sendAgentUpdate(sock, port, host, seqnum, result)
             seqnum += 1
         #sendacks()
         #sendacks()
         i = i + 1
         i += 1
         data,addr = sock.recvfrom(buf)
         data,addr = sock.recvfrom(buf)
          
         t = datetime.now()
        t.strftime("%H:%M:%S")
 
 
 
         if not data:
         if not data:
             print "Client has exited!"
             print "Client has exited!"
Line 184: Line 276:
             ID = data[6:12]
             ID = data[6:12]
             #print "ID =", ByteToHex(ID)  
             #print "ID =", ByteToHex(ID)  
             if (ord(data[0])&0x80): ID = zero_decode_ID(data[6:12])
             if ord(data[0])&0x80:  
                ID = zero_decode_ID(data[6:12])
               
            if ord(data[0])&0x40:
                scheduleacknowledgemessage(data);
                ack_need_list_changed = True
             #print "ID =", ByteToHex(ID)  
             #print "ID =", ByteToHex(ID)  
             #print "ID =", unpack(">L", ID[:4])
             #print "ID =", unpack(">L", ID[:4])
Line 190: Line 287:
                 if ID[1] == '\xFF':
                 if ID[1] == '\xFF':
                     if ID[2] == '\xFF':
                     if ID[2] == '\xFF':
                         myentry = mypacketdictionary[("Fixed" , int("0x"+ByteToHex(ID[2:4]).replace(' ', ''),16))]
                         myentry = mypacketdictionary[("Fixed" , "0x"+ByteToHex(ID[0:4]).replace(' ', ''))]
                         if (ord(data[0])&0x40):  
                         if myentry[1] == "Trusted":
                             scheduleacknowledgemessage(data);  
                             trusted += 1;
                            ack_need_list_changed = True
                        ti = "%02d:%02d:%02d.%06d" % (t.hour,t.minute,t.second,t.microsecond)
                            print "Message #", i,"Flags: 0x" + test[0], myentry,  "sequence #", unpack(">L",data[1:5]), "ack needed"
                        print ti, "Message #", i, "trusted count is", trusted,"Flags: 0x" + test[0], myentry,  "sequence #", unpack(">L",data[1:5])
                              
                              
                         #if myentry[1] == "Trusted": trusted_count = trusted_count +1;print "number of trusted messages =", trusted_count
                         #if myentry[1] == "Trusted": trusted_count += 1;print "number of trusted messages =", trusted_count
                         #if (ord(data[0])&0x40) and (myentry[1] == "Trusted"): trusted_and_ackable = trusted_and_ackable + 1; print "trusted_and_ackable =", trusted_and_ackable
                         #if ord(data[0])&0x40 and myentry[1] == "Trusted": trusted_and_ackable += 1; print "trusted_and_ackable =", trusted_and_ackable
                         #if (ord(data[0])&0x40): ackable = ackable + 1; print "number of ackable messages = ", ackable
                         #if ord(data[0])&0x40: ackable += 1; print "number of ackable messages = ", ackable
                     else:
                     else:
                         myentry = mypacketdictionary[("Low",int("0x"+ByteToHex(ID[2:4]).replace(' ', ''),16))]
                         myentry = mypacketdictionary[("Low",int(ByteToHex(ID[2:4]).replace(' ', ''),16))]
                         if (ord(data[0])&0x40):  
                         if myentry[1] == "Trusted":
                             scheduleacknowledgemessage(data);  
                             trusted += 1;
                            ack_need_list_changed = True
                        ti = "%02d:%02d:%02d.%06d" % (t.hour,t.minute,t.second,t.microsecond)
                         print "Message #", i,"Flags: 0x" + test[0], myentry,  "sequence #", unpack(">L",data[1:5])
                         print ti, "Message #", i,"trusted count is", trusted,"Flags: 0x" + test[0], myentry,  "sequence #", unpack(">L",data[1:5])
                        if myentry[0] == "UUIDNameReply":
                            pass
                            #print ByteToHex(data)
                            #print data[:28]
                            #print data[28:36],data[38:45]
                        elif myentry[0] == "RegionHandshake":
                            sendRegionHandshakeReply(sock, port, host, seqnum,result["agent_id"],result["session_id"])
                            seqnum += 1
                          
                          
                         #if myentry[1] == "Trusted": trusted_count = trusted_count +1;print "number of trusted messages =", trusted_count
                         #if myentry[1] == "Trusted": trusted_count += 1;print "number of trusted messages =", trusted_count
                         #if (ord(data[0])&0x40) and (myentry[1] == "Trusted"): trusted_and_ackable = trusted_and_ackable + 1; print "trusted_and_ackable =", trusted_and_ackable
                         #if ord(data[0])&0x40 and myentry[1] == "Trusted": trusted_and_ackable += 1; print "trusted_and_ackable =", trusted_and_ackable
                      #if (ord(data[0])&0x40): ackable = ackable + 1; print "number of ackable messages = ", ackable
                        #if ord(data[0])&0x40: ackable += 1; print "number of ackable messages = ", ackable
                 else:
                 else:
                     myentry = mypacketdictionary[("Medium", int("0x"+ByteToHex(ID[1:2]).replace(' ', ''),16))]
                     myentry = mypacketdictionary[("Medium", int(ByteToHex(ID[1:2]).replace(' ', ''),16))]
                     if (ord(data[0])&0x40):  
                     if myentry[1] == "Trusted":
                         scheduleacknowledgemessage(data);  
                         trusted += 1;
                        ack_need_list_changed = True
                    ti = "%02d:%02d:%02d.%06d" % (t.hour,t.minute,t.second,t.microsecond)
                     print "Message #", i,"Flags: 0x" + test[0], myentry,  "sequence #", unpack(">L",data[1:5])
                     print ti, "Message #", i,"trusted count is", trusted,"Flags: 0x" + test[0], myentry,  "sequence #", unpack(">L",data[1:5])
                   
                      
                      
                     #if myentry[1] == "Trusted": trusted_count = trusted_count +1;print "number of trusted messages =", trusted_count
                     #if myentry[1] == "Trusted": trusted_count += 1;print "number of trusted messages =", trusted_count
                     #if (ord(data[0])&0x40) and (myentry[1] == "Trusted"): trusted_and_ackable = trusted_and_ackable + 1; print "trusted_and_ackable =", trusted_and_ackable
                     #if ord(data[0])&0x40 and myentry[1] == "Trusted": trusted_and_ackable += 1; print "trusted_and_ackable =", trusted_and_ackable
                     #if (ord(data[0])&0x40): ackable = ackable + 1; print "number of ackable messages = ", ackable
                     #if ord(data[0])&0x40: ackable += 1; print "number of ackable messages = ", ackable
             else:
             else:
                 myentry = mypacketdictionary[("High", int("0x"+ByteToHex(ID[0]), 16))]
                 myentry = mypacketdictionary[("High", int(ByteToHex(ID[0]), 16))]
                 if (ord(data[0])&0x40):  
                 if myentry[0] == "StartPingCheck":  
                     scheduleacknowledgemessage(data);
                     print "data from StartPingCheck", test
                     ack_need_list_changed = True
                    sendCompletePingCheck(sock, port, host, seqnum,data,lastPingSent)
                 print "Message #", i,"Flags: 0x" + test[0], myentry,   "sequence #", unpack(">L",data[1:5])
                     lastPingSent += 1
                    seqnum += 1
                   
                 if myentry[1] == "Trusted":
                    trusted += 1;    
                ti = "%02d:%02d:%02d.%06d" % (t.hour,t.minute,t.second,t.microsecond)
                  
                  
                 #if myentry[1] == "Trusted": trusted_count = trusted_count +1;print "number of trusted messages =", trusted_count
                print ti, "Message #", i,"trusted count is", trusted,"Flags: 0x" + test[0], myentry,  "sequence #", unpack(">L",data[1:5])
                 #if (ord(data[0])&0x40) and (myentry[1] == "Trusted"): trusted_and_ackable = trusted_and_ackable + 1; print "trusted_and_ackable =",  trusted_and_ackable
               
                 #if (ord(data[0])&0x40): ackable = ackable + 1; print "number of ackable messages = ", ackable
                 #if myentry[1] == "Trusted": trusted_count += 1;print "number of trusted messages =", trusted_count
                 #if ord(data[0])&0x40 and myentry[1] == "Trusted": trusted_and_ackable += 1; print "trusted_and_ackable =",  trusted_and_ackable
                 #if ord(data[0])&0x40: ackable += 1; print "number of ackable messages = ", ackable
 
    sendLogoutRequest(sock, port, host,seqnum,myAgentID,mySessionID)
 
     sock.close()
     sock.close()
     print "final number of trusted messages =", trusted_count
     print "final number of trusted messages =", trusted_count
Line 254: Line 370:




</python>
</syntaxhighlight>
[[Category: AW Groupies]]
[[Category: AW Groupies]]

Latest revision as of 19:07, 10 September 2024

Extremely incomplete example of how to log an avatar in and establish a presence. So far it only sends enough to temporarily show in-world.

N.B.: the packet ID number of a zero encoded pack is encoded and must be decoded before you can know what packet you are actually dealing with (Thanks John Hurliman/Eddy Stryker).

(based on a sample login script found at libsl login.)

The zerocode Python 2 module used here can be found in Zerocode.

from struct import *
from zerocode import  *
import md5
import xmlrpclib
import sys 

import re
import httplib, urllib        
from urlparse import urlparse    
import socket, sys, time
import uuid
from makepacketdict import makepacketdict



from datetime import datetime


mypacketdictionary = {}
outputstring = ''
ack_need_list = []

logoutputflag = False

if logoutputflag:
    temp = sys.stdout
    sys.stdout =open('alog.txt','w')

def login(first, last, passwd, mac):
  passwd_md5 = '$1$' + md5.new(passwd).hexdigest()
 
  uri = 'http://127.0.0.1'
  uri = 'https://login.agni.lindenlab.com/cgi-bin/login.cgi'
  s = xmlrpclib.ServerProxy(uri)
 
  login_details = {
    'first': first,
    'last': last,
    'passwd': passwd_md5,
    'start': 'last',
    'major': '1',
    'minor': '18',
    'patch': '5',
    'build': '3',
    'platform': 'Win',
    'mac': mac,
    'options': [],
    'user-agent': 'sl.py 0.1',
    'id0': '',
    'agree_to_tos': '',
    'viewer_digest': '09d93740-8f37-c418-fbf2-2a78c7b0d1ea'
  }
  results = s.login_to_simulator(login_details)
  print results
  
  return results




def get_caps(results,cap_key, request_keys):

  _, netloc, path, _, _, _ = urlparse(results[cap_key])

  params = "<llsd><array><string>"+ request_keys[0]+"</string></array></llsd>"
  headers = {"content-type": "application/xml"}
  conn = httplib.HTTPSConnection(netloc)

  conn.request("POST", path, params, headers)
  response = conn.getresponse()


  data = response.read()
  conn.close()
  return data
  
def ExtractCap(cap_result):
  trim_xml = re.compile(r"<key>([a-zA-Z_]+)</key><string>([a-zA-Z_:/0-9-.]+)</string>")
  new_key = trim_xml.search(cap_result).group(1)
  new_cap = trim_xml.search(cap_result).group(2)
  return new_key, new_cap
  

  
def scheduleacknowledgemessage(data):
    if not ord(data[0])&0x40:
        print "OOOPS! Got asked to ack a message that shouldn't be acked"
        
        return
    else:
        ID = data[1:5]
        if (ord(data[0])&0x40) & 0x80: ID = zero_decode_ID(ID) #impossible
        ack_need_list.append(unpack(">L",ID)[0])
        #ack_need_list.append(unpack(">L",data[1:5])[0])
        #print "ack needed","insdie schedule ack_need_list", ack_need_list
        

    return

def packacks():
    acksequence = ""
    for msgnum in ack_need_list:
        acksequence += pack("<L", msgnum)
    
    
    return acksequence
        
#def sendacks():
 #   if len(ack_need_list)>0:
 
 
#===============================================================================
# {
#    UUIDNameRequest Low NotTrusted Unencoded
#    {
#        UUIDNameBlock    Variable
#        {    ID            LLUUID    }
#    }
# }
#===============================================================================

def sendUUIDNameRequest(sock, port, host, currentsequence,aUUID):
    
    packed_data = ""
    fix_ID = int("ffff0000",16)+ 235
    data_header = pack('>BLB', 0x00,currentsequence,0x00) 
    
    
    for x in aUUID:
        packed_data += uuid.UUID(x).bytes
        
    packed_data += pack("L",fix_ID) + pack(">B",len(aUUID)) + packed_data
        
    sock.sendto(packed_data, (host, port)) 
    return              
   
def sendRegionHandshakeReply(sock, port, host, currentsequence,agentUUID,sessionUUID):
    packed_data = ""
    
    low_ID = "ffff00%2x" % 149
    data_header = pack('>BLB', 0x00,currentsequence,0x00)
    packed_data += uuid.UUID(agentUUID).bytes+uuid.UUID(sessionUUID).bytes+ pack(">L",0x00)
    packed_data = data_header + pack(">L",int(low_ID,16))+packed_data
    sock.sendto(packed_data, (host, port)) 
    #print "RegionHandshakeReply", ByteToHex(packed_data)
    return
    
   
        
def sendAgentUpdate(sock, port, host, currentsequence, result):

#AgentUpdate

    tempacks = packacks()
    del ack_need_list[:]
    if tempacks == "": 
        flags = 0x00
    else:
        flags = 0x10

    #print "tempacks is:", ByteToHex(tempacks)  
        
    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)

    encoded_packed_data = zero_encode(packed_data_message_ID+packed_data_ID+packed_data_QuatRots+packed_data_State+packed_data_Camera+packed_data_Flags)

    packed_data = data_header + encoded_packed_data+tempacks

   # print "sending AgentUpdate to server",ByteToHex(packed_data_header+zero_decode(encoded_packed_data)+ tempacks)
    
    sock.sendto(packed_data, (host, port))
    return

def sendCompletePingCheck(sock, port, host, currentsequence,data,lastPingSent):
#    print "data from PingCHeck", ByteToHex(data)
    
    data_header = pack('>BLB', 0x00,currentsequence,0x00)
    packed_data_message_ID = pack('>B',0x02)
    packed_data = data_header + packed_data_message_ID+pack('>B', lastPingSent)
    print "CompletePingCheck packet sent:", ByteToHex(packed_data)
    sock.sendto(packed_data, (host, port))
    
    return
    
def sendPacketAck(sock, port, host,currentsequence):

    tempacks = packacks()
    templen = len(ack_need_list)
    del ack_need_list[:]
    data_header = pack('>BLB',0x00,currentsequence,0x00) 
    packed_data_message_ID = pack('>L',0xFFFFFFFB)
    packed_ack_len = pack('>B',templen)
    
    packed_data = data_header + packed_data_message_ID + packed_ack_len + tempacks
#===============================================================================
#    t = datetime.now()
#    t.strftime("%H:%M:%S")
#    ti = "%02d:%02d:%02d.%06d" % (t.hour,t.minute,t.second,t.microsecond)
#    print ti, "PacketAck packet sent:", ByteToHex(packed_data)
#===============================================================================
    sock.sendto(packed_data, (host, port))
    return

def sendLogoutRequest(sock, port, host,seqnum,aUUID,sUUID):
    packed_data = ""
    packed_data_message_ID = pack('>L',0xffff00fc)
    data_header = pack('>BLB', 0x00,seqnum,0x00)
    packed_data += uuid.UUID(aUUID).bytes+uuid.UUID(sUUID).bytes+ pack(">L",0x00)
    
    packed_data = data_header + packed_data_message_ID + packed_data
    sock.sendto(packed_data, (host, port))
    return


def establishpresence(host, port, circuit_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 True:
        if ack_need_list_changed:
            ack_need_list_changed = False
            seqnum += 1
            sendPacketAck(sock, port, host,seqnum)
            #sendAgentUpdate(sock, port, host, seqnum, result)
            seqnum += 1
        #sendacks()
        i += 1
        data,addr = sock.recvfrom(buf)
        t = datetime.now()
        t.strftime("%H:%M:%S")



        if not data:
            print "Client has exited!"
            
            break
        else:
            test =  ByteToHex(data).split()
            #print test
            ID = data[6:12]
            #print "ID =", ByteToHex(ID) 
            if ord(data[0])&0x80: 
                ID = zero_decode_ID(data[6:12])
                
            if ord(data[0])&0x40: 
                scheduleacknowledgemessage(data); 
                ack_need_list_changed = True
            #print "ID =", ByteToHex(ID) 
            #print "ID =", unpack(">L", ID[:4])
            if ID[0] == '\xFF':
                if ID[1] == '\xFF':
                    if ID[2] == '\xFF':
                        myentry = mypacketdictionary[("Fixed" , "0x"+ByteToHex(ID[0:4]).replace(' ', ''))]
                        if myentry[1] == "Trusted":
                            trusted += 1;
                        ti = "%02d:%02d:%02d.%06d" % (t.hour,t.minute,t.second,t.microsecond)
                        print ti, "Message #", i, "trusted count is", trusted,"Flags: 0x" + test[0], myentry,  "sequence #", unpack(">L",data[1:5])
                            
                        #if myentry[1] == "Trusted": trusted_count += 1;print "number of trusted messages =", trusted_count
                        #if ord(data[0])&0x40 and myentry[1] == "Trusted": trusted_and_ackable += 1; print "trusted_and_ackable =", trusted_and_ackable
                        #if ord(data[0])&0x40: ackable += 1; print "number of ackable messages = ", ackable
                    else:
                        myentry = mypacketdictionary[("Low",int(ByteToHex(ID[2:4]).replace(' ', ''),16))]
                        if myentry[1] == "Trusted":
                            trusted += 1;
                        ti = "%02d:%02d:%02d.%06d" % (t.hour,t.minute,t.second,t.microsecond)
                        print ti, "Message #", i,"trusted count is", trusted,"Flags: 0x" + test[0], myentry,   "sequence #", unpack(">L",data[1:5])
                        if myentry[0] == "UUIDNameReply":
                            pass
                            #print ByteToHex(data)
                            #print data[:28]
                            #print data[28:36],data[38:45]
                        elif myentry[0] == "RegionHandshake":
                            sendRegionHandshakeReply(sock, port, host, seqnum,result["agent_id"],result["session_id"])
                            seqnum += 1
                        
                        #if myentry[1] == "Trusted": trusted_count += 1;print "number of trusted messages =", trusted_count
                        #if ord(data[0])&0x40 and myentry[1] == "Trusted": trusted_and_ackable += 1; print "trusted_and_ackable =", trusted_and_ackable
                        #if ord(data[0])&0x40: ackable += 1; print "number of ackable messages = ", ackable
                else:
                    myentry = mypacketdictionary[("Medium", int(ByteToHex(ID[1:2]).replace(' ', ''),16))]
                    if myentry[1] == "Trusted":
                        trusted += 1;
                    ti = "%02d:%02d:%02d.%06d" % (t.hour,t.minute,t.second,t.microsecond)
                    print ti, "Message #", i,"trusted count is", trusted,"Flags: 0x" + test[0], myentry,  "sequence #", unpack(">L",data[1:5])
                    
                    
                    #if myentry[1] == "Trusted": trusted_count += 1;print "number of trusted messages =", trusted_count
                    #if ord(data[0])&0x40 and myentry[1] == "Trusted": trusted_and_ackable += 1; print "trusted_and_ackable =", trusted_and_ackable
                    #if ord(data[0])&0x40: ackable += 1; print "number of ackable messages = ", ackable
            else:
                myentry = mypacketdictionary[("High", int(ByteToHex(ID[0]), 16))]
                if myentry[0] == "StartPingCheck": 
                    print "data from StartPingCheck", test
                    sendCompletePingCheck(sock, port, host, seqnum,data,lastPingSent)
                    lastPingSent += 1
                    seqnum += 1
                    
                if myentry[1] == "Trusted":
                    trusted += 1;   
                ti = "%02d:%02d:%02d.%06d" % (t.hour,t.minute,t.second,t.microsecond)
                
                print ti, "Message #", i,"trusted count is", trusted,"Flags: 0x" + test[0], myentry,   "sequence #", unpack(">L",data[1:5])
                
                #if myentry[1] == "Trusted": trusted_count += 1;print "number of trusted messages =", trusted_count
                #if ord(data[0])&0x40 and myentry[1] == "Trusted": trusted_and_ackable += 1; print "trusted_and_ackable =",  trusted_and_ackable
                #if ord(data[0])&0x40: ackable += 1; print "number of ackable messages = ", ackable

    sendLogoutRequest(sock, port, host,seqnum,myAgentID,mySessionID)

    sock.close()
    print "final number of trusted messages =", trusted_count
    
    return


            
        
result = login("first", "last", "password", MAC)

mypacketdictionary = makepacketdict()

myhost = result["sim_ip"]
myport = result["sim_port"]
mycircuit_code = result["circuit_code"]

establishpresence(myhost, myport, mycircuit_code)

#cap_out = get_caps(result,"seed_capability", ["ChatSessionRequest"])