示例#1
0
 def notesflush(self):
     dprint("notes flush")
     fd = open("./mapper/notes", "w")
     for note in self.notes:
         line = "%s\x19%s\x19%s" % (note[0], note[1], note[2])
         fd.write("%s\n" % line)
     fd.close()
示例#2
0
 def notesflush(self):
     dprint('notes flush')
     fd = open('./mapper/notes', 'w')
     for note in self.notes:
         line = '%s\x19%s\x19%s' % (note[0], note[1], note[2])
         fd.write('%s\n' % line)
     fd.close()
示例#3
0
 def connect(self):
     self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     self.sock.connect((self.host, self.port))
     self.sock.send(b'\x1bbc 1\n')
     self.xsock[0] = self.sock
     self.connected = True
     dprint('CONNECTED', self, self.sock)
示例#4
0
    def createchannel(self, chgrpwidget, channels, title):
        """Create channel in specified channel group.
        """
        tabwidget = chgrpwidget.qtabwidget
        css = self.parent.styleSheet()
        qconsole = QConsoleWindow(tabwidget.getTabParent(), css)
        qconsole.hide()
        qconsole.setupdowncallback(self.updowncallback)
        qconsole.setcommandchangedcallback(self.commandchangedcallback)

        def __close():
            tabwidget.removeWidget(qconsole)

        menu = QtGui.QMenu(self.parent)
        if '$all' not in channels and '$battle' not in channels:
            a1 = QtGui.QAction('Close', self.parent)
            a1.triggered.connect(__close)
            menu.addAction(a1)

        tabwidget.addTab(qconsole, title, menu)
        qconsole.show()

        qconsole.chanlist = channels

        # check if single input
        if len(channels) < 2:
            # check if channel only
            if channels[0][0] == '#':
                builtin = (
                    'bat', 'bs', 'd3', 'ghost', 'ifin', 'lfp',
                    'newbie', 'race', 'suomi', 'battlebot',
                    'chat', 'eso', 'hockey', 'imud', 'magical',
                    'sports', 'tunes', 'boardgaming', 'client',
                    'football', 'houses', 'infalert', 'mudcon',
                    'politics', 'sales', 'stream', 'wanted'
                )
                # this actually became annoying..
                #if channels[0][1:] in builtin:
                #    qconsole.setcommandprefix('%s ' % (channels[0][1:]))
                #else:
                #    qconsole.setcommandprefix('%s say ' % (channels[0][1:]))
            if channels[0][0] == '!':
                # add prefix for talking over tells to player
                qconsole.setcommandprefix('tell %s ' % (channels[0][1:]))
            if channels[0] == '$readme':
                if os.path.exists('README'):
                    readme = 'README'
                if os.path.exists('./client/README'):
                    readme = './client/README'
                fd = open(readme, 'r')
                dprint('readme', 'rb')
                lines = fd.readlines()
                for line in lines:
                    line = bytes(line, 'utf8').strip(b'\r\n').replace(b'\\x1b', b'\x1b')
                    self.addlinetoconsole(qconsole, line)
                fd.close()

        qconsole.commandEvent = self.commandEvent
        qconsole.show()
        return qconsole
示例#5
0
    def event_lineunknown(self, event, line):
        #l:b'A little bunny is such a sweet sight, fluffy like a ball of cotton and as'
        #l:b'white too. You cannot help but adore this tiny cute animal.'
        #l:b'He is in excellent shape.'
        #l:b'He looks hungry.'
        if self.look_intercept:
            # He looks
            # She looks
            # It looks
            x = line.find(b'looks')
            if x < 6 and x > -1:
                # ignore this line
                return True
            if line.endswith(b'shape.'):
                tmp = ' '.join(self.tmp)
                phrase = self.pendinglooks.pop(0)
                self.game.pushevent(
                    'lineunknown', b'\x1b#99ff99mAdded looks of [' +
                    bytes(phrase, 'utf8') + b'] to MOB-LORE.')
                self.moblore['looks'][phrase] = tmp
                self.dumplore()
                self.look_intercept = False
                self.do_nextlook()
                return True
            self.tmp.append(line.decode('utf8'))
            return True

        #l:b'That is not possible.'
        if line.find(
                b'That is not possible.') == 0 and self.consider_intercept:
            self.consider_intercept = False
            # do nothing because it was invalid
            entry = self.pendingconsiders.pop(0)
            self.do_nextconsider()
            return True

        # At the moment these are useless
        #l:b'You make a small puddle on the floor.'
        #if line.find(b'You make a small puddle on the floor.') == 0 and self.consider_intercept:
        #    return True
        #l:b"Not a valid adverb, 'blurred'."
        #if line.find(b'Not a valid adverb, ') == 0 and self.consider_intercept:
        #    return True

        #l:b'\x1b[1;32msix spotted ladybird\x1b[0m'
        if line.find(b'\x1b[1;32m') == 0 and line.count(
                b'\x1b') == 2 and line.find(b':') < 0:
            mob = line[line.find(b'm') + 1:line.rfind(b'\x1b')].decode(
                'utf8', 'ignore')
            mob = mob.replace(',', '')
            if mob.find(' is') > -1:
                mob = mob[0:mob.find(' is')].strip()
            if mob.startswith('a '):
                mob = mob[2:]
            if mob.startswith('A '):
                mob = mob[2:]
            dprint('mob:%s' % mob)
            self.game.pushevent('mobdetected', mob)
示例#6
0
 def do_nextconsider(self):
     if not self.consider_intercept:
         if len(self.pendingconsiders) < 1:
             # unlock command group and exit since
             # we have finished doing our considers
             self.do_nextlook()
             return  
         phrase = self.pendingconsiders[0][0]
         self.consider_intercept = True
         dprint('considering `%s`' % phrase)
         self.game.command('consider %s' % phrase, self)
