Example #1
0
    def login(self, username, password, serverNumber=0):
        """
        Perform a KoL login given a username and password. A server number may also be specified
        to ensure that the user logs in using that particular server. This can be helpful
        if the user continues to be redirected to a server that is down.
        """

        self.userName = username
        self.userPasswordHash = hashlib.md5(password).hexdigest()

        # Grab the KoL homepage.
        homepageRequest = HomepageRequest(self, serverNumber=serverNumber)
        homepageResponse = homepageRequest.doRequest()
        self.serverURL = homepageResponse["serverURL"]

        # Perform the login.
        loginRequest = LoginRequest(self, homepageResponse["loginChallenge"])
        loginRequest.doRequest()

        # Load the charpane once to make StatusRequest report the rollover time
        charpaneRequest = CharpaneRequest(self)
        charpaneRequest.doRequest()

        # Get pwd, user ID, and the user's name.
        request = StatusRequest(self)
        response = request.doRequest()
        self.pwd = response["pwd"]
        self.userName = response["name"]
        self.userId = int(response["playerid"])
        self.rollover = int(response["rollover"])
Example #2
0
    def login(self, username, password, serverNumber=0):
        """
        Perform a KoL login given a username and password. A server number may also be specified
        to ensure that the user logs in using that particular server. This can be helpful
        if the user continues to be redirected to a server that is down.
        """

        self.userName = username
        self.userPasswordHash = hashlib.md5(password).hexdigest()

        # Grab the KoL homepage.
        homepageRequest = HomepageRequest(self, serverNumber=serverNumber)
        homepageResponse = homepageRequest.doRequest()
        self.serverURL = homepageResponse["serverURL"]

        # Perform the login.
        loginRequest = LoginRequest(self, homepageResponse["loginChallenge"])
        loginRequest.doRequest()

        # Load the charpane once to make StatusRequest report the rollover time
        charpaneRequest = CharpaneRequest(self)
        charpaneRequest.doRequest()

        # Get pwd, user ID, and the user's name.
        request = StatusRequest(self)
        response = request.doRequest()
        self.pwd = response["pwd"]
        self.userName = response["name"]
        self.userId = int(response["playerid"])
        self.rollover = int(response["rollover"])
Example #3
0
def doFilter(eventName, context, **kwargs):
    bot = kwargs["bot"]
    charpaneRequest = CharpaneRequest(bot.session)
    response = charpaneRequest.doRequest()
    if len(response.get("effects", [])) > 0:
        for effect in response["effects"]:
            if effect["name"] == "B-b-brr!":
                uneffect(bot, 718)
            elif effect["name"] == "Bruised Jaw":
                uneffect(bot, 697)
        
    returnCode = FilterManager.FINISHED
    return returnCode
Example #4
0
    def _heartbeat(self):
        # actual breakfast is done inside the heartbeat thread to make it
        # asynchronous.
        if self._breakfasted or not self._initialized:
            return
        self._breakfasted = True
        r = RumpusRoomRequest(self.session)
        d1 = self.tryRequest(r)
        d = d1.get('furniture', [])
        sourceList = []

        self.log("Performing breakfast...")
        if 'A Mr. Klaw "Skill" Crane Game' in d:
            success = self._doRequest(MrKlawRequest)
            success |= self._doRequest(MrKlawRequest)
            success |= self._doRequest(MrKlawRequest)
            if success:
                sourceList.append("Mr. Klaw")
        if "An Exotic Hanging Meat Orchid" in d:
            success = self._doRequest(MeatOrchidRequest)
            if success:
                sourceList.append("Meat Orchid")
        if "A Potted Meat Bush" in d:
            success = self._doRequest(MeatBushRequest)
            if success:
                sourceList.append("Meat Bush")
        if "A Potted Meat Tree" in d:
            success = self._doRequest(MeatTreeRequest)
            if success:
                sourceList.append("Meat Tree")
        if self._vip:
            success = self._doRequest(CrimboTreeRequest)
            if success:
                sourceList.append("Crimbo Tree")
            success = self._doRequest(LookingGlassRequest)
            if success:
                sourceList.append("Looking Glass")
            success = self._doRequest(DeluxeMrKlawRequest)
            success |= self._doRequest(DeluxeMrKlawRequest)
            success |= self._doRequest(DeluxeMrKlawRequest)
            if success:
                sourceList.append("Deluxe Mr. Klaw")

        r = CharpaneRequest(self.session)
        d = self.tryRequest(r, nothrow=True)
        if d is not None and d['meat'] > 2000:
            success = self._getClover()
            while success:
                success = self._getClover()

        if self._meat > 0 or len(self._items) > 0:
            itemTxt = '\n'.join("{}x {}".format(qty, name)
                                for name, qty in self._items.items()
                                if qty != 0)
            self.log("Breakfast results:\nGot {} meat and the following "
                     "items:\n{}".format(self._meat, itemTxt))
        else:
            self.log("Got nothing.")
