|
@@ -15,6 +15,45 @@ def merge(color_string):
|
|
|
|
|
|
|
|
|
class PlayerInput(object):
|
|
|
+ """ Player Input
|
|
|
+
|
|
|
+ Example:
|
|
|
+ from flexible import PlayerInput
|
|
|
+
|
|
|
+ ask = PlayerInput(self.game)
|
|
|
+ # abort_blank means, if the input field is blank, abort. Use error_back.
|
|
|
+ d = ask.prompt("What is your quest?", 40, name="quest", abort_blank=True)
|
|
|
+
|
|
|
+ # Display the user's input / but not needed.
|
|
|
+ d.addCallback(ask.output)
|
|
|
+
|
|
|
+ d.addCallback(
|
|
|
+ lambda ignore: ask.prompt(
|
|
|
+ "What is your favorite color?", 10, name="color"
|
|
|
+ )
|
|
|
+ )
|
|
|
+ d.addCallback(ask.output)
|
|
|
+
|
|
|
+ d.addCallback(
|
|
|
+ lambda ignore: ask.prompt(
|
|
|
+ "What is your least favorite number?",
|
|
|
+ 12,
|
|
|
+ name="number",
|
|
|
+ digits=True,
|
|
|
+ )
|
|
|
+ )
|
|
|
+ d.addCallback(ask.output)
|
|
|
+
|
|
|
+ def show_values(show):
|
|
|
+ log.msg(show)
|
|
|
+ self.queue_game.put(pformat(show).replace("\n", "\n\r") + self.nl)
|
|
|
+
|
|
|
+ d.addCallback(lambda ignore: show_values(ask.keep))
|
|
|
+ d.addCallback(self.welcome_back)
|
|
|
+
|
|
|
+ # On error, just return back
|
|
|
+ d.addErrback(self.welcome_back)
|
|
|
+ """
|
|
|
def __init__(self, game):
|
|
|
# I think game gives us access to everything we need
|
|
|
self.game = game
|
|
@@ -48,6 +87,8 @@ class PlayerInput(object):
|
|
|
def prompt(self, user_prompt, limit, **kw):
|
|
|
""" Generate prompt for user input.
|
|
|
|
|
|
+ Note: This returns deferred.
|
|
|
+
|
|
|
prompt = text displayed.
|
|
|
limit = # of characters allowed.
|
|
|
default = (text to default to)
|
|
@@ -168,6 +209,25 @@ import re
|
|
|
|
|
|
|
|
|
class CIMPortReport(object):
|
|
|
+ """ Parse data from CIM Port Report
|
|
|
+
|
|
|
+ Example:
|
|
|
+
|
|
|
+ from flexible import CIMPortReport
|
|
|
+
|
|
|
+ report = CIMPortReport(self.game)
|
|
|
+ d = report.whenDone()
|
|
|
+ d.addCallback(self.port_report)
|
|
|
+ d.addErrback(self.welcome_back)
|
|
|
+
|
|
|
+ def port_report(self, portdata):
|
|
|
+ self.portdata = portdata
|
|
|
+ self.queue_game.put("Loaded {0} records.".format(len(portdata)) + self.nl)
|
|
|
+ self.welcome_back()
|
|
|
+
|
|
|
+ def welcome_back(self,*_):
|
|
|
+ ... restore keep alive timers, etc.
|
|
|
+ """
|
|
|
def __init__(self, game):
|
|
|
self.game = game
|
|
|
self.queue_game = game.queue_game
|
|
@@ -203,7 +263,7 @@ class CIMPortReport(object):
|
|
|
self.portcycle = cycle(["/", "-", "\\", "|"])
|
|
|
self.queue_player.put("R")
|
|
|
self.state = 2
|
|
|
- if self.state == 2:
|
|
|
+ elif self.state == 2:
|
|
|
self.queue_player.put("Q")
|
|
|
self.state = 3
|
|
|
if re.match(r"Command \[TL=.* \(\?=Help\)\? :", prompt):
|
|
@@ -299,8 +359,137 @@ class CIMPortReport(object):
|
|
|
self.game.to_player = self.to_player
|
|
|
self.observer.load(self.save)
|
|
|
|
|
|
+class ScriptPort(object):
|
|
|
+ """ Performs the Port script. """
|
|
|
+ def __init__(self, game):
|
|
|
+ self.game = game
|
|
|
+ self.queue_game = game.queue_game
|
|
|
+ self.queue_player = game.queue_player
|
|
|
+ self.observer = game.observer
|
|
|
+ self.r = Style.RESET_ALL
|
|
|
+ self.nl = "\n\r"
|
|
|
+
|
|
|
+ # Activate
|
|
|
+ self.prompt = game.buffer
|
|
|
+ self.save = self.observer.save()
|
|
|
+ self.observer.connect('player', self.player)
|
|
|
+ self.observer.connect("prompt", self.game_prompt)
|
|
|
+ self.observer.connect("game-line", self.game_line)
|
|
|
+
|
|
|
+ self.defer = None
|
|
|
+ self.queue_game.put(
|
|
|
+ self.nl + "Script based on: Port Pair Trading v2.00" + self.r + self.nl
|
|
|
+ )
|
|
|
+
|
|
|
+ self.sector_number = None
|
|
|
+ self.possible_sectors = None
|
|
|
+
|
|
|
+ self.state = 1
|
|
|
+ self.queue_player.put("D")
|
|
|
+ # Original, send 'D' to display current sector.
|
|
|
+ # We could get the sector number from the self.prompt string -- HOWEVER:
|
|
|
+ # IF! We send 'D', we can also get the sectors around -- we might not even need to
|
|
|
+ # prompt for sector to trade with (we could possibly figure it out ourselves).
|
|
|
+ # [Command [TL=00:00:00]:[967] (?=Help)? : D]
|
|
|
+ # [<Re-Display>]
|
|
|
+ # []
|
|
|
+ # [Sector : 967 in uncharted space.]
|
|
|
+ # [Planets : (M) Into the Darkness]
|
|
|
+ # [Warps to Sector(s) : 397 - (562) - (639)]
|
|
|
+ # []
|
|
|
+
|
|
|
+ def whenDone(self):
|
|
|
+ self.defer = defer.Deferred()
|
|
|
+ # Call this to chain something after we exit.
|
|
|
+ return self.defer
|
|
|
+
|
|
|
+ def deactivate(self):
|
|
|
+ log.msg("ScriptPort.deactivate")
|
|
|
+ assert(not self.save is None)
|
|
|
+ self.observer.load(self.save)
|
|
|
+ self.save = None
|
|
|
+ if self.defer:
|
|
|
+ self.defer.callback('done')
|
|
|
+ self.defer = None
|
|
|
+
|
|
|
+ def player(self, chunk: bytes):
|
|
|
+ pass
|
|
|
+
|
|
|
+ def game_prompt(self, prompt: str):
|
|
|
+ log.msg("{0} : {1}".format(self.state, prompt))
|
|
|
+ if self.state == 3:
|
|
|
+ log.msg("game_prompt: ", prompt)
|
|
|
+ if re.match(r"Command \[TL=.* \(\?=Help\)\? :", prompt):
|
|
|
+ self.state = 4
|
|
|
+ log.msg("Ok, state 4")
|
|
|
+ self.deactivate()
|
|
|
+
|
|
|
+
|
|
|
+ def game_line(self, line: str):
|
|
|
+ if self.state == 1:
|
|
|
+ # First exploration
|
|
|
+ if line.startswith("Sector :"):
|
|
|
+ # We have starting sector information
|
|
|
+ parts = re.split("\s+", line)
|
|
|
+ self.sector_number = int(parts[2])
|
|
|
+ # These will be the ones swapped around as we trade back and forth.
|
|
|
+ self.sector1 = self.sector_number
|
|
|
+ elif line.startswith("Warps to Sector(s) : "):
|
|
|
+ # Warps to Sector(s) : 397 - (562) - (639)
|
|
|
+ _, _, warps = line.partition(':')
|
|
|
+ warps = warps.replace('-', '').replace('(', '').replace(')', '').strip()
|
|
|
+ log.msg("Warps: [{0}]".format(warps))
|
|
|
+ self.warps = [ int(x) for x in re.split("\s+", warps)]
|
|
|
+ log.msg("Warps: [{0}]".format(self.warps))
|
|
|
+ self.state = 2
|
|
|
+ elif self.state == 2:
|
|
|
+ if line == "":
|
|
|
+ # Ok, we're done
|
|
|
+ self.state = 3
|
|
|
+ # Check to see if we have information on any possible ports
|
|
|
+ if hasattr(self.game, 'portdata'):
|
|
|
+ if not self.sector_number in self.game.portdata:
|
|
|
+ log.msg("Current sector {0} not in portdata.".format(self.sector_number))
|
|
|
+ self.queue_game.put(self.r + self.nl + "I can't find the current sector in the portdata." + self.nl)
|
|
|
+ self.deactivate()
|
|
|
+ return
|
|
|
+ possible = [ x for x in self.warps if x in self.game.portdata]
|
|
|
+ log.msg("Possible:", possible)
|
|
|
+ self.possible = possible
|
|
|
+ if len(possible) == 0:
|
|
|
+ self.queue_game.put(self.r + self.nl + "I don't see any ports in [{0}].".format(self.warps) + self.nl)
|
|
|
+ self.deactivate()
|
|
|
+ return
|
|
|
+ elif len(possible) == 1:
|
|
|
+ # Ok! there's only one!
|
|
|
+ self.sector1 = possible[0]
|
|
|
+
|
|
|
+ # Display possible ports:
|
|
|
+ # spos = [ str(x) for x in possible]
|
|
|
+ # self.queue_game.put(self.r + self.nl + self.nl.join(spos) + self.nl)
|
|
|
+ # At state 3, we only get a prompt.
|
|
|
+ return
|
|
|
+ else:
|
|
|
+ log.msg("We don't have any portdata!")
|
|
|
+ self.queue_game.put(self.r + self.nl + "I have no portdata. Please run CIM Port Report." + self.nl)
|
|
|
+ self.deactivate()
|
|
|
+ return
|
|
|
+ # elif self.state == 3:
|
|
|
+ # log.msg("At state 3 [{0}]".format(line))
|
|
|
+ # self.queue_game.put("At state 3.")
|
|
|
+ # self.deactivate()
|
|
|
+ # return
|
|
|
|
|
|
class ProxyMenu(object):
|
|
|
+ """ Display ProxyMenu
|
|
|
+
|
|
|
+ Example:
|
|
|
+
|
|
|
+ from flexible import ProxyMenu
|
|
|
+
|
|
|
+ if re.match(r"Command \[TL=.* \(\?=Help\)\? :", prompt):
|
|
|
+ menu = ProxyMenu(self.game)
|
|
|
+ """
|
|
|
def __init__(self, game):
|
|
|
self.nl = "\n\r"
|
|
|
self.c = merge(Style.BRIGHT + Fore.YELLOW + Back.BLUE)
|
|
@@ -342,7 +531,7 @@ class ProxyMenu(object):
|
|
|
self.nl + self.c + "TradeWars Proxy active." + self.r + self.nl
|
|
|
)
|
|
|
|
|
|
- def menu_item(ch, desc):
|
|
|
+ def menu_item(ch: str, desc: str):
|
|
|
self.queue_game.put(
|
|
|
" " + self.c1 + ch + self.c2 + " - " + self.c1 + desc + self.nl
|
|
|
)
|
|
@@ -359,12 +548,12 @@ class ProxyMenu(object):
|
|
|
log.msg("ProxyMenu.awake()")
|
|
|
self.game.queue_player.put(" ")
|
|
|
|
|
|
- def port_report(self, portdata):
|
|
|
+ def port_report(self, portdata: dict):
|
|
|
self.portdata = portdata
|
|
|
self.queue_game.put("Loaded {0} records.".format(len(portdata)) + self.nl)
|
|
|
self.welcome_back()
|
|
|
|
|
|
- def player(self, chunk):
|
|
|
+ def player(self, chunk: bytes):
|
|
|
""" Data from player (in bytes). """
|
|
|
chunk = chunk.decode("utf-8", "ignore")
|
|
|
key = chunk.upper()
|
|
@@ -391,7 +580,8 @@ class ProxyMenu(object):
|
|
|
return
|
|
|
elif key == "S":
|
|
|
self.queue_game.put(self.c + key + self.r + self.nl)
|
|
|
-
|
|
|
+ self.activate_scripts_menu()
|
|
|
+ return
|
|
|
elif key == "D":
|
|
|
self.queue_game.put(self.c + key + self.r + self.nl)
|
|
|
self.queue_game.put(pformat(self.portdata).replace("\n", "\n\r") + self.nl)
|
|
@@ -459,6 +649,53 @@ class ProxyMenu(object):
|
|
|
self.keepalive.start(30, True)
|
|
|
self.menu()
|
|
|
|
|
|
+ def activate_scripts_menu(self):
|
|
|
+ self.observer.disconnect("player", self.player)
|
|
|
+ self.observer.connect("player", self.scripts_player)
|
|
|
+ self.scripts_menu()
|
|
|
+
|
|
|
+ def deactivate_scripts_menu(self):
|
|
|
+ self.observer.disconnect("player", self.scripts_player)
|
|
|
+ self.observer.connect("player", self.player)
|
|
|
+ self.welcome_back()
|
|
|
+
|
|
|
+ def scripts_menu(self, *_):
|
|
|
+ c1 = merge(Style.BRIGHT + Fore.CYAN)
|
|
|
+ c2 = merge(Style.NORMAL + Fore.CYAN)
|
|
|
+
|
|
|
+ def menu_item(ch, desc):
|
|
|
+ self.queue_game.put(
|
|
|
+ " " + c1 + ch + c2 + " - " + c1 + desc + self.nl
|
|
|
+ )
|
|
|
+
|
|
|
+ menu_item("1", "Ports (Trades between two sectors)")
|
|
|
+ menu_item("2", "TODO")
|
|
|
+ menu_item("3", "TODO")
|
|
|
+ menu_item("X", "eXit")
|
|
|
+ self.queue_game.put(" " + c1 + "-=>" + self.r + " ")
|
|
|
+
|
|
|
+ def scripts_player(self, chunk: bytes):
|
|
|
+ """ Data from player (in bytes). """
|
|
|
+ chunk = chunk.decode("utf-8", "ignore")
|
|
|
+ key = chunk.upper()
|
|
|
+
|
|
|
+ if key == '1':
|
|
|
+ self.queue_game.put(self.c + key + self.r + self.nl)
|
|
|
+ # Activate this magical event here
|
|
|
+ ports = ScriptPort(self.game)
|
|
|
+ d = ports.whenDone()
|
|
|
+ d.addCallback(self.scripts_menu)
|
|
|
+ d.addErrback(self.scripts_menu)
|
|
|
+ return
|
|
|
+ elif key == 'X':
|
|
|
+ self.queue_game.put(self.c + key + self.r + self.nl)
|
|
|
+ self.deactivate_scripts_menu()
|
|
|
+ return
|
|
|
+ else:
|
|
|
+ self.queue_game.put(self.c + "?" + self.r + self.nl)
|
|
|
+ self.scripts_menu()
|
|
|
+
|
|
|
+
|
|
|
def welcome_back(self, *_):
|
|
|
log.msg("welcome_back")
|
|
|
self.keepalive.start(30, True)
|