示例#7
0
 def do_nextconsider(self):
     if not self.consider_intercept:
         if len(self.pendingconsiders) < 1:
             # unlock command group and exit since
             # we have finished doing our considers
             self.do_nextlook()
             return
         phrase = self.pendingconsiders[0][0]
         self.consider_intercept = True
         dprint('considering `%s`' % phrase)
         self.game.command('consider %s' % phrase, self)
示例#8
0
    def event_lineunknown(self, event, line):
        #l:b'A little bunny is such a sweet sight, fluffy like a ball of cotton and as'
        #l:b'white too. You cannot help but adore this tiny cute animal.'
        #l:b'He is in excellent shape.'
        #l:b'He looks hungry.'
        if self.look_intercept:
            # He looks
            # She looks
            # It looks
            x = line.find(b'looks')
            if x < 6 and x > -1:
                # ignore this line
                return True
            if line.endswith(b'shape.'):
                tmp = ' '.join(self.tmp)
                phrase = self.pendinglooks.pop(0)
                self.game.pushevent('lineunknown', b'\x1b#99ff99mAdded looks of [' + bytes(phrase, 'utf8') + b'] to MOB-LORE.')
                self.moblore['looks'][phrase] = tmp
                self.dumplore()
                self.look_intercept = False
                self.do_nextlook()
                return True
            self.tmp.append(line.decode('utf8'))
            return True


        #l:b'That is not possible.'
        if line.find(b'That is not possible.') == 0 and self.consider_intercept:
            self.consider_intercept = False
            # do nothing because it was invalid
            entry = self.pendingconsiders.pop(0)
            self.do_nextconsider()
            return True

        # At the moment these are useless 
        #l:b'You make a small puddle on the floor.'
        #if line.find(b'You make a small puddle on the floor.') == 0 and self.consider_intercept:
        #    return True
        #l:b"Not a valid adverb, 'blurred'."
        #if line.find(b'Not a valid adverb, ') == 0 and self.consider_intercept:
        #    return True

        #l:b'\x1b[1;32msix spotted ladybird\x1b[0m'
        if line.find(b'\x1b[1;32m') == 0 and line.count(b'\x1b') == 2 and line.find(b':') < 0:
            mob = line[line.find(b'm') + 1:line.rfind(b'\x1b')].decode('utf8', 'ignore')
            mob = mob.replace(',', '')
            if mob.find(' is') > -1:
                mob = mob[0:mob.find(' is')].strip()
            if mob.startswith('a '):
                mob = mob[2:]
            if mob.startswith('A '):
                mob = mob[2:]
            dprint('mob:%s' % mob)
            self.game.pushevent('mobdetected', mob)
示例#9
0
    def command(self, command, group="default"):
        if type(command) is str:
            command = bytes(command, "utf8")

        if self.cmdgrouplock is not None and group != self.cmdgrouplock:
            self.cmdpending.append(command)
            self.pushevent("lineunknown", b"\x1b#ff9999mThe command `" + command + b"` is pending!")
            return

        dprint("command", command)
        self.c.writeline(command)
示例#10
0
文件: game.py 项目: mark3982/pybatmud
    def command(self, command, group='default'):
        if type(command) is str:
            command = bytes(command, 'utf8')

        if self.cmdgrouplock is not None and group != self.cmdgrouplock:
            self.cmdpending.append(command)
            self.pushevent(
                'lineunknown',
                b'\x1b#ff9999mThe command `' + command + b'` is pending!')
            return

        dprint('command', command)
        self.c.writeline(command)
示例#11
0
 def commandEvent(self, line):
     """When the command input on any channel window changes.
     """
     # set history line, only if not a movement command
     if line not in {'n', 's', 'w', 'e', 'nw', 'ne', 'sw', 'se'}:
         self.chistory[-1] = line
         # make new history line
         self.chistory.append('')
     res = self.game.pushevent('command', line)
     if res is True or (type(res) == tuple and res[0] is True):
         dprint('dropped command')
         # the command was intercepted, processed, and the handler
         # has requested that we drop the command and not forward
         # it to the game
         return
     self.game.command(line)
示例#12
0
    def update(self):
        if len(self.spells) < 1:
            return
        self.resize(self.width(), len(self.spells) * 30)
        hpe = self.height() / len(self.spells)

        ct = time.time()

        cy = 0
        for who in self.spells:
            toremove = []
            for spellname in self.spells[who]:
                spell = self.spells[who][spellname]
                w = spell[0]
                l = spell[1]
                c = spell[2]
                m = spell[3]
                st = spell[4]

                # get current tick in real time (counting seconds per #)
                cc = c - (ct - st) * 0.35

                if cc < 0 or m <= 0:
                    toremove.append(spellname)
                    continue

                width = (cc / m) * self.width()

                w.move(0, cy)
                w.resize(width, hpe)
                l.move(0, cy)
                l.resize(self.width(), hpe)
                l.setText('%s (%.01f)' % (spellname.replace('_', ' '), cc))
                l.raise_()
                cy = cy + hpe
            for r in toremove:
                spell = self.spells[who][r]
                w = spell[0]
                l = spell[1]
                l.hide()
                l.setParent(None)
                w.hide()
                w.setParent(None)
                del self.spells[who][r]
                dprint('removed spell', r)
示例#13
0
    def do_nextlook(self):
        if len(self.pendinglooks) < 1:
            self.game.unlockcmdgroup(self)
            return

        # only look at things we have never looked at before
        while True:
            if len(self.pendinglooks) < 1:
                self.game.unlockcmdgroup(self)
                return
            phrase = self.pendinglooks[0]
            if phrase in self.moblore['looks']:
                dprint('[%s] already in looks' % phrase)
                self.pendinglooks.pop(0)
                continue
            break

        self.look_intercept = True
        self.tmp = []
        self.game.command('look %s' % phrase, self)
