瀏覽代碼

Merge branch 'master' of ssh://gitredgreen/RedGreen/twgs-proxy

Steve Thielemann 5 年之前
父節點
當前提交
6de3bccd6b
共有 2 個文件被更改,包括 267 次插入9 次删除
  1. 249 6
      flexible.py
  2. 18 3
      galaxy.py

+ 249 - 6
flexible.py

@@ -2996,7 +2996,7 @@ class ColoScript2(object):
                 self.TO = 1
                 self.planet_name = "Terra"
                 ask1 = PlayerInput(self.game)
-                d1 = ask1.prompt("From: (1 = Terra) ", 3, name="from", digits=True)
+                d1 = ask1.prompt("From: ", 3, name="from", digits=True)
                 d1.addCallback(self.from_chosen)
             elif self.to_number in self.planets:
                 # Ok, this'll work
@@ -3005,7 +3005,7 @@ class ColoScript2(object):
                 # Are we really getting this? Yup
                 # log.debug("TO Planet Number: {0} Sector: {1}".format(self.to_number, self.TO))
                 ask1 = PlayerInput(self.game)
-                d1 = ask1.prompt("From: (1 = Terra) ", 3, name="from", digits=True)
+                d1 = ask1.prompt("From: ", 3, name="from", digits=True)
                 d1.addCallback(self.from_chosen)
             else:
                 self.deactivate(True)
@@ -3122,6 +3122,13 @@ class ColoScript2(object):
                 )
                 self.queue_game.put(box.row(row))
 
+            # Manually add in Terra so a player knows about it,
+            # Since we now support Terra being TO or FROM.
+            terra = row = "{0}{1:^3} {2:6} {3}{4:29} {0}{5:2} ".format(
+                c1, 1, 1, c2, "Terra", " "
+            )
+            self.send2player(box.row(terra))
+
             for s in sorted(self.planets.keys()):
                 planet_output(
                     s,
@@ -3131,7 +3138,6 @@ class ColoScript2(object):
                 )
 
             self.queue_game.put(box.bottom())
-
             ask = PlayerInput(self.game)
             d = ask.prompt("To: ", 3, name="planet", digits=True)
             d.addCallback(self.to_chosen)
@@ -4332,6 +4338,218 @@ class evilTrade(object):
                     self.state = 4
 
 
