from lib.client_interfacer import ClientInterfacer cf = ClientInterfacer() cf._sendToClient("monitor") while 1: s = cf._readLineFromClient() if s.startswith("scripttell"): break cf._sendToConsole(s)
""" Print sys.argv for the player to see. To demonstrate that you can pass command line arguments to crossfire scripts. """ import sys from lib.client_interfacer import ClientInterfacer cf = ClientInterfacer() cf.draw("sys.argv is:") for i in range(len(sys.argv)): cf.draw("- %s) %r" % (i, sys.argv[i]))
from lib.client_interfacer import ClientInterfacer, Color cf = ClientInterfacer(targetPendingCommands=100) cf.draw("scripttell me the tag of an item to use for the test.") cf.waitForScripttell() s = cf.getNextScripttell() tag = int(s) testItem = None for item in cf.getInventory(): if item.tag == tag: testItem = item break if testItem is None: cf.fatal("Couldn't find item with tag %d" % tag) dropCmd = cf.getDropCommand(testItem) pickupCmd = cf.getPickupCommand(testItem) for i in range(20): # We set targetPendingCommands high enough that these will all dispatch # immediately. cf.queueCommand(dropCmd) cf.queueCommand(pickupCmd) cf.queueCommand("east") cf._sendToClient("sync 6") # Fall back to passthru.py. while 1: s = cf._readLineFromClient()
""" Create water of the wise by alchemy. Lower-tech version of the script, works by renaming the ingredient and using "drop 7 ingred1" rather than issuing true "move" commands. """ import sys from lib.client_interfacer import ClientInterfacer, Command from lib.recipe import runCommandSequence cf = ClientInterfacer() # Find the cauldron on the ground. itemsOn = cf.getItemsOfType("on") cauldrons = [] for item in itemsOn: if item.name == "cauldron": cauldrons.append(item) if len(cauldrons) != 1: cf.logError("Expected 1 cauldron on ground, got %d" % len(cauldrons)) sys.exit(0) cauldron = cauldrons[0] # Find the largest pile of waters in the player's inventory. waters = None inv = cf.getInventory() for item in inv: if item.name.endswith(" water") or item.name.endswith(" waters"): if waters is None or item.num > waters.num:
""" Test script, just to showcase/smoketest some of the simpler features of ClientInterfacer. Intentionally does the loop by hand, even though it's really another recipe.loopCommands script, because that's more in keeping with its purpose. """ from lib.client_interfacer import ClientInterfacer cf = ClientInterfacer() MAX_ITERS = 20 count = 0 done = False while not done: cf.issueCommand("north") cf.issueCommand("east") cf.issueCommand("south") cf.issueCommand("west") if cf.hasScripttell(): done = True cf.draw("Closing down; just need to wait for pending commands.") count += 1 if count > MAX_ITERS: # If there's a bug, try not to totally crash the client by flooding it # with too much stuff. cf.draw("Count maxed out; stopping.") done = True
def main(): cf = ClientInterfacer() loadoutData = readFile("loadout", getLoadoutFilename(cf), default=FILE_SKELETON) args = sys.argv[1:] if args[0] == "help": cf.draw("Usage: %s <cmd> <arguments>" % sys.argv[0]) cf.draw("Available commands:") cf.draw("- current show current loadout") cf.draw("- list list available loadouts") cf.draw("- show <name> show a loadout") # cf.draw("- set-stashable edit stashable items") # TODO cf.draw("- save <name> save current loadout") # cf.draw("- equip <name> equip specified loadout") # TODO elif len(args) == 1 and args[0] == "list": cf.draw("Available loadouts:") for name in sorted(loadoutData["loadouts"].keys()): cf.draw("- %s" % name) elif len(args) == 1 and args[0] == "current": currentLoadout = getCurrentLoadout(cf, loadoutData["stashable"]) cf.draw("Your current loadout is:") showLoadout(cf, currentLoadout) elif len(args) == 2 and args[0] == "show": name = args[1] if name in loadoutData["loadouts"]: loadout = loadoutData["loadouts"][name] cf.draw("Loadout %r consists of wearing:" % name) showLoadout(cf, loadout) else: cf.drawError("No such loadout %r" % name) elif len(args) == 1 and args[0] == "set-stashable": cf.fatal("Not implemented.") # TODO: Interactively edit stashable list elif len(args) == 2 and args[0] == "save": saveLoadout(cf, args[1], loadoutData) elif len(args) == 2 and args[0] == "equip": cf.fatal("Not implemented.") # TODO: Equip a loadout elif len(args) == 1: # Assume "equip". cf.fatal("Not implemented.") # TODO: Equip a loadout else: cf.fatal("Unable to parse command line. Try 'help'.")
""" Really basic test of the inventory subsystem. Request the player's inventory once, block until we get a full response, and then print it out. """ from lib.client_interfacer import ClientInterfacer, Color cf = ClientInterfacer() inv = cf.getInventory() # Probably already sorted by clientType, but just to be sure, re-sort it # ourselves. inv.sort(key=lambda x: x.clientType) for item in inv: name = item.name if item.locked: name += " *" if item.magical: name += " (magic)" if item.damned: name += " (damned)" elif item.cursed: name += " (cursed)" if item.unpaid: name += " (unpaid)" if item.applied: name += " (applied)" if item.open: name += " (open)"
from lib.client_interfacer import ClientInterfacer cf = ClientInterfacer() cf.watchStats() MIN_MED_PER_CAST = 4 while True: if cf.hasScripttell(): cf.draw("Exiting.") break if cf.playerInfo.sp >= 0.8 * cf.playerInfo.maxsp: cf.queueCommand("invoke charm monsters") cf.queueCommand("killpets") for i in range(MIN_MED_PER_CAST): cf.queueCommand("use_skill meditation") cf.issueQueuedCommands(maxQueueSize=max(MIN_MED_PER_CAST - 1, 0)) else: cf.issueCommand("use_skill meditation") cf.idle() cf.flushCommands()
""" Repeatedly drop and pick up a selected item, to show that the timing is reasonable. (Recommend running in DEBUG mode for a better test.) """ import sys from lib.client_interfacer import ClientInterfacer, Command from lib.recipe import runCommandSequence cf = ClientInterfacer() if len(sys.argv) != 2: cf.fatal("Usage: %s TAG" % sys.argv[0]) try: tag = int(sys.argv[1]) except: cf.fatal("%r: invalid tag (must be an integer)." % (sys.argv[1])) # Search inventory for matching tag. itemToMove = None inv = cf.getInventory() for item in inv: if item.tag == tag: itemToMove = item break if itemToMove is None: cf.fatal("Could not find item in inventory with tag %d." % (tag)) commands = [cf.getDropCommand(itemToMove),
Partial port of old/travel.py to the new ClientInterfacer API. Only supports walking between already-defined waypoints. For transitional use until I can create a real new travel.py. """ import glob import os import sys from lib.client_interfacer import ClientInterfacer # Use a deeper-than-usual pipeline for this one because we really want to walk # as fast as possible. cf = ClientInterfacer(targetPendingCommands=10) DIR = "data/travel" SERVER = "metalforge" def main(): if len(sys.argv) != 3: cf.draw("Usage: python %s SOURCE DEST" % sys.argv[0]) cf.draw("If there are spaces in the name of a city, replace them with " "underscores.") cf.draw("If there are underscores in the name, too bad.") return _, source, dest = sys.argv source = source.upper().replace("_", " ")
""" Convert any coins in player's inventory to at least platinum. Assumes you are standing somewhere in the Bank of Skud in Scorn. Hardcodes knowledge about the layout of that building. Also, assumes there's no one else there. """ from lib.client_interfacer import ClientInterfacer cf = ClientInterfacer() # Get to the northeast corner, so we don't have to examine the level to get our # bearings. for i in range(4): cf.issueCommand("north") for i in range(12): cf.issueCommand("east") # Silver to gold. cf.issueCommand("west") cf.issueCommand("west") cf.issueCommand("drop silver coin", count=0) cf.issueCommand("get coin", count=0) # Gold to platinum. cf.issueCommand("west") cf.issueCommand("west") cf.issueCommand("drop gold coin", count=0) cf.issueCommand("get coin", count=0)
""" Identify items using rods of identify. """ import re import sys from lib.client_interfacer import ClientInterfacer, Command from lib.recipe import loopCommands cf = ClientInterfacer() # To be safe, first unready any rod that may be readied. cf.execCommand("apply -u rod") # This regex is used to check which items are rods of identify. The expected # name is "Rod of Knowledge of identify (lvl 20)", but this should match # anything that's a rod of identify. identRodRE = re.compile(r"(heavy )?rod.* of identify \(.*", flags=re.IGNORECASE) # Now make a list of all the rods of identify in the player's inventory. identRods = [] inv = cf.getInventory() for item in inv: if identRodRE.match(item.name): if item.applied: cf.fatal("Item %r already applied." % item.name) identRods.append(item) commands = []
import time from lib.client_interfacer import ClientInterfacer cf = ClientInterfacer() for i in range(50 + 1): cf.draw("draw %s hello world" % i, color=i) # For some reason the script seems to hang if we send too many at once? time.sleep(0.1)
from lib.client_interfacer import ClientInterfacer, Color cf = ClientInterfacer() while 1: s = cf._readLineFromClient() cf.draw("recv: '%s'" % (s)) if s.startswith("scripttell "): rest = s[len("scripttell "):] cf.draw("send: %s" % (rest), color=Color.DARK_ORANGE) cf._sendToClient(rest)
""" Create water of the wise by alchemy. """ import sys from lib.client_interfacer import ClientInterfacer, Command from lib.recipe import runCommandSequence cf = ClientInterfacer() # Find the cauldron on the ground. itemsOn = cf.getItemsOfType("on") cauldrons = [] for item in itemsOn: if item.name == "cauldron": cauldrons.append(item) if len(cauldrons) != 1: cf.logError("Expected 1 cauldron on ground, got %d" % len(cauldrons)) sys.exit(0) cauldron = cauldrons[0] # Find the largest pile of waters in the player's inventory. waters = None inv = cf.getInventory() for item in inv: if item.name.endswith(" water") or item.name.endswith(" waters"): if waters is None or item.num > waters.num: waters = item if waters is None: cf.logError("You don't have any water.")
from lib.client_interfacer import ClientInterfacer cf = ClientInterfacer() cf._sendToClient("watch comc") while 1: s = cf._readLineFromClient() if s.startswith("scripttell"): break cf._sendToConsole(s)
""" Dead-simple proof of concept that I can watch the player's stats. Sits idle until the player's hunger runs below 200, then summons and eats a waybread. Useful to leave running while afk. """ from lib.client_interfacer import ClientInterfacer cf = ClientInterfacer() cf.watchStats() while True: if cf.hasScripttell(): cf.draw("Exiting.") break if cf.playerInfo.food < 200: cf.issueCommand("cast create food waybread") cf.issueCommand("stay fire") cf.issueCommand("get waybread", count=0) # NOTE: This isn't quite right. If the player is carrying some special # sort of waybread, then we'll eat it, which is probably not what they # want. But it's the best we can do for now, since (as of when this # script was written) we don't support examining the player's # inventory. cf.issueCommand("apply waybread") cf.flushCommands() cf.idle() # Shouldn't matter, but good practice. cf.flushCommands()