示例#14
0
    def do_nextlook(self):
        if len(self.pendinglooks) < 1:
            self.game.unlockcmdgroup(self)
            return

        # only look at things we have never looked at before
        while True:
            if len(self.pendinglooks) < 1:
                self.game.unlockcmdgroup(self)
                return
            phrase = self.pendinglooks[0]
            if phrase in self.moblore['looks']:
                dprint('[%s] already in looks' % phrase)
                self.pendinglooks.pop(0)
                continue
            break

        self.look_intercept = True
        self.tmp = []
        self.game.command('look %s' % phrase, self)
示例#15
0
    def event_blockunknown(self, event, block):
        #b:b'\x1b<10spec_skill\x1b|The final estimation is that Caretaker of the Temple can easily reduce you to\r\nminced meat, so run for your life.\r\n\x1b>10'
        #b:b'\x1b<10spec_skill\x1b|The final estimation is that Monarch butterfly looks quite skilled, beware.\r\n\x1b>10'
        #b:b"\x1b<10spec_skill\x1b|The final estimation is that Warthog's power overwhelms your mind! You PANIC!!\r\n\x1b>10"
        if block.find(
                b'\x1b<10spec_skill\x1b|The final estimation is that') == 0:
            i = block.find(b'that') + 5
            x = findmulti(block, (b'can', b'looks', b'power', b'and', b'has'),
                          i)
            mob_basename = block[i:x].strip()
            desc = block[x:]

            if mob_basename.endswith(b'\'s'):
                mob_basename = mob_basename[0:-2]

            mob_basename = mob_basename.decode('utf8')
            desc = desc.decode('utf8')
            if desc.find('\r') > -1:
                desc = desc[0:desc.find('\r')].strip()

            print('mob_basename:[%s] desc:[%s]' % (mob_basename, desc))

            if self.consider_intercept:
                entry = self.pendingconsiders.pop(0)
                self.moblore['descnametoname'][entry[1]] = mob_basename
            else:
                entry = None

            mylevel = self.playerlevel

            # if we do not have our level then the consideration
            # can be quite meaningless really... right?
            if mylevel > -1:
                if mylevel not in self.moblore['consider-base']:
                    self.moblore['consider-base'][mylevel] = {}
                if mylevel not in self.moblore['consider-full']:
                    self.moblore['consider-full'][mylevel] = {}
                self.moblore['consider-base'][mylevel][mob_basename] = desc
                if entry is not None:
                    self.moblore['consider-full'][mylevel][entry[1]] = desc
                self.game.pushevent(
                    'lineunknown', b'\x1b#99ff99mAdded level of [' +
                    bytes(mob_basename, 'utf8') + b'] to MOB-LORE.')
                self.dumplore()

            if self.consider_intercept:
                self.consider_intercept = False
                # remove everything else to keep from just wasting
                # bandwidth and time trying them when we have already
                # found the correct one
                _pendingconsiders = []
                for p in self.pendingconsiders:
                    if p[1] != entry[1]:
                        _pendingconsiders.append(p)
                self.pendingconsiders = _pendingconsiders

                self.pendinglooks.append(mob_basename)
                self.do_nextconsider()
                return True
            else:
                # take a quick look at the mob
                dprint('doing quick look at [%s]' % mob_basename)
                self.game.lockcmdgroup(self)
                self.pendinglooks.append(mob_basename)
                self.do_nextlook()
        elif block.find(b'\x1b<10spec_skill') == 0 and self.consider_intercept:
            # drop it
            return True
示例#16
0
    def event_batmapper(self, event, thiszone, xid, lastmove, desc, moves):

        dprint('thiszone', thiszone)
        dprint('thisroom', xid)
        dprint('lastmove', lastmove)
        dprint('desc', desc[0:10].replace('\n', '').replace('\r', ''))
        dprint('moves', moves)

        _moves = moves.split(',')
        moves = set()
        mi = {
            'n': 's',
            's': 'n',
            'e': 'w',
            'w': 'e',
            'u': 'd',
            'd': 'u',
            'nw': 'se',
            'ne': 'sw',
            'sw': 'ne',
            'se': 'nw',
        }
        m = {
            'north': 'n',
            'northeast': 'ne',
            'east': 'e',
            'southeast': 'se',
            'south': 's',
            'southwest': 'sw',
            'west': 'w',
            'northwest': 'nw',
            'up': 'u',
            'down': 'd'
        }
        for move in _moves:
            if move in m:
                moves.add(m[move])
            else:
                moves.add(move)

        # normalize it
        if lastmove in m:
            lastmove = m[lastmove]
            lastmoveinvert = mi[lastmove]
        else:
            lastmoveinvert = None

        if thiszone not in self.batmap:
            self.batmap[thiszone] = {}
        zone = self.batmap[thiszone]

        if xid not in zone:
            zone[xid] = {}
            zone[xid]['forward'] = set()
            zone[xid]['backward'] = set()
            zone[xid]['desc'] = None
            zone[xid]['moves'] = None
            zone[xid]['entered'] = set()
            zone[xid]['exited'] = set()
            zone[xid]['seenmobs'] = set()

        if self.lastbatmapper is not None:
            lastzone = self.lastbatmapper[0]
            lastxid = self.lastbatmapper[1]
            if lastzone == thiszone:
                # add backward link
                dprint('lastmoveinvert:%s lastmove:%s' %
                       (lastmoveinvert, lastmove))
                zone[xid]['backward'].add(
                    ((lastzone, lastxid), lastmoveinvert))
                # add forward link
                zone[lastxid]['forward'].add(((thiszone, xid), lastmove))
            else:
                # mark we entered here
                zone[xid]['entered'].add(lastzone)
                zone[xid]['backward'].add(
                    ((lastzone, lastxid), lastmoveinvert))
                # mark we exited here
                self.batmap[lastzone][lastxid]['exited'].add(thiszone)
                self.batmap[lastzone][lastxid]['forward'].add(
                    ((thiszone, xid), lastmove))
        else:
            if self.wasoutside is True:
                # we came from the world
                zone[xid]['entered'].add('world')

        if zone[xid]['desc'] is not None and zone[xid]['desc'] != desc:
            # well.. we must be in a maze.. or something crazy
            self.game.pushevent(
                'lineunknown',
                b'\x1b#ff9999mwarning: \x1b#ffffffmmapper plugin detected possible maze!'
            )

        zone[xid]['desc'] = desc
        zone[xid]['moves'] = moves

        dprint('added entry zone:%s xid:%s moves:%s' % (thiszone, xid, moves))

        self.wasoutside = False
        self.lastbatmapper = (thiszone, xid, lastmove, desc, moves)

        self.batmapflush()

        self.update()
