def upload_chunk(self): done, chunk = self.up.next() for cmd in chunk: cmd = cmd.rstrip() # convert tabs to spaces if TABSIZE > 0: cmd = cmd.expandtabs(TABSIZE) # /send blank does nothing, so send a space if not cmd: cmd = " " # and send it tf.send(cmd, self.world) self.lines_sent += 1 # clean up and finish, or schedule further upload if done: self.done() del self.up else: # show progress if self.progress_size and (self.lines_sent - self.lines_sent0) >= self.progress_size: tf.out( "- diffedit.upload -> %s %s - %4d cmds sent" % \ ( self.world, self.remote, self.lines_sent ) ) self.lines_sent0 = self.lines_sent - (self.lines_sent % self.progress_size) # schedule a callback in 1 second INPROGRESS[self.keyname] = self tf.eval('/repeat -w%s -1 1 /python_call diffedit.__more %s' % (self.world, self.keyname))
def execute(self, announce_only=False): """ """ if announce_only: template = ( '/run_path -a%(announce)s -A%(alignment)s -F%(flags)s -r%(index)d -s%(skip)d ' '-t%(target)s -w%(out)s -W%(warnings)s -x%(in)s') else: template = ( '/run_path -a%(announce)s -A%(alignment)s -c%(commands)s -d%(path)s -F%(flags)s ' '-i%(items)s -r%(index)d -s%(skip)d -t%(target)s -w%(out)s -W%(warnings)s -x%(in)s') tf.eval(template % { 'alignment': repr(self._alignment), 'announce': repr(self._announce), 'commands': repr(';'.join(self._commands)), 'flags': repr(self._flags), 'in': repr(';'.join(self._in_commands)), 'index': self._index, 'items': repr(self._items), 'out': repr(';'.join(self._out_commands)), 'path': repr(';'.join(self._path)), 'skip': self.next_skip, 'target': repr(self._target), 'warnings': repr(self._warnings), })
def loadMovementsFromConfigFile(self, config_file): """Load movements from config file. Args: config_file: String Returns: Boolean """ if (not os.path.isfile(config_file + '.py') and not os.path.isfile(config_file + '.pyc')): tf.err('Could not find file: %s [.py or .pyc]' % config_file) return False path, basename = os.path.split(config_file) movements = self.loadMovementsListFromConfigFile(path, basename) if not isinstance(movements, list): tf.err('The FILE attribute is not a list.') return False self.fixMovements(movements) self.loadMovementsFromDictList(movements) tf.eval('/say -d"party" -b -c"green" -- Loaded run from config: %s' % basename) self._name = basename self._path = config_file return True
def quit(argstr): cmd, opts, argstr = tfutil.cmd_parse(argstr, 'y') if not ACTIVITY: opts['y'] = '' tf.eval(tfutil.cmd_unparse("/@quit", opts, argstr))
def activate(self): self.check_last() global FG if self != FG: FG = self tf.eval("/set _tf4world=%s" % self.name)
def recall(argstr): cmd, opts, argstr = tfutil.cmd_parse(argstr, 'w:ligvt:a:m:A:B:C:') if not 'w' in opts or not opts['w']: opts['w'] = FG.name tf.eval(tfutil.cmd_unparse("/@recall", opts, argstr))
def execute(self, announce_only=False): """ """ if announce_only: template = ( '/run_path -a%(announce)s -A%(alignment)s -F%(flags)s -r%(index)d -s%(skip)d ' '-t%(target)s -w%(out)s -W%(warnings)s -x%(in)s') else: template = ( '/run_path -a%(announce)s -A%(alignment)s -c%(commands)s -d%(path)s -F%(flags)s ' '-i%(items)s -r%(index)d -s%(skip)d -t%(target)s -w%(out)s -W%(warnings)s -x%(in)s ' '-e%(eval)s') tf.eval( util.escape( template % { 'alignment': repr(self._alignment), 'announce': repr(self._announce), 'commands': repr(';'.join(self._commands)), 'eval': repr(self._eval), 'flags': repr(self._flags), 'in': repr(';'.join(self._in_commands)), 'index': self._index, 'items': repr(self._items), 'out': repr(';'.join(self._out_commands)), 'path': repr(';'.join(self._path)), 'skip': self.next_skip, 'target': repr(self._target), 'warnings': repr(self._warnings), }))
def connect(argstr): cmd, opts, argstr = tfutil.cmd_parse(argstr, "lqxfb") opts['b'] = '' if 'f' in opts: del opts['f'] tf.out(tfutil.cmd_unparse("/@connect", opts, argstr)) tf.eval(tfutil.cmd_unparse("/@connect", opts, argstr))
def screenscrape(command): """ Execute an arbitrary command and returns the output as a list. """ _caught[:] = [] x = tf.eval("/def -iq _tfscrape = /python_call tfutil._scrape \%*") tf.eval("/quote -S /_tfscrape `%s" % command) tf.eval("/undefn %s" % x) return _caught[:]
def conhook(argstr): name = argstr.split()[0] world = WDICT.get(name.lower()) if not world: # create a new world - adds itself to WDICT, WLIST world = World(name) tf.eval("/@fg _tf4") # just in case world.connect()
def setup(): CONN.send("testing connection") eval( "/def -mglob -q -p10 -t'chan_party: *' chat_party = /python_call chat.trigger \%-1" ) eval( "/def -mglob -q -p10 -t'chan_tell: *' chat_tell = /python_call chat.trigger \%-1" ) tfprint("Loaded chat.py")
def status(self, argstr): # save current fields if not self.status_saved: tf.eval("/status_save _tf4status") self.status_saved = True if not argstr.startswith("/"): argstr = "/status_" + argstr tf.eval(argstr)
def setvar(self, var, value): """ old = State.setvar( <var>, <value> ) set TF variable <var> to <value>, returns the old value. Saves the old value for when reverting State. """ old = tf.getvar(var) tf.eval("/set %s=%s" % (var, value)) if not var in self.oldvar: self.oldvar[var] = old return old
def skip(self): if self._current is not None: skip = self._current.skip if skip: tf.eval( '/say -d"party" -x -b -c"yellow" -- SKIPPING %d ROOM%s' % ( skip, 'S' if skip != 1 else '')) for unused_i in xrange(skip - 1): self.forward() self.execute(announce_only=True) self.forward() return self._current
def skip(self): if self._current is not None: skip = self._current.skip if skip: tf.eval( '/say -d"party" -x -b -c"yellow" -- SKIPPING %d ROOM%s' % (skip, 'S' if skip != 1 else '')) for unused_i in xrange(skip - 1): self.forward() self.execute(announce_only=True) self.forward() return self._current
def exitInfo(json): try: exits = json['exits'] tf.eval('/_statusbar_update_compass %s' % ' '.join(exits)) exits = ', '.join(exits) tf.eval('/set __movement_exits=%s' % exits) debug('exitinfo -> %s' % exits) except: return
def on(self, quiet=False): """Turn this effect on and call back to tf extra information. Args: quiet: Boolean """ self._state.append(time.time()) self._state = self._state[-self._layers:] if quiet: return if self._layers > 1: tf.eval('/announce_effect -p%s -s1 -o%s' % ( repr(self._name), repr('%d/%d' % (self.count, self._layers)))) else: tf.eval('/announce_effect -p%s -s1' % repr(self._name))
def roomInfo(json): try: domain = json['map']['domain'] x = json['map']['x'] y = json['map']['y'] location = "%s.%sx%s" % (domain, x, y) if location in set(telepyrts): eval = '/_map_teleport %s' % telepyrts.get(location) debug(eval) tf.eval(eval) except (AttributeError, KeyError) as e: debug('roomInfo error: %s not found' % e.message) return
def display(self, command): session = self.session total = self.total output = [ '.-----------------------------------------------------------------------------.', '| %s |' % self._name.center(75), '|-------------------------------.----------------------.----------------------|', '| | SESSION | TOTAL |', '|-------------------------------+----------------------+----------------------|', ] special = [] found = False for stat in self: if stat.hide: continue if stat.special: special.append( '| %-29s | %10s (%6.2f%%%%) | %10s (%6.2f%%%%) |' % (stat.name, util.formatNumber(stat.session), stat.session * 100.0 / (session or 1), util.formatNumber( stat.total), stat.total * 100.0 / (total or 1))) continue found = True output.append('| %-29s | %10s (%6.2f%%%%) | %10s (%6.2f%%%%) |' % (stat.name, util.formatNumber( stat.session), stat.session * 100.0 / (session or 1), util.formatNumber( stat.total), stat.total * 100.0 / (total or 1))) if found: output.append( '|-------------------------------+----------------------+----------------------|' ) if special: special.append( '|-------------------------------+----------------------+----------------------|' ) output.extend(special) output.append('| | %20s | %20s |' % (util.formatNumber(session), util.formatNumber(total))) output.append( "'-------------------------------'----------------------'----------------------'" ) for line in output: tf.eval('%s %s' % (command, line))
def roomInfo(json): try: name = json['map']['name'] x = json['map']['x'] y = json['map']['y'] location = "%s.%sx%s" % (name, x, y) tf.eval("/set _map_gmcp_location=%s" % location) if location in set(telepyrts): eval = '/_map_teleport %s' % telepyrts.get(location) debug(eval) tf.eval(eval) except (AttributeError, KeyError) as e: debug('roomInfo error: %s not found' % e.message) return
def display(self, command): session = self.session total = self.total output = [ '.-----------------------------------------------------------------------------.', '| %s |' % self._name.center(75), '|-------------------------------.----------------------.----------------------|', '| | SESSION | TOTAL |', '|-------------------------------+----------------------+----------------------|', ] special = [] found = False for stat in self: if stat.hide: continue if stat.special: special.append('| %-29s | %10s (%6.2f%%%%) | %10s (%6.2f%%%%) |' % ( stat.name, util.formatNumber(stat.session), stat.session * 100.0 / (session or 1), util.formatNumber(stat.total), stat.total * 100.0 / (total or 1))) continue found = True output.append('| %-29s | %10s (%6.2f%%%%) | %10s (%6.2f%%%%) |' % ( stat.name, util.formatNumber(stat.session), stat.session * 100.0 / (session or 1), util.formatNumber(stat.total), stat.total * 100.0 / (total or 1))) if found: output.append( '|-------------------------------+----------------------+----------------------|') if special: special.append( '|-------------------------------+----------------------+----------------------|') output.extend(special) output.append('| | %20s | %20s |' % ( util.formatNumber(session), util.formatNumber(total))) output.append("'-------------------------------'----------------------'----------------------'") for line in output: tf.eval('%s %s' % (command, line))
def dc(argstr): argstr = argstr.lower().strip() # do them all if argstr == "-all": for world in WLIST: tf.out("/@dc %s" % world.name) tf.eval("/@dc %s" % world.name) dischook(world.name + " tf4") return # otherwise do foreground world if argstr: world = WDICT.get(argstr) else: world = FG if world: tf.eval("/@dc %s" % world.name) dischook(world.name + " tf4")
def forall(self, template, keys=None, online=True, offline=True): """Apply template for each effect that matches the search criteria. Args: template: String keys: String/List online: Boolean offline: Boolean """ if not template: return if keys is None: effects = sorted(self._effects.values()) else: effects = [] if isinstance(keys, str): keys = keys.split() for key in keys: if key in self._effect_groups: effects.append(self._effect_groups[key]) elif key in self._effects: effects.append(self._effects[key]) found = False for effect in effects: result = effect.stateDict(online=online, offline=offline) if result: found = True tf.eval(template % result) if not found: tf.eval(template % { 'name': 'None', 'key': '', 'count': '-', 'status': '-', 'state': '-', 'color': 'red', })
def charInfo(json): debug('charInfo, received %s' % json) try: hp = int(json['hp']) + 1 color, bg = hpColor(hp) tf.eval('/_statusbar_update_hp %s %s %s' % (hp, color, bg)) debug('charInfo -> hp to %s' % hp) except Exception as e: pass try: stamina = 10 - int(json['fatigue']) tf.eval('/_statusbar_update_stamina %s' % stamina) debug('charInfo -> stamina to %s' % stamina) except Exception as e: pass try: mana = int(json['mana']) tf.eval('/_statusbar_update_mana %s' % mana) debug('charInfo -> mana to %s' % mana) except Exception as e: pass
def _change_worlds(old, wdict): # remove old worlds for name, item in old.items(): if name not in wdict: tf.eval("/unworld " + name) # add new or changed worlds for name, item in wdict.items(): cmd = item.addworld_command(func=True, full=True) if name not in old: if cmd: tf.eval(cmd) elif item.changed_from(old[name]): tf.eval("/unworld " + name) if cmd: tf.eval(cmd)
def off(self, quiet=False): """Turn this effect off and call back to tf extra information. Args: quiet: Boolean """ duration = self.duration if self._state: self._last_duration = duration self._state = self._state[1:] if quiet: return tanking = tf.eval('/test is_me(tank)') if self._layers > 1: tf.eval('/announce_effect -p%s -s0 -o%s -n%d' % ( repr(self._name), repr('%s, %d/%d' % ( util.getPrettyTime(int(duration), short=True), self.count, self._layers)), 2 if tanking else 1)) else: tf.eval('/announce_effect -p%s -s0 -o%s -n%d' % ( repr(self._name), repr(util.getPrettyTime(int(duration), short=True)), 2 if tanking else 1))
def define(self, name="", body="", flags=""): """ n = State.define( name='<name>', body='<body>', flags='<flags>' ) Adds a new /def, returns the number of the new /def. All args optional. Saves the old value of named /def if it exists, for reverting State. Not named def() because that's a Python keyword. """ if name and not name in self.olddef: x = screenscrape("/list -i -msimple %s" % name) if x: self.olddef[name] = x[0] if flags and not flags.startswith("-"): flags = "-" + flags n = tf.eval("/def %s %s = %s" % (flags, name, eval_escape(body))) self.newdef.append(n) return n
def bind(self, key, body="", flags=""): """ n = State.bind( key='<key>', body='<body>', flags='<flags>' ) Create a new key binding for <key>. Returns the number of the new /def. Body and flags are optional. Saves old binding for reverting State. """ if not key: raise Exception("tfutil.bind: empty key name") if not key in self.oldkey: x = screenscrape("/list -i -msimple -b'%s'" % key) if x: self.oldkey[key] = x[0] if flags and not flags.startswith("-"): flags = "-" + flags key = "-b'%s'" % key.strip("'") n = tf.eval("/def %s %s = %s" % (flags, key, eval_escape(body))) self.newkey.append(n) return n
def worlds(argstr): # wrap the function in case it crashes curses.wrapper(_worlds) # screen is all messed up, redraw it tf.eval("/dokey REDRAW")
def _worlds(stdscr): # get dictionary of current worlds wdict = tfutil.listworlds(asdict=True) cols, lines = tfutil.screensize() colors = curses.can_change_color() # Draw the border and create a world window stdscr.clear() stdscr.border() stdscr.addstr(0, 4, "| TinyFugue Worlds |", curses.A_BOLD) wpos, lastwpos = 0, 9999 worldwin, scrollwin = _worldwin(stdscr, lines - 4, cols - 4, 2, 2) #worldwin, scrollwin = _worldwin( stdscr, 15, cols-4, 2, 2 ) worldwin.refresh() # start an undo stack undo, redo = [], [] global SAVED # now loop message, lastmessage = None, "dummy" while True: # sort by name wlist = sorted(wdict.values()) # draw the list, get a command _drawworlds(wlist, scrollwin, wpos, lastwpos) lastwpos = wpos # # parse keys # c = scrollwin.getkey() # Movement if c in ('i', 'KEY_UP', '\x10'): if wpos > 0: wpos -= 1 elif c in ('j', 'KEY_DOWN', '\x0e'): if (wpos + 1) < len(wlist): wpos += 1 # actual editing elif wlist and c in ('d', 'KEY_DC'): message = 'Deleted world %s' % wlist[wpos].name _new_undo(undo, wdict, message, SAVED) del wdict[wlist[wpos].name] wpos = min(wpos, len(wdict) - 1) SAVED, lastwpos = False, 9999 elif wlist and c in ('c', ): w = wlist[wpos] for i in range(2, 99): newname = '%s(%d)' % (w.name, i) if not newname in wdict: message = 'Copied world %s' % newname _new_undo(undo, wdict, message, SAVED) newworld = tfutil.World(w) newworld.name = newname wdict[newname] = newworld SAVED, lastwpos = False, 9999 break elif c in ('a', 'KEY_INS'): w = _editworld(worldwin, wdict.keys(), None) if w: message = 'Added world %s' % w.name _new_undo(undo, wdict, message, SAVED) wdict[w.name] = w SAVED = False lastwpos = 9999 _worldwin_redraw(worldwin) elif wlist and c in ('e', ): oldname = wlist[wpos].name w = _editworld(worldwin, wdict.keys(), tfutil.World(wlist[wpos])) if w: message = 'Edited world %s' % w.name _new_undo(undo, wdict, message, SAVED) if oldname != w.name: del wdict[oldname] wdict[w.name] = w SAVED = False lastwpos = 9999 _worldwin_redraw(worldwin) # undo/redo elif c == 'u': if undo: message, wdict2, SAVED2 = undo.pop() _new_undo(redo, wdict, message, SAVED) wdict, SAVED = wdict2, SAVED2 message = "Undid: " + message lastwpos = 9999 else: message = 'Nothing to undo' elif c == 'r': if redo: message, wdict2, SAVED2 = redo.pop() _new_undo(undo, wdict, message, SAVED) wdict, SAVED = wdict2, SAVED2 message = "Redid: " + message lastwpos = 9999 else: message = 'Nothing to redo' # Anything that terminates us elif wlist and c in ('\n', 'KEY_ENTER', 'Q'): if undo: _change_worlds(undo[0][1], wdict) if c != 'Q': tf.eval("/connect %s" % wlist[wpos].name) if not SAVED: tf.err("* Warning: your /worlds haven't been saved yet") break elif c == 'S': if undo: _change_worlds(undo[0][1], wdict) if not SAVED: SAVED, message = _save_worlds(wdict) if SAVED: break elif c == 'A': if not SAVED: tf.err("* all /worlds changes aborted") SAVED = False break message, lastmessage = _show_message(stdscr, message, lastmessage)
else: if i < start or i >= end: continue attrib = (wpos == i) and curses.A_REVERSE or curses.A_NORMAL item = wlist[i] ssl = ('x' in item.flags) and '*' or ' ' window.addnstr( "%-10s %-16s %s%-20s %5s" % \ ( item.name, item.character, ssl, item.host, item.port ), cols, attrib ) window.move(wpos - top, 0) window.refresh() # Define our functions tf.eval("/def worlds=/python_call config.worlds") # --------------------------------------------------------------------------- # Editing a world # --------------------------------------------------------------------------- def _validate_port(world, worldnames, value): try: if int(value) > 0 and int(value) < 65536: return None except: pass return "Port number must be from 1 and 65535."
def toggle(dummy): tf.eval("/def -hGMCP _gmcp_received = /python_call gmcp.handle \%{*}")
def display(self): tf.eval('/say -d"status" -- %s' % self._current)
import tf import sys import pprint def wrapper(args): macro, arg = args.split(None,1) pprint.pprint((macro,args)) sys.stdout.output = tf.out sys.stderr.output = tf.err tf.eval("/def -hCONNECT h_connect_hook = /python_call %s.wrapper h_connect_hook \\%%*" % __name__)
def unload(self): self._first = None self._current = None self._name = None self._path = None tf.eval('/say -d"party" -b -c"yellow" -- Unloaded run')