+class bustViewer(object):
+    """ Display all busts
+
+        Perhaps also add it so we can manually reset/clear busts?
+        Or maybe...
+        We make galaxy's maint_busts() configurable so the check in days is in the config
+
+        States:
+        0 = Perform convertion of self.game.gamedata.busts into a more understandable format.
+        1 = Display/List all busts perferably just their sector numbers and when (what date) did that occur.
+        
+        Optionals:
+        1. Give numbering to state 0 so you can select a specific bust to be perhaps removed and/or add a remove all option.
+           (Dangerous, might not want to allow someone to manually reset all that)
+        2. Add math that calculates the age in days for that particular bust. (Then add this to state 1 Display/List)
+           (Ok well this one should be really easy make a string/tuple storing month/day/year for both now and the bust then,)
+           (compare them one by one against eachother if 0 we know it's not that category) <- Should always be days since we are clearing them out automatically
+    """
+
+    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.c = merge(Style.BRIGHT + Fore.YELLOW)
+        self.nl = "\n\r"
+
+        # Stuff
+        self.busted = {}  # Make custom bust dict based on self.game.gamedata.busts dict
+        self.age = {}
+        self.state = 0  # Display/List
+
+        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.to_player = self.game.to_player
+        self.game.to_player = False
+        self.send2game("D")  # Since we need to send at least 1 character
+
+    def whenDone(self):
+        self.defer = defer.Deferred()
+        return self.defer
+
+    def deactivate(self, andExit=False):
+        self.state = 0
+        log.debug("bustViewer.deactivate()")
+        self.game.to_player = True
+        assert not self.save is None
+        self.observer.load(self.save)
+        self.save = None
+        if self.defer:
+            if andExit:
+                self.defer.callback({"exit": True})
+            else:
+                self.defer.callback("done")
+            self.defer = None
+
+    def player(self, chunk: bytes):
+        self.deactivate(True)
+
+    def send2game(self, txt):
+        self.queue_player.put(txt)
+
+    def send2player(self, txt):
+        self.queue_game.put(txt)
+
+    def calcAge(self, dt):
+        rightNow = pendulum.now()
+        result = rightNow.diff(dt).in_days()
+        log.debug("calcAge('{0}') got {1} days".format(dt.to_datetime_string(), result))
+        return result
+
+    def game_prompt(self, prompt: str):
+        log.debug("P {0} | {1}".format(self.state, prompt))
+        if self.state == 0:
+            # Convert from YYYY-MM-DD to MM-DD-YYYY
+            for s in self.game.gamedata.busts:
+                d = self.game.gamedata.busts[s]  # Keep as string
+                d1 = pendulum.parse(d)  # Convert to dateTime obj
+                log.debug("{0} on {1}".format(s, d))
+                self.busted[s] = "{0:02d}-{1:02d}-{2:04d}".format(
+                    d1.month, d1.day, d1.year
+                )
+                self.age[s] = self.calcAge(d1)
+            self.state += 1
+            self.send2game("D")
+        elif self.state == 1:
+            # Display it nicely to the user, then exit
+            tc = merge(Style.BRIGHT + Fore.YELLOW + Back.BLUE)
+            c1 = merge(Style.BRIGHT + Fore.WHITE + Back.BLUE)
+            c2 = merge(Style.BRIGHT + Fore.CYAN + Back.BLUE)
+
+            if self.busted:
+                box = Boxes(42, color=tc)
+                self.queue_game.put(box.top())
+                self.queue_game.put(
+                    box.row(
+                        tc
+                        + " {0:10} {1:<20} {2:8} ".format(
+                            "Sector", "Date Busted On", "Days old"
+                        )
+                    )
+                )
+                self.queue_game.put(box.middle())
+                for s in self.busted:
+                    if self.age[s]:
+                        self.queue_game.put(
+                            box.row(
+                                c1
+                                + " {0:<10} {1:<20} {2:8} ".format(
+                                    s, self.busted[s], self.age[s]
+                                )
+                            )
+                        )
+                    else:
+                        self.queue_game.put(
+                            box.row(
+                                c1
+                                + " {0:<10} {1:<20}          ".format(s, self.busted[s])
+                            )
+                        )
+
+                self.queue_game.put(box.bottom())
+            else:
+                self.send2player(
+                    self.nl
+                    + Boxes.alert(
+                        "You have no busts to view, perhaps you just aren't into trouble."
+                    )
+                )
+            self.deactivate(True)
+
+    def game_line(self, line: str):
+        log.debug("L {0} | {1}".format(self.state, line))
+
+
+class firstActivate(object):
+    """ Uppon first time activation of the proxy what happens
+
+        States:
+        0 = Send V and gather information on when busts were cleared
+        1 = Calcualte date from pendulum.now().subtract(days=#)
+        2 = If pendulum.now() is greater than our date to clear then self.game.gamedata.reset_busts()
+
+        Well drat... while in a game you can't access when busts were cleared. :(
+    """
+
+    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.c = merge(Style.BRIGHT + Fore.YELLOW)
+        self.nl = "\n\r"
+
+        # Stuffz
+        self.state = 0  # V and gather info
+
+        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.to_player = self.game.to_player
+        self.game.to_player = False
+        self.send2game("V")  # Since we need to send at least 1 character
+
+    def whenDone(self):
+        self.defer = defer.Deferred()
+        return self.defer
+
+    def deactivate(self, andExit=False):
+        self.state = 0
+        log.debug("firstActivate.deactivate()")
+        self.game.to_player = True
+        assert not self.save is None
+        self.observer.load(self.save)
+        self.save = None
+        if self.defer:
+            if andExit:
+                self.defer.callback({"exit": True})
+            else:
+                self.defer.callback("done")
+            self.defer = None
+
+    def player(self, chunk: bytes):
+        self.deactivate(True)
+
+    def send2game(self, txt):
+        self.queue_player.put(txt)
+
+    def send2player(self, txt):
+        self.queue_game.put(txt)
+
+    def game_prompt(self, prompt: str):
+        log.debug("P {0} | {1}".format(self.state, prompt))
+        if self.state == 0:
+            if prompt.startswith("Command"):
+                self.deactivate()
+
+    def game_line(self, line: str):
+        log.debug("L {0} | {1}".format(self.state, line))
+
+
 class ProxyMenu(object):
     """ Display ProxyMenu 
     
@@ -4381,15 +4599,31 @@ class ProxyMenu(object):
         self.defer = None
         self.game.to_player = True
 
-        self.keepalive = task.LoopingCall(self.awake)
-        self.keepalive.start(30)
-        self.menu()
+        # Is it our first time activated? if so do a little extra stuff.
+        if self.game.gamedata.activated == False:
+            self.game.gamedata.activated = True
+            # Run V to get date of bust clear from game
+            # Decide to clear or not
+            # Clear or continue on
+            log.debug("First time activation dectected!")
+            first = firstActivate(self.game)
+            d = first.whenDone()
+            d.addCallback(self.pre_back)
+            d.addErrback(self.pre_back)
+        else:
+            # welp that was all skipped because we already did that.
+            self.pre_back()
 
     def __del__(self):
         log.debug("ProxyMenu {0} RIP".format(self))
         # When we exit, always make sure player echo is on.
         self.game.to_player = True
 
+    def pre_back(self, stuffz=None):
+        self.keepalive = task.LoopingCall(self.awake)
+        self.keepalive.start(30)
+        self.menu()
+
     def whenDone(self):
         self.defer = defer.Deferred()
         # Call this to chain something after we exit.
@@ -4427,6 +4661,7 @@ class ProxyMenu(object):
         menu_item("W", "Warp CIM Report ({0})".format(len(self.game.gamedata.warps)))
         menu_item("R", "Restock Report")
         menu_item("T", "Trading Report")
+        menu_item("B", "Display Busts ({0})".format(len(self.game.gamedata.busts)))
         menu_item("S", "Scripts")
         menu_item("X", "eXit")
         bottom = box.bottom()
@@ -4667,6 +4902,14 @@ class ProxyMenu(object):
                 d.addCallback(self.activate_macro)
                 d.addErrback(self.welcome_back)
             return
+        elif key == "B":
+            self.queue_game.put(self.c + key + self.r + self.nl)
+            # Display Busts
+            busting = bustViewer(self.game)
+            d = busting.whenDone()
+            d.addCallback(self.welcome_back)
+            d.addErrback(self.welcome_back)
+            return
         elif key == "S":
             self.queue_game.put(self.c + key + self.r + self.nl)
             # Scripts

+ 18 - 3
galaxy.py

@@ -4,6 +4,7 @@ import logging
 import pendulum
 
 # from twisted.python import log
+from copy import deepcopy
 from pprint import pprint
 from colorama import Fore, Back, Style
 import config
@@ -46,6 +47,7 @@ class GameData(object):
         self.port_groups = 3
         # Not sure, I don't think it will be big.
         self.bust_groups = 5
+        self.activated = False  # Did we activate the proxy? Not sure if this is the right spot to put it in.
 
     def storage_filename(self):
         """ return filename