示例#17
0
    def event_batmapper(self, event, thiszone, xid, lastmove, desc, moves):

        dprint("thiszone", thiszone)
        dprint("thisroom", xid)
        dprint("lastmove", lastmove)
        dprint("desc", desc[0:10].replace("\n", "").replace("\r", ""))
        dprint("moves", moves)

        _moves = moves.split(",")
        moves = set()
        mi = {
            "n": "s",
            "s": "n",
            "e": "w",
            "w": "e",
            "u": "d",
            "d": "u",
            "nw": "se",
            "ne": "sw",
            "sw": "ne",
            "se": "nw",
        }
        m = {
            "north": "n",
            "northeast": "ne",
            "east": "e",
            "southeast": "se",
            "south": "s",
            "southwest": "sw",
            "west": "w",
            "northwest": "nw",
            "up": "u",
            "down": "d",
        }
        for move in _moves:
            if move in m:
                moves.add(m[move])
            else:
                moves.add(move)

        # normalize it
        if lastmove in m:
            lastmove = m[lastmove]
            lastmoveinvert = mi[lastmove]
        else:
            lastmoveinvert = None

        if thiszone not in self.batmap:
            self.batmap[thiszone] = {}
        zone = self.batmap[thiszone]

        if xid not in zone:
            zone[xid] = {}
            zone[xid]["forward"] = set()
            zone[xid]["backward"] = set()
            zone[xid]["desc"] = None
            zone[xid]["moves"] = None
            zone[xid]["entered"] = set()
            zone[xid]["exited"] = set()
            zone[xid]["seenmobs"] = set()

        if self.lastbatmapper is not None:
            lastzone = self.lastbatmapper[0]
            lastxid = self.lastbatmapper[1]
            if lastzone == thiszone:
                # add backward link
                dprint("lastmoveinvert:%s lastmove:%s" % (lastmoveinvert, lastmove))
                zone[xid]["backward"].add(((lastzone, lastxid), lastmoveinvert))
                # add forward link
                zone[lastxid]["forward"].add(((thiszone, xid), lastmove))
            else:
                # mark we entered here
                zone[xid]["entered"].add(lastzone)
                zone[xid]["backward"].add(((lastzone, lastxid), lastmoveinvert))
                # mark we exited here
                self.batmap[lastzone][lastxid]["exited"].add(thiszone)
                self.batmap[lastzone][lastxid]["forward"].add(((thiszone, xid), lastmove))
        else:
            if self.wasoutside is True:
                # we came from the world
                zone[xid]["entered"].add("world")

        if zone[xid]["desc"] is not None and zone[xid]["desc"] != desc:
            # well.. we must be in a maze.. or something crazy
            self.game.pushevent(
                "lineunknown", b"\x1b#ff9999mwarning: \x1b#ffffffmmapper plugin detected possible maze!"
            )

        zone[xid]["desc"] = desc
        zone[xid]["moves"] = moves

        dprint("added entry zone:%s xid:%s moves:%s" % (thiszone, xid, moves))

        self.wasoutside = False
        self.lastbatmapper = (thiszone, xid, lastmove, desc, moves)

        self.batmapflush()

        self.update()
