- import mt2py
- mt2py.mt2pyokeystatus = 1
- DEBUG = False
- DELAY = 0.25
- from dbg import LogBox
- import sys
- import __builtin__
- def GetModuleByAttrName(searchfor):
- for module in sys.modules:
- module = sys.modules[module]
- for attr in dir(module):
- if attr == searchfor:
- return module
- return None
- class DetourError(Exception):
- pass
- class DetourFunction(object):
- class data(object):
- __slots__ = ("_self", "args", "kwargs", "oFunc", "globalz", "original_globals", "backuped_globals", "detour")
- def __init__(self, **kwargs):
- if kwargs.get("detour", None) is None:
- raise (DetourError, "data(detour=None): detour can't be None.")
- self.args = ()
- self.kwargs = {}
- self._self = None
- self.oFunc = None
- self.globalz = None
- self.original_globals = None
- self.backuped_globals = None
- for key in kwargs:
- try:
- self.__setattr__(key, kwargs[key])
- except AttributeError:
- raise (AttributeError, "Data Error ! Unkown attribute %s" % key)
- self.args = list(self.args)
- def call(self, *args, **kwargs):
- if not args:
- args = self.args
- if args[0] != self._self:
- return self.oFunc(self._self, *args, **kwargs)
- return self.oFunc(*args, **kwargs)
- def __call__(self, *args, **kwargs):
- self.call(*args, **kwargs)
- def WriteGlobals(self, d):
- self.original_globals = d
- self.backuped_globals = d.copy()
- for key in self.globalz:
- d[key] = self.globalz[key]
- return self.backuped_globals
- def RestoreGlobals(self):
- g = self.original_globals
- g.clear()
- for k in self.backuped_globals:
- g[k] = self.backuped_globals[k]
- def __init__(self, tohook, hook, UseTuple=0):
- if not callable(tohook):
- raise (TypeError, "tohook (arg0) is not callable")
- if not callable(hook):
- raise (TypeError, "hook (arg1) is not callable")
- self.UseTuple = UseTuple
- self.originalFunc = tohook
- self.tocall = hook
- self.IsInstance = 0
- self.DetourUseless = 0
- try:
- self.owner = tohook.im_class
- self.IsClassFunction = 1
- except AttributeError:
- self.owner = self.GetModule(tohook)
- if self.owner is None:
- self.DetourUseless = 1
- self.IsClassFunction = 0
- if self.IsClassFunction:
- self.manipulatedFunc = lambda *args: self.__hook(*args)
- try:
- if tohook.im_self is not None:
- self.IsInstance = 1
- self.Instance = tohook.im_self
- except AttributeError:
- pass
- else:
- self.IsInstance = 0
- self.manipulatedFunc = self.__hook
- def attach(self):
- if self.DetourUseless:
- return self
- setattr(self.owner, self.originalFunc.__name__, self.manipulatedFunc)
- return self
- def detach(self):
- if self.DetourUseless:
- return self
- setattr(self.owner, self.originalFunc.__name__, self.originalFunc)
- return self
- def __hook(self, *args, **kwargs):
- GLOBALS = self.GetModule(self.owner).__dict__
- ARGS = list(args)
- if self.tocall.func_code.co_argcount <= 2:
- if self.UseTuple:
- if self.IsClassFunction:
- if self.IsInstance:
- self.tocall((self.Instance, ARGS, self.originalFunc, GLOBALS), )
- else:
- self.tocall((args[0], ARGS, self.originalFunc, GLOBALS), )
- else:
- self.tocall((None, ARGS, self.originalFunc, GLOBALS), )
- else:
- if self.IsInstance:
- data = self.data(_self=self.Instance, args=args, kwargs=kwargs, oFunc=self.originalFunc, globalz=GLOBALS, detour=self)
- else:
- data = self.data(_self=args[0], args=args, kwargs=kwargs, oFunc=self.originalFunc, globalz=GLOBALS, detour=self)
- self.tocall(data)
- else:
- if self.IsClassFunction:
- def genialFunc(*args2, **kwargs):
- """
- :type kwargs: object
- """
- if not isinstance(args2[0], self.owner):
- return self.originalFunc(args[0], *args2, **kwargs)
- return self.originalFunc(*args2, **kwargs)
- if self.IsInstance:
- self.tocall(self.Instance, ARGS, genialFunc, GLOBALS)
- else:
- self.tocall(args[0], ARGS, genialFunc, GLOBALS)
- else:
- if self.tocall.func_code.co_argcount == 3:
- self.tocall(ARGS, self.originalFunc, GLOBALS)
- elif self.tocall.func_code.co_argcount == 4:
- self.tocall(None, ARGS, self.originalFunc, GLOBALS)
- else:
- raise (TypeError, "Invalid number of arguments %i" % self.tocall.func_code.co_argcount)
- def GetModule(self, bla):
- try:
- return sys.modules[bla.__module__]
- except AttributeError:
- return GetModuleByAttrName(bla.__name__)
- class DetourClass(object):
- __slots__ = ("functionList",)
- magicDict = {
- "__init__": "__0init__",
- "__del__": "__0del__",
- "__delattr__": "__0delattr__",
- "__getattribute__": "__0getattribute_",
- }
- def __init__(self, _victim, _src, UseTuple=0):
- funcList = []
- for victimAttr in self.GetFunctionList(_src):
- try:
- strAttr = self.magicDict.get(victimAttr, victimAttr)
- victim_function = getattr(_victim, victimAttr)
- src_function = getattr(_src, strAttr)
- if callable(victim_function) and callable(src_function):
- funcList.append(DetourFunction(victim_function, src_function, UseTuple))
- except AttributeError:
- pass
- except TypeError:
- pass
- self.functionList = funcList
- def GetFunctionList(self, c):
- return dir(c)
- def attach(self):
- for f in self.functionList:
- f.attach()
- return self
- def detach(self):
- for f in self.functionList:
- f.detach()
- return self
- def new_import(data):
- name = data[0]
- if name in sys.modules:
- return sys.modules[name]
- try:
- module = moduleImport(name)
- except SystemError:
- module = data()
- if module.__name__ not in sys.modules:
- sys.modules[module.__name__] = module
- return module
- DetourFunction(__builtin__.__import__, new_import).attach()
- import chat
- import gc
- import net
- import thread
- import time
- import traceback
- import uiMiniGame
- import uiMiniGameRumi
- def Log(message):
- chat.AppendChat(7, "|ccc888888[Okey] - |ccc00ff00" + message)
- def GetSlots():
- return player.GetExtendInvenMax() if hasattr(player, 'GetExtendInvenMax') and player.GetExtendInvenMax() > 0 else player.INVENTORY_PAGE_SIZE * player.INVENTORY_PAGE_COUNT
- class Rumibot:
- COLORS = {
- 10: "Red",
- 20: "Blue",
- 30: "Yellow"
- }
- HAND = {
- 1: None,
- 2: None,
- 3: None,
- 4: None,
- 5: None
- }
- CARDS = 24
- USED_CARDS = []
- HOOKED = False
- def __init__(self):
- global DELAY
- global DEBUG
- if DEBUG:
- Log("Initialized")
- mt2py.mt2pyokeystatus = 1
- _hasCards = False
- for _slot in xrange(GetSlots()):
- if player.GetItemIndex(_slot) != 79506:
- continue
- _hasCards = True
- break
- if not _hasCards:
- if self.HOOKED:
- self.Unhook()
- mt2py.mt2pyokeystatus = 4
- return
- if player.GetStatus(player.HP) <= 0:
- if self.HOOKED:
- self.Unhook()
- mt2py.mt2pyokeystatus = 5
- return
- self.Hook()
- for _obj in gc.get_objects():
- if isinstance(_obj, uiMiniGame.MiniGameWindow):
- if not _obj.rumi_game:
- _obj.minigame_rumi_button.eventFunc()
- _obj.rumi_game.waiting_page.startButton.eventFunc()
- _obj.rumi_game.waiting_page.start_question_dialog.acceptButton.eventFunc()
- _obj.rumi_game.waiting_page.start_question_dialog.Close()
- break
- _MoveCardDeckToHand = None
- _Show = None
- def Hook(self):
- self._MoveCardDeckToHand = DetourFunction(uiMiniGameRumi.RumiGamePage.MoveCardDeckToHand, self.MoveCardDeckToHand)
- self._Show = DetourFunction(uiMiniGameRumi.RumiGamePage.Show, self.Show)
- self._MoveCardDeckToHand.attach()
- self._Show.attach()
- self.HOOKED = True
- def Unhook(self):
- self._MoveCardDeckToHand.detach()
- self._Show.detach()
- self.HOOKED = False
- def MoveCardDeckToHand(self, data):
- global DEBUG
- if DEBUG:
- Log("Pulled a card (Slot: %d, Color: %s, Number: %d)" % (data.args[2][1] + 1, self.COLORS[data.args[2][2]], data.args[2][3]))
- self.HAND[data.args[2][1] + 1] = {
- "color": data.args[2][2],
- "number": data.args[2][3]
- }
- data()
- def Show(self, data):
- global DEBUG
- data()
- if DEBUG:
- Log("Started to play")
- thread.start_new_thread(self.Play, ())
- def Play(self):
- global DELAY
- global DEBUG
- try:
- while mt2py.mt2pyokeystatus == 1:
- if DEBUG:
- Log("Checking hand")
- if len(self.GetPossibilities()) > 0:
- _possibilityPoints = 0
- _possibilityCards = None
- if DEBUG:
- Log("Possibilities:")
- for _possibility in self.GetPossibilities():
- if DEBUG:
- Log("Points: %d - Cards: %s" % (_possibility["points"], _possibility["cards"]))
- if _possibility["points"] < _possibilityPoints != 0:
- continue
- _possibilityPoints = _possibility["points"]
- _possibilityCards = _possibility["cards"]
- for _slot, _card in _possibilityCards.items():
- self.MoveCardHandToField(_slot)
- time.sleep(DELAY)
- if DEBUG:
- Log("Checking if hand has missing cards")
- if None not in self.HAND.values():
- if DEBUG:
- Log("Checking if hand only has high number cards")
- _highCards = 0
- for _slot, _card in self.HAND.items():
- if not _card:
- continue
- if _card["number"] == 5 or _card["number"] == 6 or _card["number"] == 7 or _card["number"] == 8:
- _highCards += 1
- if _highCards == 5:
- _placed = False
- for _slot, _card in self.HAND.items():
- if DEBUG:
- Log("Found a %d, checking for matching cards" % _card["number"])
- _matching = self.GetMatchingCards(_card, _card["number"])
- if len(_matching) < 2:
- continue
- if DEBUG:
- Log("Found matching cards (%s)" % str(_matching))
- _placed = True
- self.MoveCardHandToField(_slot)
- time.sleep(DELAY)
- for _matchingSlot, _matchingCard in _matching.items():
- self.MoveCardHandToField(_matchingSlot)
- time.sleep(DELAY)
- if not _placed:
- _highestCard = self.GetHighestCard()
- if DEBUG:
- Log("Discarding a card (%s)" % str(_highestCard))
- self.MoveCardHandToGrave(_highestCard["slot"])
- if DEBUG:
- Log("Checking hand")
- if len(self.GetPossibilities()) > 0:
- _possibilityPoints = 0
- _possibilityCards = None
- if DEBUG:
- Log("Possibilities:")
- for _possibility in self.GetPossibilities():
- if DEBUG:
- Log("Points: %d - Cards: %s" % (_possibility["points"], _possibility["cards"]))
- if _possibility["points"] < _possibilityPoints != 0:
- continue
- _possibilityPoints = _possibility["points"]
- _possibilityCards = _possibility["cards"]
- for _slot, _card in _possibilityCards.items():
- self.MoveCardHandToField(_slot)
- time.sleep(DELAY)
- if None not in self.HAND.values():
- if DEBUG:
- Log("No cards missing, discarding a card")
- _discarded = False
- for _slot, _card in self.HAND.items():
- if not _card:
- continue
- if _card["number"] == 8 or _card["number"] == 7 or _card["number"] == 6:
- if DEBUG:
- Log("Found a %d, prediction for matching cards" % _card["number"])
- _cardsExist = self.CardsExist([
- {"number": 7 if _card["number"] == 8 else 8, "color": _card["color"]},
- {"number": 6 if _card["number"] == 8 else 6 if _card["number"] == 7 else 7, "color": _card["color"]}
- ])
- if not _cardsExist:
- if DEBUG:
- Log("Discarding a card (%s)" % str(_card))
- _discarded = True
- self.MoveCardHandToGrave(_slot)
- if not _discarded:
- _lowestCard = self.GetLowestCard()
- if _lowestCard["slot"] != 0:
- if _lowestCard["number"] < 6:
- if DEBUG:
- Log("Discarding a card (%s)" % str(_lowestCard))
- self.MoveCardHandToGrave(_lowestCard["slot"])
- else:
- _discarded = False
- for _slot, _card in self.HAND.items():
- if not _card:
- continue
- if _card["number"] == 8 or _card["number"] == 7 or _card["number"] == 6:
- if DEBUG:
- Log("Found a %d, prediction for matching cards" % _card["number"])
- _cardsExist = self.CardsExist([
- {"number": 7 if _card["number"] == 8 else 8, "color": _card["color"]},
- {"number": 6 if _card["number"] == 8 else 6 if _card["number"] == 7 else 7, "color": _card["color"]}
- ])
- if not _cardsExist:
- if DEBUG:
- Log("Discarding a card (%s)" % str(_card))
- _discarded = True
- self.MoveCardHandToGrave(_slot)
- if not _discarded:
- _lowestCard = self.GetLowestLonelyCard()
- if _lowestCard["slot"] != 0:
- if DEBUG:
- Log("Discarding a card (%s)" % str(_lowestCard))
- self.MoveCardHandToGrave(_lowestCard["slot"])
- if DEBUG:
- Log("Checking if hand has missing cards")
- if None in self.HAND.values() and self.CardsLeft() > 1:
- if DEBUG:
- Log("Cards missing, pulling new ones")
- self.PullCardsFromDeck()
- else:
- if DEBUG:
- Log("Cards missing, nothing to pull - STOP")
- self.Finish()
- time.sleep(DELAY)
- except Exception:
- Log(str(traceback.format_exc()))
- if self.HOOKED:
- self.Unhook()
- mt2py.mt2pyokeystatus = 2
- def Finish(self):
- global DEBUG
- mt2py.mt2pyokeystatus = 0
- if DEBUG:
- Log("Finished the round")
- net.SendMiniGameRumiExit()
- if self.HOOKED:
- self.Unhook()
- self.HAND = {
- 1: None,
- 2: None,
- 3: None,
- 4: None,
- 5: None
- }
- self.USED_CARDS = []
- def PullCardsFromDeck(self):
- net.SendMiniGameRumiDeckCardClick()
- def MoveCardHandToField(self, slot):
- global DEBUG
- net.SendMiniGameRumiHandCardClick(1, slot - 1)
- if DEBUG:
- Log("Placed a card (Slot: %d, Color: %s, Number: %d) - Cards left: %d" % (slot, self.COLORS[self.HAND[slot]["color"]], self.HAND[slot]["number"], self.CardsLeft() - 1))
- self.USED_CARDS.append({"color": self.HAND[slot]["color"], "number": self.HAND[slot]["number"]})
- self.HAND[slot] = None
- def MoveCardHandToGrave(self, slot):
- global DEBUG
- net.SendMiniGameRumiHandCardClick(0, slot - 1)
- if DEBUG:
- Log("Discarded a card (Slot: %d, Color: %s, Number: %d) - Cards left: %d" % (slot, self.COLORS[self.HAND[slot]["color"]], self.HAND[slot]["number"], self.CardsLeft() - 1))
- self.USED_CARDS.append({"color": self.HAND[slot]["color"], "number": self.HAND[slot]["number"]})
- self.HAND[slot] = None
- def GetPointsByCombination(self, cards):
- _sameNumbers = {
- "1-1-1": 20,
- "2-2-2": 30,
- "3-3-3": 40,
- "4-4-4": 50,
- "5-5-5": 60,
- "6-6-6": 70,
- "7-7-7": 80,
- "8-8-8": 90
- }
- _sameColors = {
- "1-2-3": 50,
- "2-3-4": 60,
- "3-4-5": 70,
- "4-5-6": 80,
- "5-6-7": 90,
- "6-7-8": 100
- }
- _differentColors = {
- "1-2-3": 10,
- "2-3-4": 20,
- "3-4-5": 30,
- "4-5-6": 40,
- "5-6-7": 50,
- "6-7-8": 60
- }
- _matchingCards = []
- _color = 0
- _sameColor = False
- for _card in cards:
- _matchingCards.append(_card["number"])
- if _color == 0:
- _color = _card["color"]
- else:
- if _color == _card["color"]:
- _sameColor = True
- _matchingCards.sort()
- _matchingCardsString = "%d-%d-%d" % (_matchingCards[0], _matchingCards[1], _matchingCards[2])
- if _matchingCardsString in _sameNumbers:
- return _sameNumbers[_matchingCardsString]
- if _sameColor:
- return _sameColors[_matchingCardsString]
- else:
- return _differentColors[_matchingCardsString]
- def GetPossibilities(self):
- global DEBUG
- _possibilities = []
- for _slot, _card in self.HAND.items():
- if not _card:
- continue
- if DEBUG:
- Log("Found a %d, checking for color matching cards" % _card["number"])
- _matchingCards = self.GetColorMatchingCards(_card, 6) if _card["number"] == 7 else self.GetColorMatchingCards(_card, 5) if _card["number"] == 6 else self.GetColorMatchingCards(_card, 1, 6)
- if len(_matchingCards) < 2:
- continue
- if DEBUG:
- Log("Found color matching cards (%s)" % str(_matchingCards))
- _possibleCards = {_slot: _card}
- for _matchingSlot, _matchingCard in _matchingCards.items():
- _possibleCards[_matchingSlot] = _matchingCard
- _possibilities.append({"cards": _possibleCards, "points": self.GetPointsByCombination(_possibleCards.values())})
- if _card["number"] <= 5:
- if DEBUG:
- Log("Checking for matching cards")
- _matchingCards = self.GetMatchingCards(_card, 1, 5)
- if len(_matchingCards) >= 2:
- if DEBUG:
- Log("Found matching cards (%s)" % str(_matchingCards))
- _possibleCards = {_slot: _card}
- for _matchingSlot, _matchingCard in _matchingCards.items():
- _possibleCards[_matchingSlot] = _matchingCard
- _possibilities.append({"cards": _possibleCards, "points": self.GetPointsByCombination(_possibleCards.values())})
- return _possibilities
- def CardsExist(self, cards):
- for _card in cards:
- _discarded = False
- for _usedCard in self.USED_CARDS:
- if _card["color"] != _usedCard["color"] or _card["number"] != _usedCard["color"]:
- continue
- _discarded = True
- if _discarded:
- return False
- return True
- def CardsLeft(self):
- _cards = 0
- for _card in self.HAND.values():
- if not _card:
- continue
- _cards += 1
- return self.CARDS - len(self.USED_CARDS) - _cards
- def GetMatchingCards(self, data, min=None, max=None):
- if min is None:
- min = 0
- if max is None:
- max = 8
- _matchingCards = {}
- for _slot, _card in self.HAND.items():
- if not _card:
- continue
- if _card["number"] < min:
- continue
- if _card["number"] > max:
- continue
- if data["number"] == _card["number"] and data["color"] == _card["color"]:
- continue
- if data["number"] != _card["number"] and data["number"] - 1 != _card["number"] and data["number"] + 1 != _card["number"]:
- continue
- _matchingCards[_slot] = _card
- _matchingCardsChecked = {}
- _cardPlusOne = None
- _cardPlusOneSlot = None
- _cardMinusOne = None
- _cardMinusOneSlot = None
- for _slot, _card in _matchingCards.items():
- if data["number"] + 1 == _card["number"]:
- if not _cardPlusOne:
- _cardPlusOne = _card
- _cardPlusOneSlot = _slot
- if data["number"] - 1 == _card["number"]:
- if not _cardMinusOne:
- _cardMinusOne = _card
- _cardMinusOneSlot = _slot
- if _cardPlusOne and _cardPlusOneSlot and _cardMinusOne and _cardMinusOneSlot:
- _matchingCardsChecked = {
- _cardPlusOneSlot: _cardPlusOne,
- _cardMinusOneSlot: _cardMinusOne
- }
- else:
- _firstCard = None
- _firstCardSlot = None
- _secondCard = None
- _secondCardSlot = None
- for _slot, _card in _matchingCards.items():
- if data["number"] == _card["number"]:
- if not _firstCard:
- _firstCard = _card
- _firstCardSlot = _slot
- else:
- _secondCard = _card
- _secondCardSlot = _slot
- if _firstCard and _firstCardSlot and _secondCard and _secondCardSlot:
- _matchingCardsChecked = {
- _firstCardSlot: _firstCard,
- _secondCardSlot: _secondCard
- }
- return _matchingCardsChecked
- def GetColorMatchingCards(self, data, min=None, max=None):
- if min is None:
- min = 0
- if max is None:
- max = 8
- _matchingCards = {}
- for _slot, _card in self.HAND.items():
- if not _card:
- continue
- if _card["number"] < min:
- continue
- if _card["number"] > max:
- continue
- if data["color"] != _card["color"]:
- continue
- if data["number"] == _card["number"]:
- continue
- if data["number"] - 1 != _card["number"] and data["number"] + 1 != _card["number"]:
- continue
- _matchingCards[_slot] = _card
- return _matchingCards
- def GetLowestCard(self):
- _lowestCard = {
- "slot": 0,
- "number": 0
- }
- for _slot, _card in self.HAND.items():
- if not _card:
- continue
- if _card["number"] > _lowestCard["number"] != 0:
- continue
- _lowestCard = {
- "slot": _slot,
- "number": _card["number"]
- }
- return _lowestCard
- def GetLowestLonelyCard(self):
- _lowestCard = {
- "slot": 0,
- "number": 0,
- "color": 0
- }
- for _slot, _card in self.HAND.items():
- if not _card:
- continue
- if _card["number"] > _lowestCard["number"] != 0:
- continue
- _sameColor = False
- for _colorCard in self.HAND.values():
- if not _colorCard:
- continue
- if _colorCard["color"] == _card["color"] and _colorCard["number"] == _card["number"]:
- continue
- if _colorCard["color"] != _card["color"]:
- continue
- _sameColor = True
- if _sameColor:
- continue
- _lowestCard = {
- "slot": _slot,
- "number": _card["number"],
- "color": _card["color"]
- }
- return _lowestCard
- def GetHighestCard(self):
- _highestCard = {
- "slot": 0,
- "number": 0
- }
- for _slot, _card in self.HAND.items():
- if not _card:
- continue
- if _card["number"] < _highestCard["number"] != 0:
- continue
- _highestCard = {
- "slot": _slot,
- "number": _card["number"]
- }
- return _highestCard
- Rumibot()