@@ -66,6 +68,7 @@ class GameData(object):
         self.warps = {}
 
     def reset_busts(self):
+        # Ok well we won't ever use this since maint_busts() goes thru them all and filters out those that are 7 days or older
         self.busts = {}
 
     def special_ports(self):
@@ -240,6 +243,8 @@ class GameData(object):
                         for s, d in obj["busts"].items():
                             self.busts[int(s)] = d
                     yield
+            # Clean Busts after loading
+            self.maint_busts()
         log.info(
             "Loaded {0} {1}/{2}/{3}/{4}".format(
                 filename,
@@ -279,6 +284,8 @@ class GameData(object):
                     if "busts" in obj:
                         for s, d in obj["busts"].items():
                             self.busts[int(s)] = d
+            # Clean Busts after loading
+            self.maint_busts()
         log.info(
             "Loaded {0} {1}/{2}/{3}/{4}".format(
                 filename,
@@ -346,11 +353,19 @@ class GameData(object):
     def maint_busts(self):
         # Checks the current date to see if any busts need to be cleared
         rightNow = pendulum.now()
-        for s, d in self.busts:
+        dropped = 0  # Add in debug message so we can see if we are running correctly
+        new = deepcopy(
+            self.busts
+        )  # Get essentially a backup, one we will be changing without iterating over
+        for s in self.busts:
+            d = self.busts[s]  # Pull string of DateTime object
             d = pendulum.parse(d)  # Convert string to DateTime obj
             d = d.add(7)  # Add 7 days
-            if d == rightNow:  # Compare
-                del self.busts[s]
+            if d <= rightNow:  # Compare
+                del new[s]  # remove it from a 2nd dict
+                dropped += 1
+        self.busts = new
+        log.debug("Dropped {0} sectors from busted list".format(dropped))
 
     def port_buying(self, sector: int, cargo: str):
         """ Given a sector, is this port buying this?