示例#18
0
    def findpath(self, goalcheck, usegg=True):
        """This will find all paths that satisfy the goal check function provided.

        This will find all paths that satisfy the goal check function provided.

        goalcheck    - shall be a function taking the appropriate arguments
        usegg        - uses geometric grid to determine if rooms have been visited
        """
        if self.lastbatmapper is None:
            self.game.pushevent("lineunknown", b"mapper: not inside zone - assuming your in the world (try moving)!")
            return []
        thiszone = self.lastbatmapper[0]
        zone = self.batmap[thiszone]
        thisxid = self.lastbatmapper[1]
        goal = []
        visited = set()
        gg = set()
        gg = {}
        gg[(0, 0, 0)] = (thiszone, thisxid)
        bugs = []
        bugs.append((thiszone, thisxid, [(thiszone, thisxid, "start")], 0, 0, 0))
        amap = self.amap
        if goalcheck is not None:
            res = goalcheck(thiszone, thisxid, gg, (0, 0, 0))
            if res is not False and res is not None:
                goal.append(([(thiszone, thisxid, "start")], res))
        visited.add((thiszone, thisxid))
        while len(bugs) > 0:
            _bugs = []
            # iterate through parents letting them create child bugs
            for thiszone, thisxid, history, tx, ty, tz in bugs:
                zone = self.batmap[thiszone]
                room = zone[thisxid]
                forward = room["forward"]
                backward = room["backward"]
                _combined = set()
                for action in forward:
                    _combined.add(action)
                for action in backward:
                    _combined.add(action)

                for action in _combined:
                    tozone, toxid = action[0]
                    if (tozone, toxid) in visited:
                        # if we been here before dont go back to it
                        continue
                    tomove = action[1]
                    # create new child bug that inherits parent history
                    nhistory = history + [(tozone, toxid, tomove)]
                    if tx is not None and tomove in amap:
                        ggoff = amap[tomove]
                        cx = tx + ggoff[0]
                        cy = ty + ggoff[1]
                        cz = tz + ggoff[2]
                        if (cx, cy, cz) in gg:
                            # it seems most dungeons do not have a straight forward
                            # geometric grid representation for vertical layers which
                            # means this fails to eliminate all visited rooms.. so we
                            # just have to be aware of it
                            pass
                        gg[(cx, cy, cz)] = (tozone, toxid)
                    else:
                        cx = None
                        cy = None
                        cz = None
                        dprint("LOST GEO GRID with %s:%s" % (tx, tomove))

                    _bugs.append((tozone, toxid, nhistory, cx, cy, cz))
                    if goalcheck is not None:
                        res = goalcheck(tozone, toxid, gg, (cx, cy, cz))
                        if res is not False and res is not None:
                            goal.append((nhistory, res))
                    visited.add((tozone, toxid))
            # parent die and children become parents
            bugs = _bugs
        self.game.pushevent(
            "lineunknown", bytes("  Searched %s/%s/%s Rooms" % (len(visited), len(zone), len(gg)), "utf8")
        )
        # should have zero or more goals
        if goalcheck is None:
            return gg
        else:
            return goal
示例#19
0
    def event_command(self, event, command):
        parts = command.split(" ")

        if len(parts) > 0 and parts[0] == "mapper":
            if len(parts) > 1 and parts[1] == "totals":
                zonecount = 0
                roomcount = 0
                for zone in self.batmap:
                    zonecount += 1
                    for room in zone:
                        roomcount += 1
                self.game.pushevent(
                    "lineunknown",
                    bytes("\x1b#ffffffmapper: tracking %s zones and %s rooms!" % (zonecount, roomcount), "utf8"),
                )
            if len(parts) > 1 and parts[1] == "addnote":
                note = " ".join(parts[2:])
                if self.lastbatmapper is None:
                    if self.lastcord is not None:
                        cx = self.lastcord[0]
                        cy = self.lastcord[1]
                        self.notes.append([cx, cy, note, None])
                        self.notesflush()
                        # specify to drop propagation of event and not to forward command
                        self.game.pushevent("lineunknown", b"mapper: added note to world")
                        return (True, True)
                else:
                    zonename = self.lastbatmapper[0]
                    roomname = self.lastbatmapper[1]
                    room = self.batmap[zonename][roomname]
                    if "notes" not in room:
                        room["notes"] = []
                    room["notes"].append(note)
                    self.game.pushevent("lineunknown", b"mapper: added note to dungeon")
            if len(parts) > 1 and parts[1] == "navtoroom":
                if len(parts) < 3:
                    self.game.pushevent("lineunknown", b"mapper: need target room name")
                else:
                    pass

            if len(parts) > 1 and parts[1] == "tracemalloc":
                ss = tracemalloc.take_snapshot()
                top_stats = ss.statistics("lineno")
                for stat in top_stats[0:30]:
                    print(stat)

            if len(parts) > 1 and parts[1] == "listnotes":
                if self.lastbatmapper is None:
                    self.game.pushevent("lineunknown", b"mapper: not inside dungeon (look at map for world maybe..)")
                else:
                    zonename = self.lastbatmapper[0]
                    zone = self.batmap[zonename]
                    for roomname in zone:
                        room = zone[roomname]
                        if "notes" in room:
                            self.game.pushevent("lineunknown", b"  " + bytes(roomname, "utf8"))
                            for note in room["notes"]:
                                self.game.pushevent("lineunknown", b"    " + bytes(note, "utf8"))

            if len(parts) > 1 and parts[1] == "findout":
                self.game.pushevent("lineunknown", b"\x1b#ffffffmmapper: Entrance And/Or Exit Shortest Path")
                goal = self.findpath(self.goalcheck_enterorexit)
                for history, extra in goal:
                    zonename = history[-1][0]
                    roomname = history[-1][1]
                    zone = self.batmap[zonename]
                    room = zone[roomname]
                    if len(room["entered"]) > 0:
                        prefix = []
                        for txt in room["entered"]:
                            prefix.append("%s" % txt)
                        prefix = b"   (out)" + bytes("|".join(prefix), "utf8")
                        self.game.pushevent("lineunknown", prefix)
                    if len(room["exited"]) > 0:
                        prefix = []
                        for txt in room["exited"]:
                            prefix.append("%s" % txt)
                        prefix = b"   (in)" + bytes("|".join(prefix), "utf8")
                        self.game.pushevent("lineunknown", prefix)
                    line = []
                    # drop the first node
                    history = history[1:]
                    for zonename, roomname, action in history:
                        line.append("%s->" % action)
                    line = bytes("".join(line), "utf8")
                    self.game.pushevent("lineunknown", b"     \x1b#99ff99m->" + line)

            if len(parts) > 1 and parts[1] == "findnew":
                self.game.pushevent("lineunknown", b"\x1b#ffffffmmapper: Unexplored Rooms")
                # gg = self.findpath(None)
                gg = {}

                def __goalcheck_newcheck(zonename, roomname, _, coff):
                    zone = self.batmap[zonename]
                    room = zone[roomname]

                    amap = self.amap

                    havedonemoves = set()
                    for zoneandroom, move in room["backward"]:
                        havedonemoves.add(move)
                    for zoneandroom, move in room["forward"]:
                        havedonemoves.add(move)

                    # dprint('goal check', zonename, roomname, havedonemoves, room['moves'])

                    for move in room["moves"]:
                        if move not in havedonemoves:
                            if coff[0] is not None and move in amap:
                                ggoff = amap[move]
                                cx = coff[0] + ggoff[0]
                                cy = coff[1] + ggoff[1]
                                cz = coff[2] + ggoff[2]
                                if (cx, cy, cz) in gg:
                                    # nope, we been here before
                                    continue
                                return (cx, cy, cz)
                            else:
                                return (None, None, None)
                    return False

                goal = self.findpath(__goalcheck_newcheck)
                for x in range(0, min(len(goal), 15)):
                    dprint("goal", goal[x][1])

                    history = goal[x][0]
                    tx, ty, tz = goal[x][1]

                    endzonename = history[-1][0]
                    endroomname = history[-1][1]

                    line = []
                    # drop the first node
                    for zonename, roomname, action in history:
                        line.append("%s->" % action)

                    # figure out which moves have never been made
                    goalroom = self.batmap[endzonename][endroomname]

                    havedonemoves = set()

                    for zoneandroom, move in goalroom["backward"]:
                        havedonemoves.add(move)

                    for zoneandroom, move in goalroom["forward"]:
                        havedonemoves.add(move)

                    sub = []
                    for move in goalroom["moves"]:
                        if move not in havedonemoves:
                            if tx is not None and move in self.amap:
                                ggoff = self.amap[move]
                                cx = tx + ggoff[0]
                                cy = ty + ggoff[1]
                                cz = tz + ggoff[2]
                                if (cx, cy, cz) in gg:
                                    # nope, we been here before
                                    continue
                            sub.append(move)

                    if len(sub) > 0:
                        line.append("\x1b#9999ddm[%s]" % "|".join(sub))

                        line = bytes("".join(line), "utf8")
                        self.game.pushevent("lineunknown", b"     \x1b#99ff99m->" + line)

            return (True, True)
