ソースを参照

Working inputs, values stored. No hidden crashes.

Steve Thielemann 5 年 前
コミット
ffb0d03abf
1 ファイル変更149 行追加6 行削除
  1. 149 6
      tcp-proxy.py

+ 149 - 6
tcp-proxy.py

@@ -70,6 +70,8 @@ def cleanANSI(line):
     return cleaner.sub("", line)
     # return re.sub(r'\x1b\[([0-9,A-Z]{1,2}(;[0-9]{1,2})?(;[0-9]{3})?)?[m|K]?', '', line)
 
+PORT_CLASSES = { 1: 'BBS', 2: 'BSB', 3: 'SBB', 4:'SSB', 5:'SBS', 6:'BSS', 7:'SSS', 8:'BBB'}
+CLASSES_PORT = { v: k for k,v in PORT_CLASSES.items() }
 
 class Observer(object):
     def __init__(self):
@@ -100,14 +102,22 @@ class Observer(object):
             if len(self.dispatch[signal]) == 0:
                 self.dispatch.pop(signal)
 
-    def get_funcs(self, signal):
+    def get_funcs(self):
+        """ Gives a copy of the dispatch. """
+        return dict(self.dispatch)
+
+    def set_funcs(self, dispatch):
+        """ Replaces the dispatch. """
+        self.dispatch = dict(dispatch)
+
+    def get_funcs_(self, signal):
         """ Gives a copy of the dispatch for a given signal. """
         if signal in self.dispatch:
             return list(self.dispatch[signal])
         else:
             return []
 
-    def set_funcs(self, signal, funcs):
+    def set_funcs_(self, signal, funcs):
         """ Replaces the dispatch for a given signal. """
         if signal in self.dispatch:
             if len(funcs) == 0:
@@ -188,6 +198,7 @@ class MCP(object):
             " " + c1 + "T" + c2 + " - " + c1 + "Display current Time" + nl
         )
         self.queue_game.put(" " + c1 + "P" + c2 + " - " + c1 + "Port CIM Report" + nl)
+        self.queue_game.put(" " + c1 + "S" + c2 + " - " + c1 + "Scripts" + nl)
         self.queue_game.put(" " + c1 + "X" + c2 + " - " + c1 + "eXit" + nl)
         self.queue_game.put("   " + c + "-=>" + r + " ")
 
@@ -217,6 +228,11 @@ class MCP(object):
             # self.queue_game.put(nl + c + "NO, NOT YET!" + r + nl)
             # self.displayMenu()
 
+        elif key == "S":
+            log.msg("Scripts")
+            self.queue_game.put(c + key + r + nl)
+            self.scripts()
+
         elif key == 'D':
             self.queue_game.put(nl + "Diagnostics" + nl + "portdata:" + nl + repr(self.portdata) + nl)
             self.displayMenu()
@@ -280,7 +296,7 @@ class MCP(object):
         if line == ': ENDINTERROG':
             log.msg("CIM Done")
             log.msg(self.portdata)
-            self.queue_game.put("\x08 \x08" + "\n\r")
+            self.queue_game.put("\b \b" + "\n\r")
             self.observer.disconnect('prompt', self.portPrompt)
             self.observer.disconnect('game-line', self.portParse)
             self.game.to_player = True
@@ -292,7 +308,7 @@ class MCP(object):
         # Give some sort of feedback to the user.
         if self.portcycle:
             if len(self.portdata) % 10 == 0:
-                self.queue_game.put("\x08" + next(self.portcycle))
+                self.queue_game.put("\b" + next(self.portcycle))
 
         # Ok, we need to parse this line
         # 436   2870 100% - 1520 100% - 2820 100%
@@ -329,12 +345,139 @@ class MCP(object):
             data['equ'] = dict( )
             data['equ']['sale'], data['equ']['units'] = self.portBS(parts[5])
             data['equ']['pct'] = int(parts[6].strip())
+            # Store what this port is buying/selling
+            data['port'] = data['fuel']['sale'] + data['org']['sale'] + data['equ']['sale']
+            # Convert BBS/SBB to Class number 1-8
+            data['class'] = CLASSES_PORT[data['port']]
             self.portdata[port] = data
         else:
             self.queue_game.put("?")
             log.msg("Line in question is: [{0}].".format(line))
             log.msg(repr(parts))
 