Example #5
0
def mainloop():
    global s
    global chatMgr
    while True:
        event = droid.eventWait().result
        if event["name"] == "key" and event["data"]["key"] == "4":
            return

        id = event["name"]
        if id == "makeToast":
            droid.makeToast(event["data"])
        elif id == "charData":
            droid.dialogCreateSpinnerProgress("Loading", "Loading...")
            droid.dialogShow()
            c = CharpaneRequest(s)
            response = None
            try:
                response = c.doRequest()
            except Error as e:
                alertNotLoggedIn(True)
            message = ""
            title = "Character Data"
            for key in response.keys():
                if key != "effects":
                    message += "%s: %s\n" % (key, response[key])
                else:
                    message += "-------\nEFFECTS:\n"
                    for effect in response["effects"]:
                        message += " - " + effect["name"] + ": " + str(
                            effect["turns"]) + "\n"
            droid.dialogDismiss()
            droid.dialogCreateAlert(title, message)
            droid.dialogSetPositiveButtonText("OK")
            droid.dialogShow()
            # objectPost("charDataInfo", response)
        elif id == "inventory":
            droid.dialogCreateSpinnerProgress("Loading", "Loading...")
            droid.dialogShow()
            i = InventoryRequest(s)
            response = None
            try:
                response = i.doRequest()
            except Error as e:
                alertNotLoggedIn(True)
            title = "Inventory"
            message = ""
            for key in response["items"]:
                message += "%s: %s\n" % (key["name"], key["quantity"])
            droid.dialogDismiss()
            droid.dialogCreateAlert(title, message)
            droid.dialogSetPositiveButtonText("OK")
            droid.dialogShow()
            # objectPost("inventoryInfo", response)
        elif id == "findInventory":
            droid.dialogCreateInput(
                "Item to find:",
                "Enter the name (or partial name) of the item to find")
            droid.dialogSetPositiveButtonText("OK")
            droid.dialogSetNegativeButtonText("Cancel")
            droid.dialogShow()
            response = droid.dialogGetResponse().result
            if response.has_key("which") and response[
                    "which"] == "positive" and response.has_key(
                        "value") and response["value"] != "":
                droid.dialogCreateSpinnerProgress("Searching...",
                                                  "Finding items...")
                droid.dialogShow()
                i = InventoryRequest(s)
                inventory = None
                try:
                    inventory = i.doRequest()
                except Error as e:
                    alertNotLoggedIn(True)
                title = "Search results"
                message = ""
                for item in inventory["items"]:
                    if item.has_key("name") and response["value"].lower(
                    ) in item["name"].lower():
                        message += "%s: %s\n" % (item["name"],
                                                 item["quantity"])
                if message == "":
                    message = "No item matching %s was found" % response[
                        "value"]
                droid.dialogDismiss()
                droid.dialogCreateAlert(title, message)
                droid.dialogSetPositiveButtonText("OK")
                droid.dialogShow()
        elif id == "getNewChat":
            try:
                objectPost("getNewChatResult", chatMgr.getNewChatMessages())
            except Error as e:
                alertNotLoggedIn(True)
        elif id == "sendChat":
            try:
                data = json.loads(event["data"])
                chatMgr.sendChatMessage("/" + data["channel"] + " " +
                                        data["message"])
                droid.eventPost("sendChatResult", "success")
            except Error as e:
                droid.eventPost("sendChatResult", "fail")
        elif id == "getChannels":
            try:
                pass
            except Error as e:
                alertNotLoggedIn(True)
        elif id == "searchMall":
            try:
                m = MallItemSearchRequest(s, event["data"], numResults=10)
                droid.dialogCreateSpinnerProgress(
                    "Searching...", "Searching for \"%s\"" % event["data"])
                droid.dialogShow()
                objectPost("searchMallResult", m.doRequest())
                droid.dialogDismiss()
            except Error as e:
                alertNotLoggedIn(True)
        elif id == "buyMall":
            droid.dialogCreateInput("Purchase mall item",
                                    "Enter quantity to purchase", "0",
                                    "number")
            droid.dialogSetPositiveButtonText("OK")
            droid.dialogSetNegativeButtonText("Cancel")
            droid.dialogShow()
            resp = droid.dialogGetResponse().result
            evtdata = None
            try:
                evtdata = json.loads(event["data"])
                droid.log("evtdata loaded from string")
                droid.log("evtdata = %s" % event["data"])
                buy = MallItemPurchaseRequest(s, evtdata["storeId"],
                                              evtdata["id"], evtdata["price"],
                                              resp["value"])
                droid.log("MIPR created")
                droid.dialogCreateSpinnerProgress("Buying...",
                                                  "Buying item(s)...")
                droid.dialogShow()
                buyResponse = buy.doRequest()
                droid.dialogDismiss()
                droid.dialogCreateAlert(
                    "Results", "Brought %s for %d" %
                    (resp["value"], buyResponse["meatSpent"]))
                droid.dialogSetPositiveButtonText("OK")
                droid.dialogShow()
            except Error as e:
                droid.dialogCreateAlert("Results", e.msg)
                droid.dialogSetPositiveButtonText("OK")
                droid.dialogShow()
            except:
                droid.dialogCreateAlert("WTF", "WTF?")
                droid.dialogSetPositiveButtonText("OK")
                droid.dialogShow()
        elif id == "exit":
            s.logout()
            sys.exit()
            return