示例#20
0
    def event_command(self, event, command):
        parts = command.split(' ')

        if len(parts) > 0 and parts[0] == 'mapper':
            if len(parts) > 1 and parts[1] == 'totals':
                zonecount = 0
                roomcount = 0
                for zone in self.batmap:
                    zonecount += 1
                    for room in zone:
                        roomcount += 1
                self.game.pushevent(
                    'lineunknown',
                    bytes(
                        '\x1b#ffffffmapper: tracking %s zones and %s rooms!' %
                        (zonecount, roomcount), 'utf8'))
            if len(parts) > 1 and parts[1] == 'addnote':
                note = ' '.join(parts[2:])
                if self.lastbatmapper is None:
                    if self.lastcord is not None:
                        cx = self.lastcord[0]
                        cy = self.lastcord[1]
                        self.notes.append([cx, cy, note, None])
                        self.notesflush()
                        # specify to drop propagation of event and not to forward command
                        self.game.pushevent('lineunknown',
                                            b'mapper: added note to world')
                        return (True, True)
                else:
                    zonename = self.lastbatmapper[0]
                    roomname = self.lastbatmapper[1]
                    room = self.batmap[zonename][roomname]
                    if 'notes' not in room:
                        room['notes'] = []
                    room['notes'].append(note)
                    self.game.pushevent('lineunknown',
                                        b'mapper: added note to dungeon')
            if len(parts) > 1 and parts[1] == 'navtoroom':
                if len(parts) < 3:
                    self.game.pushevent('lineunknown',
                                        b'mapper: need target room name')
                else:
                    pass

            if len(parts) > 1 and parts[1] == 'tracemalloc':
                ss = tracemalloc.take_snapshot()
                top_stats = ss.statistics('lineno')
                for stat in top_stats[0:30]:
                    print(stat)

            if len(parts) > 1 and parts[1] == 'listnotes':
                if self.lastbatmapper is None:
                    self.game.pushevent(
                        'lineunknown',
                        b'mapper: not inside dungeon (look at map for world maybe..)'
                    )
                else:
                    zonename = self.lastbatmapper[0]
                    zone = self.batmap[zonename]
                    for roomname in zone:
                        room = zone[roomname]
                        if 'notes' in room:
                            self.game.pushevent(
                                'lineunknown', b'  ' + bytes(roomname, 'utf8'))
                            for note in room['notes']:
                                self.game.pushevent(
                                    'lineunknown',
                                    b'    ' + bytes(note, 'utf8'))

            if len(parts) > 1 and parts[1] == 'findout':
                self.game.pushevent(
                    'lineunknown',
                    b'\x1b#ffffffmmapper: Entrance And/Or Exit Shortest Path')
                goal = self.findpath(self.goalcheck_enterorexit)
                for history, extra in goal:
                    zonename = history[-1][0]
                    roomname = history[-1][1]
                    zone = self.batmap[zonename]
                    room = zone[roomname]
                    if len(room['entered']) > 0:
                        prefix = []
                        for txt in room['entered']:
                            prefix.append('%s' % txt)
                        prefix = b'   (out)' + bytes('|'.join(prefix), 'utf8')
                        self.game.pushevent('lineunknown', prefix)
                    if len(room['exited']) > 0:
                        prefix = []
                        for txt in room['exited']:
                            prefix.append('%s' % txt)
                        prefix = b'   (in)' + bytes('|'.join(prefix), 'utf8')
                        self.game.pushevent('lineunknown', prefix)
                    line = []
                    # drop the first node
                    history = history[1:]
                    for zonename, roomname, action in history:
                        line.append('%s->' % action)
                    line = bytes(''.join(line), 'utf8')
                    self.game.pushevent('lineunknown',
                                        b'     \x1b#99ff99m->' + line)

            if len(parts) > 1 and parts[1] == 'findnew':
                self.game.pushevent('lineunknown',
                                    b'\x1b#ffffffmmapper: Unexplored Rooms')
                #gg = self.findpath(None)
                gg = {}

                def __goalcheck_newcheck(zonename, roomname, _, coff):
                    zone = self.batmap[zonename]
                    room = zone[roomname]

                    amap = self.amap

                    havedonemoves = set()
                    for zoneandroom, move in room['backward']:
                        havedonemoves.add(move)
                    for zoneandroom, move in room['forward']:
                        havedonemoves.add(move)

                    #dprint('goal check', zonename, roomname, havedonemoves, room['moves'])

                    for move in room['moves']:
                        if move not in havedonemoves:
                            if coff[0] is not None and move in amap:
                                ggoff = amap[move]
                                cx = coff[0] + ggoff[0]
                                cy = coff[1] + ggoff[1]
                                cz = coff[2] + ggoff[2]
                                if (cx, cy, cz) in gg:
                                    # nope, we been here before
                                    continue
                                return (cx, cy, cz)
                            else:
                                return (None, None, None)
                    return False

                goal = self.findpath(__goalcheck_newcheck)
                for x in range(0, min(len(goal), 15)):
                    dprint('goal', goal[x][1])

                    history = goal[x][0]
                    tx, ty, tz = goal[x][1]

                    endzonename = history[-1][0]
                    endroomname = history[-1][1]

                    line = []
                    # drop the first node
                    for zonename, roomname, action in history:
                        line.append('%s->' % action)

                    # figure out which moves have never been made
                    goalroom = self.batmap[endzonename][endroomname]

                    havedonemoves = set()

                    for zoneandroom, move in goalroom['backward']:
                        havedonemoves.add(move)

                    for zoneandroom, move in goalroom['forward']:
                        havedonemoves.add(move)

                    sub = []
                    for move in goalroom['moves']:
                        if move not in havedonemoves:
                            if tx is not None and move in self.amap:
                                ggoff = self.amap[move]
                                cx = tx + ggoff[0]
                                cy = ty + ggoff[1]
                                cz = tz + ggoff[2]
                                if (cx, cy, cz) in gg:
                                    # nope, we been here before
                                    continue
                            sub.append(move)

                    if len(sub) > 0:
                        line.append('\x1b#9999ddm[%s]' % '|'.join(sub))

                        line = bytes(''.join(line), 'utf8')
                        self.game.pushevent('lineunknown',
                                            b'     \x1b#99ff99m->' + line)

            return (True, True)
