Presence Code Python

From Second Life Wiki
Revision as of 15:02, 4 December 2007 by Saijanai Kuhn (talk | contribs)
Jump to navigation Jump to search

Extremely incomplete example of how to log an avatar in and establish a presence. So far it only sends the UseCircuitCode UDP packet and gets a response of [currently] unknown type from the server. More to come....



import md5
import xmlrpclib

import re
import httplib, urllib
from urlparse import urlparse

import socket, sys, time

from struct import *

import uuid

sys.stdout.flush()
print "above login def"; print


def ByteToHex( byteStr ):
    """
    Convert a byte string to it's hex string representation e.g. for output.
    """
    
    # Uses list comprehension which is a fractionally faster implementation than
    # the alternative, more readable, implementation below
    #   
    #    hex = []
    #    for aChar in byteStr:
    #        hex.append( "%02X " % ord( aChar ) )
    #
    #    return ''.join( hex ).strip()        

    return ''.join( [ "%02X " % ord( x ) for x in byteStr ] ).strip()



def login(first, last, passwd, mac):
  print "inside login"; print
  passwd_md5 = '$1$' + md5.new(passwd).hexdigest()
 

  uri = 'https://login.agni.lindenlab.com/cgi-bin/login.cgi'
  s = xmlrpclib.ServerProxy(uri)

  optional_login = ["inventory-root",
                    "inventory-skeleton",
                    "inventory-lib-root",
                    "inventory-lib-owner",
                    "inventory-skel-lib",
                    "gestures",
                    "event_categories",
                    "event_notifications",
                    "classified_categories",
                    "buddy-list",
                    "ui-config",
                    "login-flags",
                    "global-textures"
                  ]

 
  login_details = {
    'first': first,
    'last': last,
    'passwd': passwd_md5,
    'start': 'last',
    'major': '1',
    'minor': '18',
    'patch': '4',
    'build': '3',
    'platform': 'Win',
    'mac': mac,
    'options': optional_login,
    'user-agent': 'sl.py 0.1',
    'id0': '',
    'agree_to_tos': 'true',
    'viewer_digest': '09d93740-8f37-c418-fbf2-2a78c7b0d1ea'
  }
  print "test1"; print
  return s.login_to_simulator(login_details)



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

print "prelogin" ; print
result = login("first", "last", "password", MAC)

#for item in result: print item, result[item]; print


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



host = result["sim_ip"]
print host
port = result["sim_port"]

circuit_code = result["circuit_code"]


sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)



#Sending packet UseCircuitCode <-- Inits the connection to the sim.
data = pack('>BLBL',0x40,01,00,0xffff0003) + pack('<L',circuit_code) + uuid.UUID(result["session_id"]).bytes+uuid.UUID(result["agent_id"]).bytes


print "%x" % circuit_code


print uuid.UUID(result["agent_id"]).bytes_le
print result["agent_id"]
print uuid.UUID(result["session_id"]).bytes_le
print result["session_id"]


print ByteToHex(data)

sock.sendto(data, (host, port))



#ISending packet CompleteAgentMovement <-- establishes the agent's presence

#data = pack('>BLBL',0x40,0x02,00,0xffff00f9) + uuid.UUID(result["agent_id"]).bytes_le + uuid.UUID(result["secure_session_id"]).bytes_le + pack('<L', circuit_code)
#print ByteToHex(data)
#sock.sendto(data, (host, port))

#ISending packet AgentUpdate <-- establishes the agent's initial location, camera and other movement states
#data = pack('>BLBB',0x40, 0x03,00,0x04) + pack('<L',circuit_code) + uuid.UUID(result["secure_session_id"]).bytes_le + uuid.UUID(result["agent_id"]).bytes_le
#print ByteToHex(data)
#sock.sendto(data, (host, port))

print "test"
print "test"
print "test"
buf = 100
#Receive messages
while 1:
    print "inside while"
    data,addr = sock.recvfrom(buf)
    if not data:
        print "Client has exited!"
        break
    else:
        print "\nReceived message '", data,"'"

#Close socket
sock.close()