Example #6
0
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"]))
Example #7
0
def mainloop():
	global s
	global chatMgr
	while True:
		event = droid.eventWait().result
		id = event["name"]
		if id == "key" and event["data"]["key"] == "4":
			return
		if id == "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:
						droid.eventPost("loginResult", "success")
						chatMgr = ChatManager(s)
						droid.dialogDismiss()
						return
				except Error as e:
					droid.dialogDismiss()
					droid.eventPost("login", "fail")
					droid.makeToast(e.msg)
				except:
					droid.eventPost("login", "fail")
				finally:
					if s.isConnected:
						droid.dialogDismiss()
					else:
						alertNotLoggedIn(False)
			except:
				droid.dialogDismiss()
				alertNotLoggedIn(False)
		elif id == "requestLoginInfo":
			objectPost("loginInfo", {"user": droid.prefGetValue("user"), "pass": droid.prefGetValue("pass")})
		elif id == "makeToast":
			droid.makeToast(event["data"])
		elif id == "charData":
			droid.dialogCreateSpinnerProgress("Loading", "Loading...")
			droid.dialogShow()
			c = CharpaneRequest(s)
			response = None
			try:
				response = c.doRequest()
			except Error as e:
				alertNotLoggedIn(True)
			message = ""
			title = "Character Data"
			for key in response.keys():
				if key != "effects":
					message += "%s: %s\n" % (key, response[key])
				else:
					message += "-------\nEFFECTS:\n"
					for effect in response["effects"]:
						message += " - " + effect["name"] + ": " + str(effect["turns"]) + "\n"
			droid.dialogDismiss()
			droid.dialogCreateAlert(title, message)
			droid.dialogSetPositiveButtonText("OK")
			droid.dialogShow()
			# objectPost("charDataInfo", response)
		elif id == "inventory":
			droid.dialogCreateSpinnerProgress("Loading", "Loading...")
			droid.dialogShow()
			i = InventoryRequest(s)
			response = None
			try:
				response = i.doRequest()
			except Error as e:
				alertNotLoggedIn(True)
			title = "Inventory"
			message = ""
			for key in response["items"]:
				message += "%s: %s\n" % (key["name"], key["quantity"])
			droid.dialogDismiss()
			droid.dialogCreateAlert(title, message)
			droid.dialogSetPositiveButtonText("OK")
			droid.dialogShow()
			# objectPost("inventoryInfo", response)
		elif id == "findInventory":
			droid.dialogCreateInput("Item to find:", "Enter the name (or partial name) of the item to find")
			droid.dialogSetPositiveButtonText("OK")
			droid.dialogSetNegativeButtonText("Cancel")
			droid.dialogShow()
			response = droid.dialogGetResponse().result
			if response.has_key("which") and response["which"] == "positive" and response.has_key("value") and response["value"] != "":
				droid.dialogCreateSpinnerProgress("Searching...", "Finding items...")
				droid.dialogShow()
				i = InventoryRequest(s)
				inventory = None
				try:
					inventory = i.doRequest()
				except Error as e:
					alertNotLoggedIn(True)
				title = "Search results"
				message = ""
				for item in inventory["items"]:
					if item.has_key("name") and response["value"].lower() in item["name"].lower():
						message += "%s: %s\n" % (item["name"], item["quantity"])
				if message == "":
					message = "No item matching %s was found" % response["value"]
				droid.dialogDismiss()
				droid.dialogCreateAlert(title, message)
				droid.dialogSetPositiveButtonText("OK")
				droid.dialogShow()
		elif id == "getNewChat":
			try:
				objectPost("getNewChatResult", chatMgr.getNewChatMessages())
			except Error as e:
				alertNotLoggedIn(True)
		elif id == "sendChat":
			try:
				data = json.loads(event["data"])
				chatMgr.sendChatMessage("/" + data["channel"] + " " + data["message"])
				droid.eventPost("sendChatResult", "success")
			except Error as e:
				droid.eventPost("sendChatResult", "fail")
		elif id == "getChannels":
			try:
				pass
			except Error as e:
				alertNotLoggedIn(True)
		elif id == "searchMall":
			try:
				m = MallItemSearchRequest(s, event["data"], numResults=10)
				droid.dialogCreateSpinnerProgress("Searching...", "Searching for \"%s\"" % event["data"])
				droid.dialogShow()
				objectPost("searchMallResult", m.doRequest())
				droid.dialogDismiss()
			except Error as e:
				alertNotLoggedIn(True)
		elif id == "buyMall":
			droid.dialogCreateInput("Purchase mall item", "Enter quantity to purchase", "0", "number")
			droid.dialogSetPositiveButtonText("OK")
			droid.dialogSetNegativeButtonText("Cancel")
			droid.dialogShow()
			resp = droid.dialogGetResponse().result
			evtdata = None
			try:
				evtdata = json.loads(event["data"])
				droid.log("evtdata loaded from string")
				droid.log("evtdata = %s" % event["data"])
				buy = MallItemPurchaseRequest(s, evtdata["storeId"], evtdata["id"], evtdata["price"], resp["value"])
				droid.log("MIPR created")
				droid.dialogCreateSpinnerProgress("Buying...", "Buying item(s)...")
				droid.dialogShow()
				buyResponse = buy.doRequest()
				droid.dialogDismiss()
				droid.dialogCreateAlert("Results", "Brought %s for %d" % (resp["value"], buyResponse["meatSpent"]))
				droid.dialogSetPositiveButtonText("OK")
				droid.dialogShow()
			except Error as e:
				droid.dialogCreateAlert("Results", e.msg)
				droid.dialogSetPositiveButtonText("OK")
				droid.dialogShow()
			except:
				droid.dialogCreateAlert("WTF", "WTF?")
				droid.dialogSetPositiveButtonText("OK")
				droid.dialogShow()
		elif id == "exit":
			s.logout()
			sys.exit()
			return