+    def scripts(self):
+        self.scripts = dict()
+
+        self.observer.disconnect("player", self.fromPlayer)
+        self.observer.connect("player", self.scriptFromPlayer)
+        self.observer.connect('game-line', self.scriptLine)
+
+        nl = "\n\r"
+        c = merge(Style.BRIGHT + Fore.WHITE + Back.BLUE)
+        r = Style.RESET_ALL
+        c1 = merge(Style.BRIGHT + Fore.CYAN)
+        c2 = merge(Style.NORMAL + Fore.CYAN)
+
+        self.queue_game.put(nl + c + "TradeWars Proxy Script(s)" + r + nl)
+        self.queue_game.put(" " + c1 + "P" + c2 + " - " + c1 + "Port Trading Pair" + nl)
+        self.queue_game.put("   " + c + "-=>" + r + " ")
+
+    def scriptLine(self, line):
+        pass
+
+    def scriptFromPlayer(self, chunk):
+        """ Data from player (in bytes).  """
+        chunk = chunk.decode("utf-8", "ignore")
+
+        nl = "\n\r"
+        c = merge(Style.BRIGHT + Fore.WHITE + Back.BLUE)
+        r = Style.RESET_ALL
+
+        key = chunk.upper()
+        if key == 'Q':
+            self.queue_game.put(c + key + r + nl)
+            self.observer.connect("player", self.fromPlayer)
+            self.observer.disconnect("player", self.scriptFromPlayer)
+            self.observer.disconnect('game-line', self.scriptLine)            
+            self.observer.connect('game-line', self.portParse)            
+            self.displayMenu()
+        elif key == 'P':
+            self.queue_game.put(c + key + r + nl)
+            d = self.playerInput("Enter sector to trade to: ", 6)
+            d.addCallback(self.save_sector)
+
+    def save_sector(self, sector):
+        log.msg("save_sector {0}".format(sector))
+        log.msg( self.observer.dispatch)        
+        s = int(sector.strip())
+        self.scripts['sector'] = s
+        d = self.playerInput("Enter times to execute script: ", 6)
+        d.addCallback(self.save_loop)
+
+    def save_loop(self, loop):
+        log.msg("save_loop {0}".format(loop))        
+        log.msg( self.observer.dispatch)        
+        l = int(loop.strip())
+        self.scripts['loop'] = l
+        d = self.playerInput("Enter markup/markdown percentage: ", 3)
+        d.addCallback(self.save_mark)
+
+    def save_mark(self, mark):
+        log.msg("save_mark {0}".format(mark))                
+        if mark.strip() == "":
+            self.scripts['mark'] = 5
+        else:
+            self.scripts['mark'] = int(mark.strip())
+        self.queue_game.put(repr(self.scripts) +"\n\r")
+
+    def playerInput(self, prompt, limit):
+        log.msg("playerInput({0}, {1}".format(prompt, limit))
+        log.msg( self.observer.dispatch) 
+
+        nl = "\n\r"
+        c = merge(Style.BRIGHT + Fore.WHITE + Back.BLUE)
+        r = Style.RESET_ALL
+        self.queue_game.put(r + nl + c + prompt)
+        d = defer.Deferred()
+        self.player_input = d
+        self.input_limit = limit
+        self.input_input = ''
+        self.save = self.observer.get_funcs()
+        input_funcs = { 'player': [self.niceInput] }
+        self.observer.set_funcs(input_funcs)
+        log.msg( self.observer.dispatch)         
+        return d
+
+    def niceInput(self, chunk):
+        """ Data from player (in bytes).  """
+        chunk = chunk.decode("utf-8", "ignore")
+        log.msg("niceInput:", repr(chunk))
+        r = Style.RESET_ALL
+
+        for c in chunk:
+            if c == '\b':
+                # Backspace
+                if len(self.input_input) > 1:
+                    self.queue_game.put("\b \b")
+                    self.input_input = self.input_input[0:-1]
+                else:
+                    # Can't
+                    self.queue_game.put("\a")
+
+            if c == "\r":
+                # Ok, completed!
+                self.queue_game.put(r + "\n\r")
+                self.observer.set_funcs(self.save)
+                self.save = None
+                line = self.input_input
+                log.msg("finishing niceInput {0}".format(line))
+                self.queue_game.put("[{0}]\n\r".format(line))
+                self.input_input = ''
+                # Ok, maybe this isn't the way to do this ...
+                # self.player_input.callback(line)
+                reactor.callLater(0, self.player_input.callback, line)                
+                log.msg("callback({0})".format(line))
+                # Maybe I don't want to do this?
+                self.player_input = None
+
+            if c.isprintable():
+                if len(self.input_input) + 1 <= self.input_limit:
+                    self.input_input += c
+                    self.queue_game.put(c)
+                else:
+                    # Limit reached
+                    self.queue_game.put("\a")
+
 class Game(protocol.Protocol):
     def __init__(self):
         self.buffer = ""
@@ -434,8 +577,8 @@ class Game(protocol.Protocol):
         self.buffer += chunk.decode("utf-8", "ignore")
 
         # Process any backspaces
-        while "\x08" in self.buffer:
-            part = self.buffer.partition("\x08")
+        while "\b" in self.buffer:
+            part = self.buffer.partition("\b")
             self.buffer = part[0][:-1] + part[2]
 
         # Treat some ANSI codes as a newline