All pastes #1406318 Raw Edit

UT3 Hax

public text v1 · immutable
#1406318 ·published 2009-04-28 17:28 UTC
rendered paste body
   1.
      #!/usr/bin/python
   2.
      """
   3.
      USAGE:
   4.
          ./query.py -u[HOST] -i[SERVER_ID] -n[NAME]
   5.
       
   6.
      """
   7.
      import optparse, os, re, string, sys, urllib, warnings
   8.
      warnings.simplefilter('ignore', DeprecationWarning)
   9.
      from Cookie import Cookie
  10.
      from urlparse import urljoin
  11.
      import MySQLdb
  12.
       
  13.
      import pylib.configobj as COBJ
  14.
       
  15.
      import logging; log=logging.getLogger('ut3_master')
  16.
       
  17.
      file = os.path.abspath(
  18.
                os.path.join(os.path.dirname(__file__), '../', '../', 'config.ini'))
  19.
      config = COBJ.load(file)
  20.
      HOST = config['DB_SERVER']
  21.
      USER = config['DB_USER']
  22.
      PASS = config['DB_PASSWD']
  23.
      DB = config['DB_DB']
  24.
       
  25.
      def qstr(s):
  26.
          return "'%s'" % s.replace('\\', '\\\\').replace("'", "\'")
  27.
       
  28.
      def dbconn(*a, **k):
  29.
          def new_conn():
  30.
              conn = MySQLdb.connect(HOST,USER,PASS,DB)
  31.
              try:
  32.
                  cursor = conn.cursor(*a, **k)
  33.
                  cursor.execute("SHOW TABLES")
  34.
                  cursor.execute("SET AUTOCOMMIT=0;")
  35.
                  cursor.close()
  36.
              except (MySQLdb.OperationalError, AttributeError):
  37.
                  return new_conn()
  38.
              else:
  39.
                  return conn
  40.
          return new_conn()
  41.
       
  42.
       
  43.
      def insert(r, server_id, verbose, debug):
  44.
          conn = dbconn()
  45.
          cursor = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
  46.
          rec = {'name'       : qstr(r[0]),
  47.
                 'ip_address' : qstr(r[1]),
  48.
                 'unique_id'  : qstr(r[2]),
  49.
                 'hash'       : qstr(r[3]),
  50.
                 'server_id'  : server_id
  51.
                }
  52.
          if duplicate(rec, verbose, debug):
  53.
              if verbose:
  54.
                  print 'DUPLICATE, returning'
  55.
                  return
  56.
          else:
  57.
              if verbose:
  58.
                  print 'INSERTING NEW PLAYER %s' % rec['name']
  59.
              sql = '''INSERT INTO hkey
  60.
                         (name, ip_address, unique_id, hash, server_id)
  61.
                      VALUES
  62.
                         (%(name)s, %(ip_address)s, %(unique_id)s, %(hash)s, %(server_id)s)''' % rec
  63.
              cursor.execute(sql)
  64.
       
  65.
       
  66.
      def duplicate(rec, verbose, debug):
  67.
          conn = dbconn()
  68.
          cursor = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
  69.
          sql = '''SELECT key_id
  70.
                      FROM hkey
  71.
                      WHERE
  72.
                          name = %(name)s AND
  73.
                          ip_address = %(ip_address)s AND
  74.
                          unique_id = %(unique_id)s AND
  75.
                          hash = %(hash)s''' % rec
  76.
          cursor.execute(sql)
  77.
          recs = cursor.fetchall()
  78.
          if recs:
  79.
       
  80.
              if verbose:
  81.
                  print 'PLAYER ALREAD EXISTS: %s' % rec['name']
  82.
                  print 'PLAYER EXIST: ', recs
  83.
                  print 'QUERIED FOR: ', rec
  84.
       
  85.
              return True
  86.
          else:
  87.
              return False
  88.
       
  89.
      def urlencode(dict, order):
  90.
          l = []
  91.
          for k in order:
  92.
              v = dict[k]
  93.
       
  94.
              k = quote_plus(str(k))
  95.
              v = quote_plus(str(v))
  96.
              l.append(k + '=' + v)
  97.
          return string.join(l, '&')
  98.
       
  99.
       
 100.
      class WebBot(urllib.FancyURLopener):
 101.
          #----------------------------------------------------------------------
 102.
          """ """
 103.
          #----------------------------------------------------------------------
 104.
       
 105.
          USER_AGENT = 'Mozilla/2.02 (OS/2; I)'
 106.
          SITENAME = 'Hedsteem'
 107.
          despace_patt = re.compile('\s+')
 108.
          verbose = False
 109.
          debug = False
 110.
          def despace(self, str): # Collapse Multiple Whitespace into One Blank
 111.
              return WebBot.despace_patt.sub(' ', str)
 112.
       
 113.
          def __init__(self, baseurl='', debug=0):
 114.
              urllib.FancyURLopener.__init__(self)
 115.
       
 116.
              self.delheader('User-agent')
 117.
              self.addheader('User-agent', self.USER_AGENT)
 118.
              self.addheader('HTTP_ACCEPT', 'text/html')
 119.
       
 120.
              self.baseurl = baseurl
 121.
              self.debug   = debug
 122.
              self.cookies = Cookie()
 123.
       
 124.
       
 125.
          def clear(self):
 126.
              self.cookies = Cookie()
 127.
       
 128.
          def delheader(self, hdrtype):
 129.
              keepers = []
 130.
              for h in self.addheaders:
 131.
                  if string.lower(h[0]) != string.lower(hdrtype):
 132.
                      keepers.append(h)
 133.
              self.addheaders = keepers
 134.
       
 135.
          def webtransact(self, relurl, optdata=None):
 136.
              url = urljoin(self.baseurl, relurl)
 137.
       
 138.
              if len(self.cookies):
 139.
                  self.delheader('Cookie')
 140.
                  for name, crumble in self.cookies.items():
 141.
                      if string.lower(name) != 'path':
 142.
                          self.addheader('Cookie', crumble.OutputString())
 143.
       
 144.
       
 145.
              if optdata is None: webpage = self.open(url)
 146.
              else:               webpage = self.open(url, optdata)
 147.
       
 148.
              # Look For and Parse Any Relevant Headers
 149.
              # --------------------------------------------------
 150.
       
 151.
              if webpage.info().has_key('Set-cookie'):
 152.
                  items = webpage.info().getallmatchingheaders('Set-cookie')
 153.
       
 154.
                  for i in items:
 155.
                      self.cookies.load(i)
 156.
       
 157.
              return webpage, url
 158.
       
 159.
          def do(self, debug, verbose):
 160.
              self.verbose = verbose
 161.
              self.debug = debug
 162.
              try:
 163.
                  webpage, fullurl = self.webtransact('/current/players')
 164.
                  loginstr         = webpage.read()
 165.
                  headers          = webpage.info()
 166.
              except Exception, e:
 167.
                  print str(e)
 168.
                  return []
 169.
              return self.getPlayers()
 170.
       
 171.
       
 172.
          def http_error_401(self, url, fp, errcode, errmsg, headers, data=None):
 173.
              return None # do nothing
 174.
       
 175.
          def stripToTable(self, input):
 176.
              ret = []
 177.
              r = False
 178.
              input = input.split('\n')
 179.
              for line in input:
 180.
                  if line.startswith('<table id="players" class="grid">'): r = True
 181.
                  if r:
 182.
                      ret.append(line)
 183.
                  if line.startswith('</table>'): r = False
 184.
              return ret
 185.
        def getData(self, table):
 186.
              players = []
 187.
              player = []
 188.
              version = 1
 189.
              for line in table:
 190.
                  if 'td style="background: #4040FF; color: #4040FF;"' in line or 'td style="background: #FF4040; color: #FF4040;"' in line:
 191.
                      version = 3
 192.
                  if 'value="sessionban">Session Ban</button>' in line:
 193.
                      version = 2
 194.
                  if version == 1 or version == 2:
 195.
                      try:
 196.
                          player.append(str(re.search(r'<div>(.+?)<input', line).group(1)).strip())
 197.
                      except AttributeError:
 198.
                          pass
 199.
                  if version == 3:
 200.
                      try:
 201.
                          player.append(str(re.search(r'<td>(.+?)</td>', line).group(1)).strip())
 202.
                      except AttributeError:
 203.
                          pass
 204.
       
 205.
                  if version == 1:
 206.
                      plen = 4
 207.
                  if version == 2:
 208.
                      plen = 5
 209.
                  if version == 3:
 210.
                      plen = 4
 211.
                  if len(player) == plen:
 212.
                      if version == 2:
 213.
                          del(player[1])
 214.
       
 215.
                      if self.verbose:
 216.
                          print 'PLAYER: ', player
 217.
                      players.append(player)
 218.
                      player = []
 219.
              if self.verbose:
 220.
                  print "ADMIN VERSION", version
 221.
              if player:
 222.
                  if self.verbose:
 223.
                      print 'PLAYER: ', player
 224.
                  players.append(player)
 225.
              if self.debug:
 226.
                  print "PLAYERS: ", players
 227.
              return players
 228.
       
 229.
          def getPlayers(self):
 230.
              try:
 231.
                  webpage, fullurl = self.webtransact('current/players')
 232.
                  html         = webpage.read()
 233.
                  headers          = webpage.info()
 234.
              except:
 235.
                  print "URL Did Not Open!"
 236.
                  raise
 237.
              table = self.stripToTable(html)
 238.
              return self.getData(table)
 239.
       
 240.
      def run(name, id, url, verbose, debug):
 241.
          if verbose:
 242.
              print 'QUERY -'
 243.
              print '  query.py'
 244.
              print '  NAME:', name
 245.
              print '  ID:', id
 246.
              print '  URL:', url
 247.
       
 248.
          bot = WebBot(url)
 249.
          for player in bot.do(debug, verbose):
 250.
              if verbose:
 251.
                  print player
 252.
              insert(player, id, verbose, debug)
 253.
          bot.clear()
 254.
          if verbose:
 255.
              print
 256.
       
 257.
      def main():
 258.
          """For Help type ./query.py -h  """
 259.
          parser = optparse.OptionParser(description=__doc__)
 260.
          parser.set_usage(main.__doc__)
 261.
          parser.formatter.format_description = lambda s:s
 262.
       
 263.
          parser.add_option("-D", "--debug", action="store_true",
 264.
                            default=False,
 265.
                            help="Enable debugging.")
 266.
       
 267.
          parser.add_option("-u", "--url", action="store",
 268.
                            default=None,
 269.
                            help="REQUIRED: Server URL")
 270.
       
 271.
          parser.add_option("-n", "--name", action="store",
 272.
                            default=None,
 273.
                            help="REQUIRED: Server Name")
 274.
       
 275.
          parser.add_option("-i", "--id", action="store",
 276.
                            default=None,
 277.
                            help="REQUIRED Server ID")
 278.
       
 279.
          parser.add_option("-v", "--verbose", action="store_true",
 280.
                            default=False,
 281.
                            help="Be verbose.")
 282.
       
 283.
          (opts, cmd) = parser.parse_args()
 284.
       
 285.
          # Logging Configuration
 286.
          log.setLevel(0)
 287.
          formatter = '%(levelname)-8s %(message)s'
 288.
       
 289.
          verbose = opts.verbose
 290.
          debug =  opts.debug
 291.
       
 292.
          if opts.debug:
 293.
              logging.basicConfig()
 294.
          else:
 295.
              logging.basicConfig()
 296.
       
 297.
       
 298.
          print 'VERBOSE IS: %s' % verbose
 299.
          print 'DEBUG IS: %s' % debug
 300.
          if not opts.name:
 301.
              print __doc__
 302.
              print 'ERROR: The server name must be provided.'
 303.
              sys.exit(1)
 304.
       
 305.
          if not opts.url:
 306.
              print __doc__
 307.
              print 'ERROR: The server url must be provided.'
 308.
              sys.exit(1)
 309.
       
 310.
          if not opts.id:
 311.
              print __doc__
 312.
              print 'ERROR: The server id must be provided.'
 313.
              sys.exit(1)
 314.
       
 315.
          if opts.name and opts.id and opts.url:
 316.
              return run(opts.name, opts.id, opts.url, verbose, debug)
 317.
          else:
 318.
              parser.print_help()
 319.
       
 320.
      if __name__ == '__main__':
 321.
          main()