def openSession(props): """ Log in to the KoL servers. """ log = logging.getLogger() s = Session() s.login(props.userName, props.password) log.info("Logged in.") return s
def go(self): """ Actually run the bot. """ self.log('Logging in.') self.__session = Session() self.__session.login(self.username, self.password) self.__chat = ChatManager(self.__session) while True: for msg in self.__fetch_chat_messages(): if msg['type'] == 'private' and self.caps.get('sign', False): # Got a blue message! Report "KICK ME" sign status self.log('{userName} (#{userId}) sent me ' 'a blue message: "{text}"'.format(**msg)) self.__sign(msg['userId']) elif msg['type'] == 'notification:kmail': # Got a green message! self.log('{userName} (#{userId}) sent me ' 'a green message.'.format(**msg)) # Fetch it and examine it kmail = self.__get_kmail(msg['userName']) if kmail['text']: self.log('They said: "{}"'.format(kmail['text'])) if kmail['meat'] > 0: self.log('They sent {} meat.'.format(kmail['meat'])) # Look at the items they sent for item in kmail['items']: self.log('They sent {} {}.'.format( item['quantity'], item['name'] if item['quantity'] == 1 else item['plural'])) if item['id'] == 7698 and self.caps.get( 'spider', False): # Rubber spider self.__use_spider(msg['userId']) elif item['id'] == 4939 and self.caps.get( 'arrow', False): # Time's arrow self.__use_arrow(msg['userId']) # Don't keep it self.__del_kmail(kmail['id']) time.sleep(1)
def login(s): try: c1 = cookielib.Cookie(None, "PHPSESSID", memcache.get("PHPSESSID"), None, False, memcache.get("domain0"), True, False, memcache.get("path0"), True, False, None, False, None, False, None, False) jar = cookielib.CookieJar() jar.set_cookie(c1) c2 = cookielib.Cookie(None, "appserver", memcache.get("appserver"), None, False, memcache.get("domain1"), True, False, memcache.get("path1"), True, False, None, False, None, False, None, False) jar.set_cookie(c2) s.cj = jar s.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(s.cj)) s.isConnected = memcache.get("isConnected") s.userId = memcache.get("userId") s.userName = memcache.get("userName") s.userPasswordHash = memcache.get("userPasswordHash") s.serverURL = memcache.get("serverURL") s.pwd = memcache.get("pwd") s.rollover = memcache.get("rollover") except: logging.error("some memcache keys were deleted") memcache.flush_all() s = Session() s.login(Data.USERNAME, Data.PASSWORD) memcache.add(key="isConnected", value=bool(s.isConnected)) memcache.add(key="userId", value=int(s.userId)) memcache.add(key="userName", value=str(s.userName)) memcache.add(key="userPasswordHash", value=str(s.userPasswordHash)) memcache.add(key="serverURL", value=str(s.serverURL)) memcache.add(key="pwd", value=str(s.pwd)) memcache.add(key="rollover", value=int(s.rollover)) i = 0 for cookie in s.cj: logging.info("%s=%s" % (cookie.name, cookie.value)) memcache.add(key=cookie.name,value=str(cookie.value)) memcache.add(key="domain%d" % i, value=str(cookie.domain)) memcache.add(key="path%d" % i, value=str(cookie.path)) i += 1 try: u = UserProfileRequest(s, 2434890) u.doRequest() except: logging.warn("Not logged in, logging in") memcache.flush_all() s = Session() s.login(Data.USERNAME, Data.PASSWORD) memcache.add(key="isConnected", value=bool(s.isConnected)) memcache.add(key="userId", value=int(s.userId)) memcache.add(key="userName", value=str(s.userName)) memcache.add(key="userPasswordHash", value=str(s.userPasswordHash)) memcache.add(key="serverURL", value=str(s.serverURL)) memcache.add(key="pwd", value=str(s.pwd)) memcache.add(key="rollover", value=int(s.rollover)) i = 0 for cookie in s.cj: logging.info("%s=%s" % (cookie.name, cookie.value)) memcache.add(key=cookie.name,value=str(cookie.value)) memcache.add(key="domain%d" % i, value=str(cookie.domain)) memcache.add(key="path%d" % i, value=str(cookie.path)) i += 1
def go(self): """ Actually run the bot. """ global active self.log('Logging in.') self.__session = Session() self.__session.login(self.username, self.password) self.__chat = ChatManager(self.__session) active = time.time() # Check pending kmails for kmail in self.__get_kmails(): self.__handle_kmail(kmail) while True: if time.time() - active > 3600: # Chat occasionally dies quietly. Maybe that happened. raise Exception("Inactive for too long.") for msg in self.__fetch_chat_messages(): if msg['type'] == 'private' and self.caps['sign']: # Got a blue message! Report "KICK ME" sign status self.log('{userName} (#{userId}) sent me ' 'a blue message: "{text}"'.format(**msg)) self.__sign(msg['userName'], msg['userId']) elif msg['type'] == 'notification:kmail': # Got a green message! self.log('{userName} (#{userId}) sent me ' 'a green message.'.format(**msg)) # Fetch it and examine it for kmail in self.__get_kmails(msg['userName'], 1): self.__handle_kmail(kmail) active = time.time() time.sleep(1)
from time import sleep from kol.Session import Session from kol.request.GetChatMessagesRequest import GetChatMessagesRequest from kol.request.SendChatRequest import SendChatRequest import urllib session = Session() password = '******' session.login( 'CGRelay', password ) while True: chatRequest = getChatMessagesRequest(session) responseData = chatRequest.doRequest() chatMessages = responseData['chatMessages'] for message in chatMessages: print message sleep(1)
# Kingdom of Loathing MallBot by KevZho (#2434890) # make sure to edit the options first on lines 15 to 27 # TODO: fix hitting the limits from kol.database import ItemDatabase from kol.Session import Session from kol.request.MallItemSearchRequest import MallItemSearchRequest from kol.request.MallItemPurchaseRequest import MallItemPurchaseRequest from kol.request.CocktailcraftingRequest import CocktailcraftingRequest from kol.request.AddItemsToStoreRequest import PutItemInStoreRequest #from kol.Error import Error as Error #import logging s = Session() # add booze terms here, make sure to use the same capitalization as in the recipe dictionary # searchTerms = ['parisian cathouse', 'prussian cathouse', 'vodka martini', 'rockin\' wagon', 'soft green echo eyedrop antidote martini', 'sangria de menthe'] searchTerms = ['soft green echo eyedrop antidote martini'] # add the ingredients as an array to the dictionary term recipe = { 'parisian cathouse': ['raspberry', 'boxed champagne'], 'prussian cathouse': ['parisian cathouse', 'magical ice cubes'], 'vodka martini': ['olive', 'bottle of vodka'], 'rockin\' wagon': ['vodka martini', 'magical ice cubes'], 'soft green echo eyedrop antidote martini': ['rockin\' wagon', 'soft green echo eyedrop antidote'], 'sangria de menthe': ['peppermint twist', 'boxed wine'] } # meat you are willing to spend in on each type booze meatLimit = 100000 # how much you want to undercut the lowest price on the market underCut = 1
# Kingdom of Loathing MallBot by KevZho (#2434890) # make sure to edit the options first on lines 15 to 27 # TODO: fix hitting the limits from kol.database import ItemDatabase from kol.Session import Session from kol.request.MallItemSearchRequest import MallItemSearchRequest from kol.request.MallItemPurchaseRequest import MallItemPurchaseRequest from kol.request.CocktailcraftingRequest import CocktailcraftingRequest from kol.request.AddItemsToStoreRequest import PutItemInStoreRequest #from kol.Error import Error as Error #import logging s = Session() # add booze terms here, make sure to use the same capitalization as in the recipe dictionary # searchTerms = ['parisian cathouse', 'prussian cathouse', 'vodka martini', 'rockin\' wagon', 'soft green echo eyedrop antidote martini', 'sangria de menthe'] searchTerms = ['soft green echo eyedrop antidote martini'] # add the ingredients as an array to the dictionary term recipe = {'parisian cathouse': ['raspberry', 'boxed champagne'], 'prussian cathouse': ['parisian cathouse', 'magical ice cubes'], 'vodka martini': ['olive', 'bottle of vodka'], 'rockin\' wagon': ['vodka martini', 'magical ice cubes'], 'soft green echo eyedrop antidote martini': ['rockin\' wagon', 'soft green echo eyedrop antidote'], 'sangria de menthe': ['peppermint twist', 'boxed wine']} # meat you are willing to spend in on each type booze meatLimit = 100000 # how much you want to undercut the lowest price on the market underCut = 1 # login with your username as password here s.login("username", "password") # end options myStoreId = s.userId result = {} def pad(word): return '"{0}"'.format(word)
def login(username, password): global _session _session = Session() _session.login(username, password)
This is script is the next logical iteration of example1; example1 just did things and didn't care if they worked or not. This script will show you how to take a different action if we couldn't do the intended action. In this case the action is really simple (print why it didn't work), but you can substitute any other action instead. We'll skip reading your mail in this example, since it's no different. """ from kol.Session import Session from kol.database import ItemDatabase from kol.request.Item import PulverizeRequest, UseItemRequest import kol.Error as Error print "Logging into the KoL Servers..." session = Session("username", "swordfish") print "Using an old coin purse:" try: item = ItemDatabase.getItemByName("old coin purse") use_request = UseItemRequest(session, item["id"]) print "Got %s meat from old coin purse" % use_request.responseData["meat"] except Error.Error, e: if e.code == Error.NOT_ENOUGH_ITEMS: print "Whoops! You didn't have an old coin purse to use...", e.message else: #we can raise the error again to stop the script: raise e print "Smashing a titanium assault umbrella:" try:
def post(self): s = Session() try: c1 = cookielib.Cookie(None, "PHPSESSID", memcache.get("PHPSESSID"), None, False, memcache.get("domain0"), True, False, memcache.get("path0"), True, False, None, False, None, False, None, False) jar = cookielib.CookieJar() jar.set_cookie(c1) c2 = cookielib.Cookie(None, "appserver", memcache.get("appserver"), None, False, memcache.get("domain1"), True, False, memcache.get("path1"), True, False, None, False, None, False, None, False) jar.set_cookie(c2) s.cj = jar s.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(s.cj)) s.isConnected = memcache.get("isConnected") s.userId = memcache.get("userId") s.userName = memcache.get("userName") s.userPasswordHash = memcache.get("userPasswordHash") s.serverURL = memcache.get("serverURL") s.pwd = memcache.get("pwd") s.rollover = memcache.get("rollover") except: logging.error("some memcache keys were deleted, logging in manually and setting memcache keys") s.login(Data.USERNAME, Data.PASSWORD) memcache.add(key="isConnected", value=bool(s.isConnected)) memcache.add(key="userId", value=int(s.userId)) memcache.add(key="userName", value=str(s.userName)) memcache.add(key="userPasswordHash", value=str(s.userPasswordHash)) memcache.add(key="serverURL", value=str(s.serverURL)) memcache.add(key="pwd", value=str(s.pwd)) memcache.add(key="rollover", value=int(s.rollover)) i = 0 for cookie in s.cj: logging.info("%s=%s" % (cookie.name, cookie.value)) memcache.add(key=cookie.name,value=str(cookie.value)) memcache.add(key="domain%d" % i, value=str(cookie.domain)) memcache.add(key="path%d" % i, value=str(cookie.path)) i += 1 # START DOING CRAP username = self.request.get("username") search = SearchPlayerRequest(s, username) uid = None try: uid = search.doRequest()['players'][0]["userId"] except: logging.error("dc'ed from server") s.login(Data.USERNAME, Data.PASSWORD) memcache.add(key="isConnected", value=bool(s.isConnected)) memcache.add(key="userId", value=int(s.userId)) memcache.add(key="userName", value=str(s.userName)) memcache.add(key="userPasswordHash", value=str(s.userPasswordHash)) memcache.add(key="serverURL", value=str(s.serverURL)) memcache.add(key="pwd", value=str(s.pwd)) memcache.add(key="rollover", value=int(s.rollover)) i = 0 for cookie in s.cj: logging.info("%s=%s" % (cookie.name, cookie.value)) memcache.add(key=cookie.name,value=str(cookie.value)) memcache.add(key="domain%d" % i, value=str(cookie.domain)) memcache.add(key="path%d" % i, value=str(cookie.path)) i += 1 uid = search.doRequest()['players'][0]["userId"] logging.info("Player: {0}, Buffs: {1}".format(username, self.request.get("buffs"))) splitBuffs = self.request.get("buffs").split("\n") msg = { "userId": s.userId, "text": "" } for buff in splitBuffs: msg["text"] += "%s %s %s\n" % (Data.secretKey, uid, buff) send = SendMessageRequest(s, msg) send.doRequest() self.response.out.write("Buff request received. Your buffs will arrive shortly. Redirecting to web buff page in 5 seconds.") self.response.out.write('''<script type="text/javascript">setTimeout("window.location='/web/'", 5000)</script>''')
def runTest(self): s = Session() s.login(TestData.data["userName"], TestData.data["password"]) self.assert_(s.isConnected == True) TestData.data["session"] = s
class SignBot(object): def __init__(self, username, password, out=sys.stdout, fmt='%Y-%m-%d %H:%M:%S', caps={ 'sign': True, 'spider': True, 'arrow': True }): """ username, password The KoL login credentials of your bot account. out Unless otherwise specified, the bot logs to sys.stdout. Provide an object with a write() method (like an open file) to change. (We won't close it.) fmt Format for the log timestamps. caps By default, the bot responds to blue messages by reporting "KICK ME" sign status, and to green messages by using rubber spiders and time's arrows contained therein. Set caps['sign'], caps['spider'], and/or caps['arrow'] to False (or omit them) to disable specific behaviours. Once the bot object is constructed, run it with go(). """ self.username, self.password = username, password self.out, self.fmt, self.caps = out, fmt, caps self.start, self.actions = time.time(), 0 def go(self): """ Actually run the bot. """ self.log('Logging in.') self.__session = Session() self.__session.login(self.username, self.password) self.__chat = ChatManager(self.__session) while True: for msg in self.__fetch_chat_messages(): if msg['type'] == 'private' and self.caps.get('sign', False): # Got a blue message! Report "KICK ME" sign status self.log('{userName} (#{userId}) sent me ' 'a blue message: "{text}"'.format(**msg)) self.__sign(msg['userId']) elif msg['type'] == 'notification:kmail': # Got a green message! self.log('{userName} (#{userId}) sent me ' 'a green message.'.format(**msg)) # Fetch it and examine it kmail = self.__get_kmail(msg['userName']) if kmail['text']: self.log('They said: "{}"'.format(kmail['text'])) if kmail['meat'] > 0: self.log('They sent {} meat.'.format(kmail['meat'])) # Look at the items they sent for item in kmail['items']: self.log('They sent {} {}.'.format( item['quantity'], item['name'] if item['quantity'] == 1 else item['plural'])) if item['id'] == 7698 and self.caps.get( 'spider', False): # Rubber spider self.__use_spider(msg['userId']) elif item['id'] == 4939 and self.caps.get( 'arrow', False): # Time's arrow self.__use_arrow(msg['userId']) # Don't keep it self.__del_kmail(kmail['id']) time.sleep(1) def __del__(self): # Convert running time to a human-readable format hours, t = divmod(time.time() - self.start, 3600) minutes, seconds = divmod(t, 60) duration = [] if hours: duration.append('{} hours'.format(int(hours))) if minutes: duration.append('{} minutes'.format(int(minutes))) if seconds: duration.append('{} seconds'.format(int(seconds))) if not duration: duration = 'a moment' else: duration = ' and '.join(duration) # Last words self.log("I existed for {}, helped {} {}, and now I am dead.".format( duration, self.actions, 'people' if self.actions != 1 else 'person')) def __fetch_chat_messages(self): try: return self.__chat.getNewChatMessages() except AttributeError: # Work around a pykol bug return [] def __chat_say(self, pid, text): self.__chat.sendChatMessage('/msg {} {}'.format(pid, text)) self.log('I told #{} "{}"'.format(pid, text)) def __get_kmail(self, username): # Fetch all of our green messages r = GetMessagesRequest(self.__session, oldestFirst=True) r.doRequest() r.parseResponse() # Return the most recent one sent by username for kmail in r.responseData['kmails']: if kmail['userName'] == username: return kmail # This is unexpected enough to crash the bot raise Exception("Couldn't find a kmail by {}!".format(username)) def __del_kmail(self, mid): d = DeleteMessagesRequest(self.__session, [mid]) d.doRequest() def __sign(self, pid): # Fetch user's profile page r = GenericRequest(self.__session) r.url = 'http://www.kingdomofloathing.com/showplayer.php?who={}'.format( pid) r.doRequest() # Check for the sign r = re.search( r'<img alt="Placed by [^"]+" title="Placed by ([^"]+)" ' r'style="position: absolute; left: 0px; top: 0px" src="' r'http://images.kingdomofloathing.com/otherimages/kickm' r'e.png" height="100" width="60" />', r.responseText) if r is None: resp = "You're clean." else: resp = "{} tagged you!".format(r.group(1)) self.__chat_say(pid, resp) self.actions += 1 def __use_arrow(self, pid): try: # Try to use a time's arrow on them c = CursePlayerRequest(self.__session, pid, 4939) c.doRequest() except Exception as e: # Something went wrong! Maybe they're in HC or ronin self.log("I couldn't use an arrow on them: {}".format(str(e))) self.__chat_say(pid, "I couldn't use that arrow on you.") else: # Success! No need to tell them, they'll be notified self.log("I used an arrow on them.") self.actions += 1 def __use_spider(self, pid): try: # Try to use a rubber spider on them c = CursePlayerRequest(self.__session, pid, 7698) c.doRequest() except Exception as e: # Something went wrong! Maybe they're in HC or ronin self.log("I couldn't use a spider on them: {}".format(str(e))) self.__chat_say(pid, "I couldn't use that spider on you.") else: # Success! Tell them they can expect their spider self.log("I used a spider on them.") self.__chat_say(pid, "I used that spider on you.") self.actions += 1 def log(self, text): """ Output time-stamped text to self.out. """ self.out.write('{} -- {}\n'.format(time.strftime(self.fmt), text))
def doStuff(): logging.debug("doStuff()") s = Session() try: c1 = cookielib.Cookie(None, "PHPSESSID", memcache.get("PHPSESSID"), None, False, memcache.get("domain0"), True, False, memcache.get("path0"), True, False, None, False, None, False, None, False) jar = cookielib.CookieJar() jar.set_cookie(c1) c2 = cookielib.Cookie(None, "appserver", memcache.get("appserver"), None, False, memcache.get("domain1"), True, False, memcache.get("path1"), True, False, None, False, None, False, None, False) jar.set_cookie(c2) s.cj = jar s.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(s.cj)) s.isConnected = memcache.get("isConnected") s.userId = memcache.get("userId") s.userName = memcache.get("userName") s.userPasswordHash = memcache.get("userPasswordHash") s.serverURL = memcache.get("serverURL") s.pwd = memcache.get("pwd") s.rollover = memcache.get("rollover") except: logging.error("some memcache keys were deleted") m = None messages = None try: m = GetMessagesRequest(s) messages = m.doRequest() except: logging.warn("Not logged in, logging in") memcache.flush_all() s = Session() s.login(Data.USERNAME, Data.PASSWORD) memcache.add(key="isConnected", value=bool(s.isConnected)) memcache.add(key="userId", value=int(s.userId)) memcache.add(key="userName", value=str(s.userName)) memcache.add(key="userPasswordHash", value=str(s.userPasswordHash)) memcache.add(key="serverURL", value=str(s.serverURL)) memcache.add(key="pwd", value=str(s.pwd)) memcache.add(key="rollover", value=int(s.rollover)) i = 0 for cookie in s.cj: logging.info("%s=%s" % (cookie.name, cookie.value)) memcache.add(key=cookie.name,value=str(cookie.value)) memcache.add(key="domain%d" % i, value=str(cookie.domain)) memcache.add(key="path%d" % i, value=str(cookie.path)) i += 1 m = GetMessagesRequest(s) messages = m.doRequest() for kmail in messages["kmails"]: logging.info("%s sent kmail with text %s" % (kmail["userName"], kmail["text"])) msg = kmail["text"].split("\n") totalMP = 0 totalCost = 0 buffsCast = [] for randomBuff in msg: specialCase = False specialUID = None info = randomBuff.split(" ") buff = "" duration = 0 if not info[0].isdigit(): if info[0] == Data.secretKey: specialCase = True specialUID = int(info[1]) else: logging.info("No duration set") buff = " ".join(info) logging.info("Need to interpret %s" % buff) duration = 50 else: logging.info("Duration set for %d" % int(info[0])) buff = " ".join(info)[len(info[0]) + 1:] logging.info("Need to interpret %s" % buff) duration = int(info[0]) if int(info[0]) < Data.MAXLENGTH else Data.MAXLENGTH if specialCase: if len(info) >= 3: if not info[2].isdigit(): logging.info("No duration set") buff = " ".join(info)[len(info[0]) + len(info[1]) + 2:] logging.info("Need to interpret %s" % buff) duration = 50 else: logging.info("Duration set for %d" % int(info[2])) buff = " ".join(info)[len(info[0]) + len(info[1]) + len(info[2]) + 3:] logging.info("Need to interpret %s" % buff) duration = int(info[2]) if int(info[2]) < Data.MAXLENGTH else Data.MAXLENGTH theBuff = None for key in Data.buffs.keys(): if buff.lower() in key.lower(): theBuff = Data.buffs[key] logging.info("keyword '{0}' matched for {1}".format(buff, key)) if theBuff is not None and buff != "": shouldBuff = True c = CharpaneRequest(s) charData = c.doRequest() currentMP = charData["currentMP"] timesNeeded = int(math.ceil(float(duration)/float(Data.ACCORDION_DURATION))) logging.info("Current: MP: {0}, meat: {1}".format(currentMP, charData["meat"])) logging.info("Current MP: {0}, Need: {1}".format(currentMP, (theBuff["mp"] - Data.MPCOSTREDUCTION) * timesNeeded)) if "once" not in theBuff: while currentMP < (theBuff["mp"] - Data.MPCOSTREDUCTION) * timesNeeded < charData["maxMP"]: if currentMP > (theBuff["mp"] - Data.MPCOSTREDUCTION) * timesNeeded: logging.error("Should not be here!") break if charData["meat"] > 94: logging.warn("Out of MP. Buying mystery juice") store = StoreRequest(s, 2, 518) try: store.doRequest() except: logging.error("dc'ed from server") s = Session() memcache.flush_all() s.login(Data.USERNAME, Data.PASSWORD) store.doRequest() memcache.add(key="isConnected", value=bool(s.isConnected)) memcache.add(key="userId", value=int(s.userId)) memcache.add(key="userName", value=str(s.userName)) memcache.add(key="userPasswordHash", value=str(s.userPasswordHash)) memcache.add(key="serverURL", value=str(s.serverURL)) memcache.add(key="pwd", value=str(s.pwd)) memcache.add(key="rollover", value=int(s.rollover)) i = 0 for cookie in s.cj: logging.info("%s=%s" % (cookie.name, cookie.value)) memcache.add(key=cookie.name,value=str(cookie.value)) memcache.add(key="domain%d" % i, value=str(cookie.domain)) memcache.add(key="path%d" % i, value=str(cookie.path)) i += 1 u = UseItemRequest(s, 518) u.doRequest() totalCost += 95 currentMP = c.doRequest()["currentMP"] else: logging.error("No meat or MP, stopping") shouldBuff = False break else: while currentMP < (theBuff["mp"] - Data.MPCOSTREDUCTION) < charData["maxMP"]: if currentMP > (theBuff["mp"] - Data.MPCOSTREDUCTION): logging.error("Should not be here!") break if charData["meat"] > 94: logging.warn("Out of MP. Buying mystery juice") store = StoreRequest(s, 2, 518) try: store.doRequest() except: logging.error("dc'ed from server") s = Session() memcache.flush_all() s.login(Data.USERNAME, Data.PASSWORD) store.doRequest() memcache.add(key="isConnected", value=bool(s.isConnected)) memcache.add(key="userId", value=int(s.userId)) memcache.add(key="userName", value=str(s.userName)) memcache.add(key="userPasswordHash", value=str(s.userPasswordHash)) memcache.add(key="serverURL", value=str(s.serverURL)) memcache.add(key="pwd", value=str(s.pwd)) memcache.add(key="rollover", value=int(s.rollover)) i = 0 for cookie in s.cj: logging.info("%s=%s" % (cookie.name, cookie.value)) memcache.add(key=cookie.name,value=str(cookie.value)) memcache.add(key="domain%d" % i, value=str(cookie.domain)) memcache.add(key="path%d" % i, value=str(cookie.path)) i += 1 u = UseItemRequest(s, 518) u.doRequest() totalCost += 95 currentMP = c.doRequest()["currentMP"] else: logging.error("No meat or MP, stopping") shouldBuff = False break if shouldBuff and theBuff["available"] and (theBuff["mp"] - Data.MPCOSTREDUCTION) * timesNeeded < charData["maxMP"]: if not specialCase: skill = UseSkillRequest(s, theBuff["id"], 1, kmail["userId"]) if "once" in theBuff else UseSkillRequest(s, theBuff["id"], timesNeeded, kmail["userId"]) logging.info("Buffing %s with %s" % (kmail["userName"], getSkillFromId(theBuff["id"])["name"])) try: skill.doRequest() totalMP += (theBuff["mp"] - Data.MPCOSTREDUCTION) * timesNeeded buffsCast.append(theBuff["id"]) except: logging.fatal("Casting error for KMail request.") else: skill = UseSkillRequest(s, theBuff["id"], 1, specialUID) if "once" in theBuff else UseSkillRequest(s, theBuff["id"], timesNeeded, specialUID) logging.info("Buffing %s with %s" % (specialUID, getSkillFromId(theBuff["id"])["name"])) try: skill.doRequest() totalMP += (theBuff["mp"] - Data.MPCOSTREDUCTION) * timesNeeded buffsCast.append(theBuff["id"]) except: logging.fatal("Casting error for web interface request.") else: logging.warn("No buff found matching %s" % buff) msg = None if not specialCase: msg = { "userId": kmail["userId"], "text": "Thanks for using BuffBot!\nTotal MP used: {0}\nTotal meat spent on magical mystery juice: {1}".format(totalMP, totalCost) } else: msg = { "userId": specialUID, "text": "Thanks for using BuffBot!\nTotal MP used: {0}\nTotal meat spent on magical mystery juice: {1}".format(totalMP, totalCost) } for someBuff in buffsCast: msg["text"] += "\nGave buff: %s" % getSkillFromId(someBuff)["name"] if len(buffsCast) > 0: send = SendMessageRequest(s, msg) send.doRequest() logging.info("KMail sent") else: if not specialCase: msg = { "userId": kmail["userId"], "text": "Thanks for using BuffBot!\nEither one of two things happened:\n1. BuffBot ran out of meat and MP, so it couldn't complete your request. Please send some meat next time for some magical mystery juice if this is the case.\n2. BuffBot did not know how to interpret your input. If this is the case, please refer to http://rubuffbot.appspot.com/faq/ for information on how to use BuffBot." } else: msg = { "userId": specialUID, "text": "Thanks for using BuffBot!\nEither one of two things happened:\n1. BuffBot ran out of meat and MP, so it couldn't complete your request. Please send some meat next time for some magical mystery juice if this is the case.\n2. BuffBot did not know how to interpret your input. If this is the case, please refer to http://rubuffbot.appspot.com/faq/ for information on how to use BuffBot." } send = SendMessageRequest(s, msg) send.doRequest() d = DeleteMessagesRequest(s, [kmail["id"]]) d.doRequest() logging.info("KMail deleted") c = CharpaneRequest(s) charData = c.doRequest() logging.info("Final MP and Meat: {0}, {1}".format(charData["currentMP"], charData["meat"]))
config = ConfigParser.RawConfigParser(allow_no_value=True) config.readfp(args.c) guser = config.get('google','user') gpwd = config.get('google','passwd') gsheet = config.get('google','sheet') client, curr_key, curr_wksht_id = google_login(guser,gpwd,gsheet) nrl = get_names(client, curr_key, curr_wksht_id) #get names and thier row names = nrl.keys() # list of names fastest = {} # Login to the KoL servers. s = Session() s.login(config.get('kol','user'), config.get('kol','passwd')) uids = get_uids(s,names) # lookup uids from names #for each users grab their fastest ascensions and update the spreadsheet with them #for name, uid in uids.items(): pnames = uids.keys() pnames.sort() for name in pnames: uid = uids[name] fastest[name] = get_hist(s, uid, starts, ends) print name, fastest[name].keys() update_spread(client, curr_key, curr_wksht_id, nrl[name],fastest[name]) s.logout()
import android, sys, json, time from kol.Session import Session from kol.request.CharpaneRequest import CharpaneRequest from kol.request.InventoryRequest import InventoryRequest from kol.request.MallItemSearchRequest import MallItemSearchRequest from kol.request.MallItemPurchaseRequest import MallItemPurchaseRequest from kol.Error import Error from kol.manager.ChatManager import ChatManager droid = android.Android() s = Session() charMgr = None def eventloop(): global s global chatMgr while True: event = droid.eventWait().result if event["name"] == "key" and event["data"]["key"] == "4": return if event["name"] == "login": try: title = "Logging in..." message = 'KoL for Android is logging you in...' droid.dialogCreateSpinnerProgress(title, message) droid.dialogShow() try: loginData = json.loads(event["data"]) s.login(loginData["user"], loginData["pass"]) if s.isConnected:
class SignBot(object): def __init__(self, username, password, out=sys.stdout, fmt='%Y-%m-%d %H:%M:%S', caps={'sign': True, 'spider': True, 'arrow': True, 'fun': True, 'tweet': 'dril', 'avatar': True, 'wang': True}): """ username, password The KoL login credentials of your bot account. out Unless otherwise specified, the bot logs to sys.stdout. Provide an object with a write() method (like an open file) to change. (We won't close it.) fmt Format for the log timestamps. caps By default, the bot responds to blue messages by reporting "KICK ME" sign status, and to green messages by using rubber spiders, time's arrows, and avatar potions contained therein, by using a wang on usernames therein, and by responding with tweets (as in Twitter) if sent meat. Set caps['sign'], caps['spider'], caps['arrow'], caps['fun'], caps['avatar'], caps['wang'] to False (or omit them) to disable specific behaviours. caps['tweet'] must be a valid Twitter username or False. Once the bot object is constructed, run it with go(). """ self.username, self.password = username, password self.out, self.fmt = out, fmt self.caps = collections.defaultdict(lambda: False, caps) self.start = time.time() bookkeeping[id(self)] = [time.time(), 0] self.cache = {} def go(self): """ Actually run the bot. """ global active self.log('Logging in.') self.__session = Session() self.__session.login(self.username, self.password) self.__chat = ChatManager(self.__session) active = time.time() # Check pending kmails for kmail in self.__get_kmails(): self.__handle_kmail(kmail) while True: if time.time() - active > 3600: # Chat occasionally dies quietly. Maybe that happened. raise Exception("Inactive for too long.") for msg in self.__fetch_chat_messages(): if msg['type'] == 'private' and self.caps['sign']: # Got a blue message! Report "KICK ME" sign status self.log('{userName} (#{userId}) sent me ' 'a blue message: "{text}"'.format(**msg)) self.__sign(msg['userName'], msg['userId']) elif msg['type'] == 'notification:kmail': # Got a green message! self.log('{userName} (#{userId}) sent me ' 'a green message.'.format(**msg)) # Fetch it and examine it for kmail in self.__get_kmails(msg['userName'], 1): self.__handle_kmail(kmail) active = time.time() time.sleep(1) def __del__(self): # Convert running time to a human-readable format start, actions = bookkeeping[id(self)] hours, t = divmod(time.time() - start, 3600) minutes, seconds = divmod(t, 60) duration = [] if hours: duration.append('{} hours'.format(int(hours))) if minutes: duration.append('{} minutes'.format(int(minutes))) if seconds: duration.append('{} seconds'.format(int(seconds))) if not duration: duration = 'a moment' else: duration = ' and '.join(duration) # Last words self.log("I existed for {}, helped {} {}, and now I am dead.".format( duration, actions, 'people' if actions != 1 else 'person')) del bookkeeping[id(self)] def __fetch_chat_messages(self, retry=0): try: return self.__chat.getNewChatMessages() except AttributeError: # Work around a pykol bug return [] except ConnectionError: if retry == 3: raise self.__chat = ChatManager(self.__session) return self.__fetch_chat_messages(retry + 1) def __chat_say(self, pname, pid, text): self.__chat.sendChatMessage('/msg {} {}'.format(pid, text)) self.log('I told {} (#{}) "{}"'.format(pname, pid, text)) def __get_kmails(self, pname=None, limit=None): # Fetch all of our green messages r = GetMessagesRequest(self.__session, oldestFirst=True) r.doRequest() r.parseResponse() # Yield an apprioprate amount, LIFO for kmail in r.responseData['kmails']: if limit is not None and limit <= 0: break if pname is None or kmail['userName'] == pname: yield kmail if limit is not None: limit -= 1 def __handle_kmail(self, kmail): if kmail['text']: self.log('They said: "{}"'.format(kmail['text'])) if (self.caps['wang'] and kmail['text'] != "Keep the contents of this message " "top-sekrit, ultra hush-hush."): self.__use_wang(kmail['userName'], kmail['userId'], kmail['text']) if kmail['meat'] > 0: self.log('They sent {} meat.'.format(kmail['meat'])) if self.caps['tweet']: self.__send_kmail(kmail['userName'], kmail['userId'], tweet(self.caps['tweet'])) # Look at the items they sent for item in kmail['items']: self.log('They sent {} {}.'.format( item['quantity'], item['name'] if item['quantity'] == 1 else item['plural'])) if item['id'] == 7698 and self.caps['spider']: # Rubber spider self.__use_spider(kmail['userName'], kmail['userId']) elif item['id'] == 4939 and self.caps['arrow']: # Time's arrow self.__use_arrow(kmail['userName'], kmail['userId']) elif item['id'] == 4811 and self.caps['fun']: # Holiday Fun! for _ in range(item['quantity']): self.__send_holiday_fun(kmail['userName'], kmail['userId']) elif item['id'] in avatar_potions and self.caps['avatar']: self.__change_avatar(item['id'], kmail['userName'], kmail['userId']) # Don't keep it self.__del_kmail(kmail['id']) def __del_kmail(self, mid): d = DeleteMessagesRequest(self.__session, [mid]) d.doRequest() def __send_kmail(self, pname, pid, message, item=None): msg = {'userId': pid, 'text': message} if item: msg['items'] = [{'id': item, 'quantity': 1}] r = SendMessageRequest(self.__session, msg) r.doRequest() self.log('I sent a kmail to {} (#{}): "{}"'.format(pname, pid, message)) if item: self.log('I sent them an item: {}'.format( {4939: "time's arrow", 7698: "rubber spider", 4811: "Holiday Fun!"}.get(item, "item #{}".format(item)))) def __sign(self, pname, pid): # "KICK ME" signs persist until rollover; SignBot does not persist # across rollovers. # If we've ever seen a player tagged, we know he'll always be tagged # by the same person while we exist, so we can just save that in a # cache. if pname not in self.cache: # Fetch user's profile page url = 'http://www.kingdomofloathing.com/showplayer.php?who={}'.format(pid) profile = self.__session.opener.open(url, {}).text # Check for the sign r = re.search(r'<img alt="Placed by [^"]+" title="Placed by ([^"]' r'+)" style="position: absolute; left: 0px; top: 0p' r'x" src="http://images.kingdomofloathing.com/other' r'images/kickme.png" height="100" width="60" />', profile) if r is not None: self.cache[pname] = r.group(1) else: self.log("Cache hit: {} (#{})".format(pname, pid)) if pname not in self.cache: resp = "You're clean." else: resp = "{} tagged you!".format(self.cache[pname]) self.__chat_say(pname, pid, resp) bookkeeping[id(self)][1] += 1 def __use_arrow(self, pname, pid): try: # Try to use a time's arrow on them c = CursePlayerRequest(self.__session, pid, 4939) c.doRequest() except Exception as e: # Something went wrong! Maybe they're in HC or ronin self.log("I couldn't use an arrow on them: {}".format(str(e))) try: self.__send_kmail(pname, pid, "I couldn't use that arrow on you, " "so I'm returning it.", 4939) except Error as e2: self.log("I couldn't return their arrow: {}".format(str(e2))) self.__chat_say(pname, pid, "I couldn't use that arrow on you and " "something went wrong when I tried to " "return it. Sorry!") else: # Success! No need to tell them, they'll be notified self.log("I used an arrow on {} (#{})".format(pname, pid)) bookkeeping[id(self)][1] += 1 def __use_spider(self, pname, pid): try: # Try to use a rubber spider on them c = CursePlayerRequest(self.__session, pid, 7698) c.doRequest() except Exception as e: # Something went wrong! Maybe they're in HC or ronin self.log("I couldn't use a spider on {} (#{}): {}".format( pname, pid, str(e))) try: self.__send_kmail(pname, pid, "You already have a rubber spider on you, " "so I'm returning this one.", 7698) except Error as e2: self.log("I couldn't return their spider: {}".format(str(e2))) self.__chat_say(pname, pid, "I couldn't use that spider on you and " "something went wrong when I tried to " "return it. Sorry!") else: # Success! Tell them they can expect their spider self.log("I used a spider on {} (#{}).".format(pname, pid)) self.__chat_say(pname, pid, "I used that spider on you.") bookkeeping[id(self)][1] += 1 def __use_wang(self, pname, pid, target): try: c = CursePlayerRequest(self.__session, target, 625) c.doRequest() except Error as e: if e.code == kol.Error.ITEM_NOT_FOUND: self.__chat_say(pname, pid, "I'm sorry, I'm out of wangs.") elif e.code == kol.Error.USER_NOT_FOUND: self.__chat_say(pname, pid, "Your kmail contained a message but it wasn't a valid " "username.") else: self.log("Something went wrong wanging: " + e) else: if target != pname: self.__chat_say(pname, pid, "Successfully wanged {}.".format(target)) else: self.log("Successfully wanged {}.".format(target)) def __send_holiday_fun(self, pname, pid): url = "http://www.kingdomofloathing.com/town_sendgift.php" data = {'whichpackage': 1, 'towho': pid, 'note': 'Your Holiday Fun!, courtesy of SignBot Industries.', 'insidenote': 'Have a day.', 'whichitem1': 4811, 'howmany1': 1, 'fromwhere': 0, 'action': 'Yep.', 'pwd': self.__session.pwd} resp = self.__session.opener.open(url, data) m = re.search(r'<table width=95% cellspacing=0 cellpadding=0><tr>' r'<td style="color: white;" align=center bgcolor=blue' r'><b>Results:</b></td></tr><tr><td style="padding: 5' r'px; border: 1px solid blue;"><center><table><tr><td' r'>(.*?)</td></tr></table>', resp.text) if m is not None and m.group(1) == 'Package sent.': self.log('I successfully sent {} (#{}) a plain brown wrapper ' 'containing some Holiday Fun!'.format(pname, pid)) else: err = m.group(1) if m is not None else 'Unspecified error.' self.__send_kmail(pname, pid, "I couldn't send you a gift package because of the " "following problem: {}".format(err), 4811) def __change_avatar(self, potion, pname, pid): try: # Find the IDs of the hard-shruggable effects we're under url = 'http://www.kingdomofloathing.com/charpane.php' pane = self.__session.opener.open(url, {}).text effects = [int(e) for e in re.findall('return hardshrug\((\d+),', pane)] # Uneffect all active avatar potions for effect in avatar_potions.values(): if effect in effects: UneffectRequest(self.__session, effect).doRequest() self.log("Uneffected ID #{}.".format(effect)) # Use the new one and inform the person UseItemRequest(self.__session, potion).doRequest() self.log("Used avatar potion #{}.".format(potion)) self.__chat_say(pname, pid, "Look at me!") except Error: try: self.__send_kmail(pname, pid, "I couldn't use that avatar potion so I'm returning it.", potion) except: self.__chat_say(pname, pid, "I couldn't use that avatar potion and I couldn't return " "it to you. Sorry.") def log(self, text): """ Output time-stamped text to self.out. """ self.out.write('{} -- {}\n'.format(time.strftime(self.fmt), text)) self.out.flush()