示例#21
0
    def findpath(self, goalcheck, usegg=True):
        """This will find all paths that satisfy the goal check function provided.

        This will find all paths that satisfy the goal check function provided.

        goalcheck    - shall be a function taking the appropriate arguments
        usegg        - uses geometric grid to determine if rooms have been visited
        """
        if self.lastbatmapper is None:
            self.game.pushevent(
                'lineunknown',
                b'mapper: not inside zone - assuming your in the world (try moving)!'
            )
            return []
        thiszone = self.lastbatmapper[0]
        zone = self.batmap[thiszone]
        thisxid = self.lastbatmapper[1]
        goal = []
        visited = set()
        gg = set()
        gg = {}
        gg[(0, 0, 0)] = (thiszone, thisxid)
        bugs = []
        bugs.append(
            (thiszone, thisxid, [(thiszone, thisxid, 'start')], 0, 0, 0))
        amap = self.amap
        if goalcheck is not None:
            res = goalcheck(thiszone, thisxid, gg, (0, 0, 0))
            if res is not False and res is not None:
                goal.append(([(thiszone, thisxid, 'start')], res))
        visited.add((thiszone, thisxid))
        while len(bugs) > 0:
            _bugs = []
            # iterate through parents letting them create child bugs
            for thiszone, thisxid, history, tx, ty, tz in bugs:
                zone = self.batmap[thiszone]
                room = zone[thisxid]
                forward = room['forward']
                backward = room['backward']
                _combined = set()
                for action in forward:
                    _combined.add(action)
                for action in backward:
                    _combined.add(action)

                for action in _combined:
                    tozone, toxid = action[0]
                    if (tozone, toxid) in visited:
                        # if we been here before dont go back to it
                        continue
                    tomove = action[1]
                    # create new child bug that inherits parent history
                    nhistory = history + [(tozone, toxid, tomove)]
                    if tx is not None and tomove in amap:
                        ggoff = amap[tomove]
                        cx = tx + ggoff[0]
                        cy = ty + ggoff[1]
                        cz = tz + ggoff[2]
                        if (cx, cy, cz) in gg:
                            # it seems most dungeons do not have a straight forward
                            # geometric grid representation for vertical layers which
                            # means this fails to eliminate all visited rooms.. so we
                            # just have to be aware of it
                            pass
                        gg[(cx, cy, cz)] = (tozone, toxid)
                    else:
                        cx = None
                        cy = None
                        cz = None
                        dprint('LOST GEO GRID with %s:%s' % (tx, tomove))

                    _bugs.append((tozone, toxid, nhistory, cx, cy, cz))
                    if goalcheck is not None:
                        res = goalcheck(tozone, toxid, gg, (cx, cy, cz))
                        if res is not False and res is not None:
                            goal.append((nhistory, res))
                    visited.add((tozone, toxid))
            # parent die and children become parents
            bugs = _bugs
        self.game.pushevent(
            'lineunknown',
            bytes(
                '  Searched %s/%s/%s Rooms' %
                (len(visited), len(zone), len(gg)), 'utf8'))
        # should have zero or more goals
        if goalcheck is None:
            return gg
        else:
            return goal
