[pyKoL-users] SF.net SVN: pykol: [25] trunk
Brought to you by:
scelis
|
From: <mi...@us...> - 2007-08-17 10:59:41
|
Revision: 25
http://pykol.svn.sourceforge.net/pykol/?rev=25&view=rev
Author: misza13
Date: 2007-08-17 03:59:35 -0700 (Fri, 17 Aug 2007)
Log Message:
-----------
Standarising repository layout.
Created /trunk, /branches and /tags.
Moved all files under /trunk.
Added Paths:
-----------
branches/
tags/
trunk/
trunk/.svnignore
trunk/LICENSE
trunk/adventure.py
trunk/bots/
trunk/campground.py
trunk/kolsite.py
trunk/mall.py
trunk/test.py
Removed Paths:
-------------
.svnignore
LICENSE
adventure.py
bots/
campground.py
kolsite.py
mall.py
test.py
Deleted: .svnignore
===================================================================
--- .svnignore 2007-06-03 22:25:53 UTC (rev 24)
+++ .svnignore 2007-08-17 10:59:35 UTC (rev 25)
@@ -1,2 +0,0 @@
-*.pyc
-*.conf
Deleted: LICENSE
===================================================================
--- LICENSE 2007-06-03 22:25:53 UTC (rev 24)
+++ LICENSE 2007-08-17 10:59:35 UTC (rev 25)
@@ -1,19 +0,0 @@
-Copyright (C) Misza <mi...@mi...>, 2007
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
Deleted: adventure.py
===================================================================
--- adventure.py 2007-06-03 22:25:53 UTC (rev 24)
+++ adventure.py 2007-08-17 10:59:35 UTC (rev 25)
@@ -1,41 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# (C) Misza <mi...@mi...>, 2007
-#
-# Distributed under the terms of the MIT license.
-#
-
-import re
-
-class AutoAdventurer:
- def __init__(self, site):
- self.site = site
-
- def adventure(self, snarfblat):
- print 'Starting adventure...'
- response, data = self.site.getPage('adventure.php?snarfblat='+snarfblat)
-
- if response.getheader('location')=='fight.php':
- self.fighting = True
- while self.fighting:
- self.fight()
-
- def fight(self):
- response, data = self.site.getPage('fight.php')
-
- monRX = re.search(r"You're fighting <span id='monname'>(?P<monname>.*?)</span>",data)
- print "You're fighting %s" % monRX.group('monname')
-
- tackRX = re.search(r"<input id='tack' class=button type=submit value=\"Attack with your (?P<tackitem>.*?)\">",data)
-
- formdata = {
- 'action' : 'attack',
- 'tack' : 'Attack with your ' + tackRX.group('tackitem'),
- }
- response, data = self.site.postForm('fight.php',formdata)
-
- if "You win the fight!" in data:
- print "You win the fight!"
- self.fighting = False
- else:
- self.fighting = True
Deleted: campground.py
===================================================================
--- campground.py 2007-06-03 22:25:53 UTC (rev 24)
+++ campground.py 2007-08-17 10:59:35 UTC (rev 25)
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# (C) Misza <mi...@mi...>, 2007
-#
-# Distributed under the terms of the MIT license.
-#
-
-import re
-
-class Campground:
- def __init__(self, site):
- self.site = site
-
-
- def rest(self, count=1):
- #Function will return cumulative gains:
- cHPgain = 0
- cMPgain = 0
- for i in range(count):
- print 'Now resting...'
- response, data = self.site.getPage('campground.php?action=rest')
-
- if "You don't need to rest." in data:
- print "You don't need to rest."
- break
- else:
- rx = re.search(r'You sleep.*?You gain (?P<hp>\d+).*?You gain (?P<mp>\d+)',data)
- if rx:
- HPgain = int(rx.group('hp'))
- MPgain = int(rx.group('mp'))
- print 'You gained %d HP, %d MP' % (HPgain,MPgain)
- return (cHPgain,cMPgain)
Deleted: kolsite.py
===================================================================
--- kolsite.py 2007-06-03 22:25:53 UTC (rev 24)
+++ kolsite.py 2007-08-17 10:59:35 UTC (rev 25)
@@ -1,156 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# (C) Misza <mi...@mi...>, 2007
-#
-# Distributed under the terms of the MIT license.
-#
-import re, urllib, httplib
-
-try:
- import hashlib
- new_md5 = hashlib.md5
-except ImportError: #Old python?
- import md5
- new_md5 = md5.md5
-
-
-def urlEncode(query):
- """This can encode a query so that it can be sent as a query using
- a http POST request"""
- if not query:
- return None
- l = []
- for key, value in query.iteritems():
- key = urllib.quote(key)
- value = urllib.quote(value)
- l.append(key + '=' + value)
- return '&'.join(l)
-
-
-def challengePassword(challenge,password):
- m = new_md5()
- m.update(password)
- hashedpw = m.hexdigest()
- m = new_md5()
- m.update(hashedpw+':'+challenge)
- return m.hexdigest()
-
-
-class LoginError:
- def __init__(self,reason='None'):
- self.reason = reason
-
- def __repr__(self):
- return 'LoginError{%s}' % self.reason
-
-
-class KoLSite:
- def __init__(self):
- self.hostname = 'www.kingdomofloathing.com'
- self.cookie = None
-
-
- def getPage(self, address, data=''):
- #print 'GET http://' + self.hostname + '/' + address
- conn = httplib.HTTPConnection(self.hostname)
-
- conn.putrequest('GET', '/' + address)
- if self.cookie:
- conn.putheader('Cookie', self.cookie)
- conn.endheaders()
- conn.send('')
-
- response = conn.getresponse()
- data = response.read().decode('utf-8')
- conn.close()
- return response, data
-
-
- def postForm(self, address, formdata):
- data = urlEncode(formdata)
- return self.postData(address, data)
-
-
- def postData(self, address, data=''):
- #print 'POST http://' + self.hostname + '/' + address
- conn = httplib.HTTPConnection(self.hostname)
-
- conn.putrequest('POST', '/' + address)
- if self.cookie:
- conn.putheader('Cookie', self.cookie)
- conn.putheader('Content-Length', str(len(data)))
- conn.putheader('Content-Type', 'application/x-www-form-urlencoded')
- conn.endheaders()
- conn.send(data)
-
- response = conn.getresponse()
- data = response.read().decode('utf-8')
- conn.close()
- return response, data
-
-
- def doLogin(self, nick, password):
- try:
- cookie = file('cookie','r').readlines()
- self.cookie = cookie[1][:-1]
- self.hostname = cookie[0][:-1]
- except:
- self.cookie = None
-
- if self.cookie:
- print 'Trying a recovered cookie...'
- response, data = self.getPage('main.php')
- if data or response.getheader('location')=='fight.php':
- print "Successfully recovered cookie file."
- return
-
- challenge = self.getChallenge()
-
- formFields = {}
- formFields['loggingin'] = 'Yup.'
- formFields['loginname'] = nick
- if challenge:
- print 'Logging in using challenge...'
- formFields['challenge'] = challenge
- formFields['response'] = challengePassword(challenge,password)
- else:
- print 'Logging in without challenge...'
- formFields['password'] = password
- formFields['secure'] = '1'
-
- response, data = self.postForm('login.php',formFields)
-
- if response.status == 302:
- self.cookie = response.getheader('set-cookie')
- file('cookie','w+').write('%s\n%s\n' % (self.hostname,self.cookie))
- print 'Saved cookie file.'
- return
-
- if re.search('Bad password.',data):
- raise LoginError, 'Bad password.'
- elif re.search('Too many login failures from this IP.',data):
- raise LoginError, 'Too many login failures from this IP.'
- elif re.search('Too many login attempts',data):
- raise LoginError, 'Too many login attempts.'
- else:
- raise LoginError, data
-
-
- def getChallenge(self):
- print 'Getting login challenge...'
- response, data = self.getPage('')
- while response.status == 302:
- #We got redirected
- locRE = re.search('http://(www\d?.kingdomofloathing.com)/(.*)',response.getheader('location'))
- if locRE: #Bounced off to a different server?
- self.hostname = locRE.group(1)
- response, data = self.getPage(locRE.group(2))
- else: #Same server, getting loginid=
- response, data = self.getPage(response.getheader('location'))
-
- #We're there. Looking for challenge...
- challenge = re.search('<input type=hidden name=challenge value="([0-9a-f]+)">',data)
- if challenge:
- return challenge.group(1)
- else:
- return ''
Deleted: mall.py
===================================================================
--- mall.py 2007-06-03 22:25:53 UTC (rev 24)
+++ mall.py 2007-08-17 10:59:35 UTC (rev 25)
@@ -1,38 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# (C) Misza <mi...@mi...>, 2007
-#
-# Distributed under the terms of the MIT license.
-#
-import re
-
-import kolsite
-
-class Mall:
- def __init__(self, Site):
- self.Site = Site
-
- def searchItem(self, what, limit=None):
- formdata = {'whichitem' : what}
- if limit:
- formdata['cheaponly'] = '1'
- formdata['shownum'] = str(limit)
- response, data = self.Site.postForm('searchmall.php',formdata)
-
- offset = re.search('Price:',data).start()
- itemRX = re.compile(r'<b>(?P<itemname>.+?)</b> \((?P<itemcount>\d+)\)(?: \((?P<limit>\d+) / day\))?.*?mallstore.php\?whichstore=(?P<whichstore>\d+).*?>(?P<shopname>.+)</a>.*?>(?P<price>[0-9,]+) ')
- for itemM in itemRX.finditer(data,offset):
- result = {}
- for v in ['itemname','itemcount','limit','whichstore','shopname','price']:
- if v == 'itemcount':
- result[v] = int(itemM.group('itemcount').replace(',',''))
- elif v == 'limit' and itemM.group('limit'):
- result[v] = int(itemM.group('limit').replace(',',''))
- elif v == 'price':
- result[v] = int(itemM.group('price').replace(',',''))
- elif v == 'whichstore':
- result[v] = int(itemM.group('whichstore').replace(',',''))
- else:
- result[v] = itemM.group(v)
- yield result
-
Deleted: test.py
===================================================================
--- test.py 2007-06-03 22:25:53 UTC (rev 24)
+++ test.py 2007-08-17 10:59:35 UTC (rev 25)
@@ -1,34 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# (C) Misza <mi...@mi...>, 2007
-#
-# Distributed under the terms of the MIT license.
-#
-import sys, random
-from kolsite import KoLSite
-from mall import Mall
-
-
-def main():
- if len(sys.argv) < 2:
- print 'Please specify a config file!'
- return
- config = {}
- execfile(sys.argv[1])
- if not config.has_key('nick') or not config.has_key('password'):
- print 'Nick or password not specified in config!'
- return
-
- Site = KoLSite()
- Site.doLogin(config['nick'],config['password'])
-
- #response, data = Site.getPage('main.html')
- #print response.status
- #print data
-
- M = Mall(Site)
- for s in M.searchItem('tiny plastic sword'):
- print s
-
-if __name__ == '__main__':
- main()
Copied: trunk/.svnignore (from rev 24, .svnignore)
===================================================================
--- trunk/.svnignore (rev 0)
+++ trunk/.svnignore 2007-08-17 10:59:35 UTC (rev 25)
@@ -0,0 +1,2 @@
+*.pyc
+*.conf
Copied: trunk/LICENSE (from rev 24, LICENSE)
===================================================================
--- trunk/LICENSE (rev 0)
+++ trunk/LICENSE 2007-08-17 10:59:35 UTC (rev 25)
@@ -0,0 +1,19 @@
+Copyright (C) Misza <mi...@mi...>, 2007
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
Copied: trunk/adventure.py (from rev 24, adventure.py)
===================================================================
--- trunk/adventure.py (rev 0)
+++ trunk/adventure.py 2007-08-17 10:59:35 UTC (rev 25)
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+#
+# (C) Misza <mi...@mi...>, 2007
+#
+# Distributed under the terms of the MIT license.
+#
+
+import re
+
+class AutoAdventurer:
+ def __init__(self, site):
+ self.site = site
+
+ def adventure(self, snarfblat):
+ print 'Starting adventure...'
+ response, data = self.site.getPage('adventure.php?snarfblat='+snarfblat)
+
+ if response.getheader('location')=='fight.php':
+ self.fighting = True
+ while self.fighting:
+ self.fight()
+
+ def fight(self):
+ response, data = self.site.getPage('fight.php')
+
+ monRX = re.search(r"You're fighting <span id='monname'>(?P<monname>.*?)</span>",data)
+ print "You're fighting %s" % monRX.group('monname')
+
+ tackRX = re.search(r"<input id='tack' class=button type=submit value=\"Attack with your (?P<tackitem>.*?)\">",data)
+
+ formdata = {
+ 'action' : 'attack',
+ 'tack' : 'Attack with your ' + tackRX.group('tackitem'),
+ }
+ response, data = self.site.postForm('fight.php',formdata)
+
+ if "You win the fight!" in data:
+ print "You win the fight!"
+ self.fighting = False
+ else:
+ self.fighting = True
Copied: trunk/bots (from rev 24, bots)
Copied: trunk/campground.py (from rev 24, campground.py)
===================================================================
--- trunk/campground.py (rev 0)
+++ trunk/campground.py 2007-08-17 10:59:35 UTC (rev 25)
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+#
+# (C) Misza <mi...@mi...>, 2007
+#
+# Distributed under the terms of the MIT license.
+#
+
+import re
+
+class Campground:
+ def __init__(self, site):
+ self.site = site
+
+
+ def rest(self, count=1):
+ #Function will return cumulative gains:
+ cHPgain = 0
+ cMPgain = 0
+ for i in range(count):
+ print 'Now resting...'
+ response, data = self.site.getPage('campground.php?action=rest')
+
+ if "You don't need to rest." in data:
+ print "You don't need to rest."
+ break
+ else:
+ rx = re.search(r'You sleep.*?You gain (?P<hp>\d+).*?You gain (?P<mp>\d+)',data)
+ if rx:
+ HPgain = int(rx.group('hp'))
+ MPgain = int(rx.group('mp'))
+ print 'You gained %d HP, %d MP' % (HPgain,MPgain)
+ return (cHPgain,cMPgain)
Copied: trunk/kolsite.py (from rev 24, kolsite.py)
===================================================================
--- trunk/kolsite.py (rev 0)
+++ trunk/kolsite.py 2007-08-17 10:59:35 UTC (rev 25)
@@ -0,0 +1,156 @@
+# -*- coding: utf-8 -*-
+#
+# (C) Misza <mi...@mi...>, 2007
+#
+# Distributed under the terms of the MIT license.
+#
+import re, urllib, httplib
+
+try:
+ import hashlib
+ new_md5 = hashlib.md5
+except ImportError: #Old python?
+ import md5
+ new_md5 = md5.md5
+
+
+def urlEncode(query):
+ """This can encode a query so that it can be sent as a query using
+ a http POST request"""
+ if not query:
+ return None
+ l = []
+ for key, value in query.iteritems():
+ key = urllib.quote(key)
+ value = urllib.quote(value)
+ l.append(key + '=' + value)
+ return '&'.join(l)
+
+
+def challengePassword(challenge,password):
+ m = new_md5()
+ m.update(password)
+ hashedpw = m.hexdigest()
+ m = new_md5()
+ m.update(hashedpw+':'+challenge)
+ return m.hexdigest()
+
+
+class LoginError:
+ def __init__(self,reason='None'):
+ self.reason = reason
+
+ def __repr__(self):
+ return 'LoginError{%s}' % self.reason
+
+
+class KoLSite:
+ def __init__(self):
+ self.hostname = 'www.kingdomofloathing.com'
+ self.cookie = None
+
+
+ def getPage(self, address, data=''):
+ #print 'GET http://' + self.hostname + '/' + address
+ conn = httplib.HTTPConnection(self.hostname)
+
+ conn.putrequest('GET', '/' + address)
+ if self.cookie:
+ conn.putheader('Cookie', self.cookie)
+ conn.endheaders()
+ conn.send('')
+
+ response = conn.getresponse()
+ data = response.read().decode('utf-8')
+ conn.close()
+ return response, data
+
+
+ def postForm(self, address, formdata):
+ data = urlEncode(formdata)
+ return self.postData(address, data)
+
+
+ def postData(self, address, data=''):
+ #print 'POST http://' + self.hostname + '/' + address
+ conn = httplib.HTTPConnection(self.hostname)
+
+ conn.putrequest('POST', '/' + address)
+ if self.cookie:
+ conn.putheader('Cookie', self.cookie)
+ conn.putheader('Content-Length', str(len(data)))
+ conn.putheader('Content-Type', 'application/x-www-form-urlencoded')
+ conn.endheaders()
+ conn.send(data)
+
+ response = conn.getresponse()
+ data = response.read().decode('utf-8')
+ conn.close()
+ return response, data
+
+
+ def doLogin(self, nick, password):
+ try:
+ cookie = file('cookie','r').readlines()
+ self.cookie = cookie[1][:-1]
+ self.hostname = cookie[0][:-1]
+ except:
+ self.cookie = None
+
+ if self.cookie:
+ print 'Trying a recovered cookie...'
+ response, data = self.getPage('main.php')
+ if data or response.getheader('location')=='fight.php':
+ print "Successfully recovered cookie file."
+ return
+
+ challenge = self.getChallenge()
+
+ formFields = {}
+ formFields['loggingin'] = 'Yup.'
+ formFields['loginname'] = nick
+ if challenge:
+ print 'Logging in using challenge...'
+ formFields['challenge'] = challenge
+ formFields['response'] = challengePassword(challenge,password)
+ else:
+ print 'Logging in without challenge...'
+ formFields['password'] = password
+ formFields['secure'] = '1'
+
+ response, data = self.postForm('login.php',formFields)
+
+ if response.status == 302:
+ self.cookie = response.getheader('set-cookie')
+ file('cookie','w+').write('%s\n%s\n' % (self.hostname,self.cookie))
+ print 'Saved cookie file.'
+ return
+
+ if re.search('Bad password.',data):
+ raise LoginError, 'Bad password.'
+ elif re.search('Too many login failures from this IP.',data):
+ raise LoginError, 'Too many login failures from this IP.'
+ elif re.search('Too many login attempts',data):
+ raise LoginError, 'Too many login attempts.'
+ else:
+ raise LoginError, data
+
+
+ def getChallenge(self):
+ print 'Getting login challenge...'
+ response, data = self.getPage('')
+ while response.status == 302:
+ #We got redirected
+ locRE = re.search('http://(www\d?.kingdomofloathing.com)/(.*)',response.getheader('location'))
+ if locRE: #Bounced off to a different server?
+ self.hostname = locRE.group(1)
+ response, data = self.getPage(locRE.group(2))
+ else: #Same server, getting loginid=
+ response, data = self.getPage(response.getheader('location'))
+
+ #We're there. Looking for challenge...
+ challenge = re.search('<input type=hidden name=challenge value="([0-9a-f]+)">',data)
+ if challenge:
+ return challenge.group(1)
+ else:
+ return ''
Copied: trunk/mall.py (from rev 24, mall.py)
===================================================================
--- trunk/mall.py (rev 0)
+++ trunk/mall.py 2007-08-17 10:59:35 UTC (rev 25)
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+#
+# (C) Misza <mi...@mi...>, 2007
+#
+# Distributed under the terms of the MIT license.
+#
+import re
+
+import kolsite
+
+class Mall:
+ def __init__(self, Site):
+ self.Site = Site
+
+ def searchItem(self, what, limit=None):
+ formdata = {'whichitem' : what}
+ if limit:
+ formdata['cheaponly'] = '1'
+ formdata['shownum'] = str(limit)
+ response, data = self.Site.postForm('searchmall.php',formdata)
+
+ offset = re.search('Price:',data).start()
+ itemRX = re.compile(r'<b>(?P<itemname>.+?)</b> \((?P<itemcount>\d+)\)(?: \((?P<limit>\d+) / day\))?.*?mallstore.php\?whichstore=(?P<whichstore>\d+).*?>(?P<shopname>.+)</a>.*?>(?P<price>[0-9,]+) ')
+ for itemM in itemRX.finditer(data,offset):
+ result = {}
+ for v in ['itemname','itemcount','limit','whichstore','shopname','price']:
+ if v == 'itemcount':
+ result[v] = int(itemM.group('itemcount').replace(',',''))
+ elif v == 'limit' and itemM.group('limit'):
+ result[v] = int(itemM.group('limit').replace(',',''))
+ elif v == 'price':
+ result[v] = int(itemM.group('price').replace(',',''))
+ elif v == 'whichstore':
+ result[v] = int(itemM.group('whichstore').replace(',',''))
+ else:
+ result[v] = itemM.group(v)
+ yield result
+
Copied: trunk/test.py (from rev 24, test.py)
===================================================================
--- trunk/test.py (rev 0)
+++ trunk/test.py 2007-08-17 10:59:35 UTC (rev 25)
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+#
+# (C) Misza <mi...@mi...>, 2007
+#
+# Distributed under the terms of the MIT license.
+#
+import sys, random
+from kolsite import KoLSite
+from mall import Mall
+
+
+def main():
+ if len(sys.argv) < 2:
+ print 'Please specify a config file!'
+ return
+ config = {}
+ execfile(sys.argv[1])
+ if not config.has_key('nick') or not config.has_key('password'):
+ print 'Nick or password not specified in config!'
+ return
+
+ Site = KoLSite()
+ Site.doLogin(config['nick'],config['password'])
+
+ #response, data = Site.getPage('main.html')
+ #print response.status
+ #print data
+
+ M = Mall(Site)
+ for s in M.searchItem('tiny plastic sword'):
+ print s
+
+if __name__ == '__main__':
+ main()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|