Bläddra i källkod

Working proxy activation.

Steve Thielemann 5 år sedan
förälder
incheckning
eff209a3dc
2 ändrade filer med 112 tillägg och 12 borttagningar
  1. 1 1
      config_dev.py
  2. 111 11
      tcp-proxy.py

+ 1 - 1
config_dev.py

@@ -9,5 +9,5 @@ LISTEN_ON = "127.0.0.1"
 RAW = True
 LOGFILE = False
 
-LOGFILE = True
+# LOGFILE = True
 LOG_LINES = True

+ 111 - 11
tcp-proxy.py

@@ -6,6 +6,7 @@ import re
 from twisted.internet import defer
 from twisted.internet import protocol
 from twisted.internet import reactor
+from twisted.internet import task
 from twisted.python import log
 from twisted.python.logfile import DailyLogFile
 import pendulum
@@ -115,11 +116,106 @@ class Observer(object):
                 self.dispatch = list(funcs)
 
 
+class MCP(object):
+    def __init__(self, game):
+        self.game = game
+        self.queue_game = None
+        # we don't have this .. yet!
+        self.prompt = None
+        self.observer = None
+        self.keepalive = None
+
+    def finishSetup(self):
+        if self.queue_game is None:
+            self.queue_game = self.game.queue_game
+        if self.observer is None:
+            self.observer = self.game.observer
+        self.observer.connect("hotkey", self.activate)
+
+    def stayAwake(self):
+        """ Send a space to the game to keep it alive/don't timeout. """
+        log.msg("Gameserver, stay awake.")
+        self.game.queue_player.put(" ")
+
+    def activate(self, _):
+        log.msg("MCP menu called.")
+        # We want the raw one, not the ANSI cleaned getPrompt.
+        prompt = self.game.buffer
+        if not self.prompt is None:
+            # silly, we're already active
+            log.msg("I think we're already active.  Ignoring request.")
+            return
+        # Or will the caller setup/restore the prompt?
+        self.prompt = prompt
+        # queue_game = to player
+        self.displayMenu()
+        self.observer.connect("player", self.fromPlayer)
+        # TODO:  Add background "keepalive" event so the game doesn't time out on us.
+        self.keepalive = task.LoopingCall(self.stayAwake)
+        self.keepalive.start(30)
+
+    def displayMenu(self):
+        nl = "\n\r"
+        c = merge(Style.BRIGHT + Fore.YELLOW + Back.BLUE)
+        r = Style.RESET_ALL
+        c1 = merge(Style.BRIGHT + Fore.BLUE)
+        c2 = merge(Style.NORMAL + Fore.BLUE)
+
+        self.queue_game.put(nl + c + "TradeWars Proxy active." + r + nl)
+        self.queue_game.put(
+            " " + 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 + "X" + c2 + " - " + c1 + "eXit" + nl)
+        self.queue_game.put("   " + c + "-=>" + r + " ")
+
+    def fromPlayer(self, chunk):
+        """ Data from player (in bytes).  """
+        chunk = chunk.decode("utf-8", "ignore")
+
+        nl = "\n\r"
+        c = merge(Style.BRIGHT + Fore.YELLOW + Back.BLUE)
+        r = Style.RESET_ALL
+        c1 = merge(Style.BRIGHT + Fore.BLUE)
+        c2 = merge(Style.NORMAL + Fore.BLUE)
+
+        key = chunk.upper()
+        if key == "T":
+            self.queue_game.put(c + key + r + nl)
+            now = pendulum.now()
+            log.msg("Time")
+            self.queue_game.put(
+                nl + c1 + "It is currently " + now.to_datetime_string() + "." + nl
+            )
+            self.displayMenu()
+        elif key == "P":
+            log.msg("Port")
+            self.queue_game.put(c + key + r + nl)
+            self.queue_game.put(nl + c + "NO, NOT YET!" + r + nl)
+            self.displayMenu()
+        elif key == "X":
+            log.msg('"Quit, return to "normal".  (Whatever that means!)')
+            self.queue_game.put(c + key + r + nl)
+            self.observer.disconnect("player", self.fromPlayer)
+            self.queue_game.put(nl + c1 + "Returning to game" + c2 + "..." + r + nl)
+            self.queue_game.put(self.prompt)
+            self.prompt = None
+            self.keepalive.stop()
+            self.keepalive = None
+        else:
+            if key.isprintable():
+                self.queue_game.put(r + nl)
+                self.queue_game.put("Excuse me? I don't understand '" + key + "'." + nl)
+                self.displayMenu()
+
+
 class Game(protocol.Protocol):
     def __init__(self):
         self.buffer = ""
         self.game = None
+        self.usergame = (None, None)
         self.to_player = True
+        self.mcp = MCP(self)
 
     def connectionMade(self):
         log.msg("Connected to Game Server")
@@ -127,18 +223,11 @@ class Game(protocol.Protocol):
         self.queue_game = self.factory.queue_game
         self.observer = self.factory.observer
         self.setPlayerReceived()
-        self.observer.connect("user", self.show_user)
         self.observer.connect("user-game", self.show_game)
-
-    def show_user(self, user):
-        """ This doesn't always show up.  :P
-
-        Because we're still connecting to the game server when
-        the player object has already sent the 'user' signal.
-        """
-        log.msg("## User:", user)
+        self.mcp.finishSetup()
 
     def show_game(self, game):
+        self.usergame = game
         log.msg("## User-Game:", game)
 
     def setPlayerReceived(self):
@@ -154,7 +243,10 @@ class Game(protocol.Protocol):
             self.transport.loseConnection()
         else:
             # Pass received data to the server
-            self.transport.write(chunk)
+            if type(chunk) == str:
+                self.transport.write(chunk.encode())
+            else:
+                self.transport.write(chunk)
             self.setPlayerReceived()
 
     def lineReceived(self, line):
@@ -185,6 +277,10 @@ class Game(protocol.Protocol):
 
         self.observer.emit("game-line", line)
 
+    def getPrompt(self):
+        """ Return the current prompt, stripped of ANSI. """
+        return cleanANSI(self.buffer)
+
     def dataReceived(self, chunk):
         """ Data received from the Game. 
         
@@ -227,7 +323,7 @@ class Game(protocol.Protocol):
             self.lineReceived(line)
             self.buffer = part[2]
 
-        self.observer.emit("prompt", cleanANSI(self.buffer))
+        self.observer.emit("prompt", self.getPrompt())
 
     def connectionLost(self, why):
         log.msg("Game connectionLost because: %s" % why)
@@ -323,11 +419,15 @@ class Player(protocol.Protocol):
                 self.buffer = ""
                 # Pass user value on to whatever needs it.
                 self.observer.emit("user", self.user)
+                # Unfortunately, the ones interested in this don't exist yet.
 
         if not self.observer.emit("player", chunk):
             # Was not dispatched.  Send to game.
             self.queue_player.put(chunk)
 
+        if chunk == b"~":
+            self.observer.emit("hotkey", None)
+
     def connectionLost(self, why):
         log.msg("lost connection %s" % why)
         self.queue_player.put(False)