示例#22
0
    def event_blockunknown(self, event, block):
        #b:b'\x1b<10spec_skill\x1b|The final estimation is that Caretaker of the Temple can easily reduce you to\r\nminced meat, so run for your life.\r\n\x1b>10'
        #b:b'\x1b<10spec_skill\x1b|The final estimation is that Monarch butterfly looks quite skilled, beware.\r\n\x1b>10'
        #b:b"\x1b<10spec_skill\x1b|The final estimation is that Warthog's power overwhelms your mind! You PANIC!!\r\n\x1b>10"
        if block.find(b'\x1b<10spec_skill\x1b|The final estimation is that') == 0:
            i = block.find(b'that') + 5
            x = findmulti(block, (b'can', b'looks', b'power', b'and', b'has'), i)
            mob_basename = block[i:x].strip()
            desc = block[x:]

            if mob_basename.endswith(b'\'s'):
                mob_basename = mob_basename[0:-2]

            mob_basename = mob_basename.decode('utf8')
            desc = desc.decode('utf8')
            if desc.find('\r') > -1:
                desc = desc[0:desc.find('\r')].strip()

            print('mob_basename:[%s] desc:[%s]' % (mob_basename, desc))

            if self.consider_intercept:
                entry = self.pendingconsiders.pop(0)
                self.moblore['descnametoname'][entry[1]] = mob_basename
            else:
                entry = None

            mylevel = self.playerlevel

            # if we do not have our level then the consideration
            # can be quite meaningless really... right?
            if mylevel > -1:
                if mylevel not in self.moblore['consider-base']:
                    self.moblore['consider-base'][mylevel] = {}
                if mylevel not in self.moblore['consider-full']:
                    self.moblore['consider-full'][mylevel] = {}
                self.moblore['consider-base'][mylevel][mob_basename] = desc
                if entry is not None:
                    self.moblore['consider-full'][mylevel][entry[1]] = desc
                self.game.pushevent('lineunknown', b'\x1b#99ff99mAdded level of [' + bytes(mob_basename, 'utf8') + b'] to MOB-LORE.')
                self.dumplore()

            if self.consider_intercept:
                self.consider_intercept = False                
                # remove everything else to keep from just wasting
                # bandwidth and time trying them when we have already
                # found the correct one
                _pendingconsiders = []
                for p in self.pendingconsiders:
                    if p[1] != entry[1]:
                        _pendingconsiders.append(p)
                self.pendingconsiders = _pendingconsiders

                self.pendinglooks.append(mob_basename)
                self.do_nextconsider()
                return True
            else:
                # take a quick look at the mob
                dprint('doing quick look at [%s]' % mob_basename)
                self.game.lockcmdgroup(self)
                self.pendinglooks.append(mob_basename)
                self.do_nextlook()
        elif block.find(b'\x1b<10spec_skill') == 0 and self.consider_intercept:
            # drop it
            return True
示例#23
0
    def processline(self, line, fgdef = None, bgdef = None):
        """Add line but convert terminal codes into HTML and convert from bytes to string.
        """
        # convert to string and replace any crazy characters
        line = line.decode('utf8', 'ignore')

        line = line.replace('\\', '\\\\')

        # escape any quotes because we encode this string into
        # javascript call and unescaped quotes will screw it up
        line = line.replace('"', '\\"')

        line = line.replace('<', '&lt;')
        line = line.replace('>', '&gt;')

        line = line.replace('-', '<nobr>-</nobr>')

        line = line.replace('\t', '&#9;')
        line = line.replace(' ', '&nbsp;')

        # split it to handle terminal escape codes
        parts = line.split('\x1b')

        line = []

        fgdef = fgdef or self.fgcolor
        bgdef = bgdef or self.bgcolor

        line.append('<span class=\\"%s %s\\">%s</span>' % (fgdef, bgdef, parts[0]))

        for x in range(1, len(parts)):
            part = parts[x]
            if part[0] == '#':
                hexcolor = part[1:part.find('m')]
                hexcolor = hexcolortotuple(hexcolor)
                hexcolor = hexcolordimblue(hexcolor, 0.4)
                #hexcolor = hexcolordimer(hexcolor, 1.0, 1.0, 0.6)
                hexcolor = tupletohexcolor(hexcolor)
                rmsg = part[part.find('m') + 1:]
                rmsg = rmsg.replace('   ', '&nbsp;' * 3)
                rmsg = rmsg.replace(' ', '&nbsp;')
                line.append('<span style=\\"color: #%s;\\">%s</span>' % (hexcolor, rmsg))
                #line.append(rmsg)
                continue
            if part[0] != '[':
                print('Expected [!')
            cstr = part[1:part.find('m')]
            rmsg = part[part.find('m') + 1:]
            codes = cstr.split(';')
            if len(cstr) < 1:
                self.fgcolor = self.nfgcolor
                self.bgcolor = self.nbgcolor
            for code in codes:
                if len(code) < 1:
                    continue
                if code == '0':
                    self.fgcolor = self.nfgcolor
                    self.bgcolor = self.nbgcolor
                    self.fgbright = False
                    continue
                if code == '1':
                    self.fgbright = True
                    continue
                if code == '2':
                    self.fgbright = False
                    continue
                if code[0] == '3':
                    val = code[1]
                    if val in self.colormap:
                        if self.fgbright:
                            self.fgcolor = 'hc_bfg_%s' % self.colormap[val]
                        else:
                            self.fgcolor = 'hc_fg_%s' % self.colormap[val]
                    continue
                if code[0] == '4':
                    if code[1] in self.colormap:
                        self.bgcolor = 'hc_bg_' % self.colormap[code[1]]
                    continue
                dprint('ignored code [%s]' % code)

            line.append('<span class=\\"%s %s\\">%s</span>' % (self.fgcolor, self.bgcolor, rmsg))

        line = ''.join(line)

        return line