From 726cd7d4d28be1c6e2c72965588c334c67878ab5 Mon Sep 17 00:00:00 2001 From: SpudGunMan Date: Sat, 5 Oct 2024 20:08:33 -0700 Subject: [PATCH] woahLottaRefactoring --- data | 0 etc/db_admin.py | 42 +++--- etc/report_generator.py | 106 ++++++++++------ etc/report_generator5.py | 106 ++++++++++------ mesh_bot.py | 47 ++----- modules/bbstools.py | 20 +-- modules/games/blackjack.py | 12 +- modules/games/dopewar.py | 6 +- modules/games/golfsim.py | 6 +- modules/games/lemonade.py | 6 +- modules/games/mmind.py | 2 +- modules/games/videopoker.py | 12 +- modules/settings.py | 4 +- modules/system.py | 247 ++++++++++++++++++------------------ 14 files changed, 330 insertions(+), 286 deletions(-) create mode 100644 data diff --git a/data b/data new file mode 100644 index 0000000..e69de29 diff --git a/etc/db_admin.py b/etc/db_admin.py index 0eb6bc3..ff9830b 100644 --- a/etc/db_admin.py +++ b/etc/db_admin.py @@ -4,65 +4,65 @@ import pickle # pip install pickle # load the bbs messages from the database file try: - with open('../bbsdb.pkl', 'rb') as f: + with open('../data/bbsdb.pkl', 'rb') as f: bbs_messages = pickle.load(f) except Exception as e: try: - with open('bbsdb.pkl', 'rb') as f: + with open('data/bbsdb.pkl', 'rb') as f: bbs_messages = pickle.load(f) except Exception as e: - bbs_messages = "System: bbsdb.pkl not found" + bbs_messages = "System: data/bbsdb.pkl not found" try: - with open('../bbsdm.pkl', 'rb') as f: + with open('../data/bbsdm.pkll', 'rb') as f: bbs_dm = pickle.load(f) except Exception as e: try: - with open('bbsdm.pkl', 'rb') as f: + with open('data/bbsdm.pkll', 'rb') as f: bbs_dm = pickle.load(f) except Exception as e: - bbs_dm = "System: bbsdm.pkl not found" + bbs_dm = "System: data/bbsdm.pkll not found" # Game HS tables try: - with open('../lemonade_hs.pkl', 'rb') as f: + with open('../data/lemonstand.pkl', 'rb') as f: lemon_score = pickle.load(f) except Exception as e: try: - with open('lemonade_hs.pkl', 'rb') as f: + with open('data/lemonstand.pkl', 'rb') as f: lemon_score = pickle.load(f) except Exception as e: - lemon_score = "System: lemonade_hs.pkl not found" + lemon_score = "System: data/lemonstand.pkl not found" try: - with open('../dopewar_hs.pkl', 'rb') as f: + with open('../data/dopewar_hs.pkl', 'rb') as f: dopewar_score = pickle.load(f) except Exception as e: try: - with open('dopewar_hs.pkl', 'rb') as f: + with open('data/dopewar_hs.pkl', 'rb') as f: dopewar_score = pickle.load(f) except Exception as e: - dopewar_score = "System: dopewar_hs.pkl not found" + dopewar_score = "System: data/dopewar_hs.pkl not found" try: - with open('../blackjack_hs.pkl', 'rb') as f: + with open('../data/blackjack_hs.pkl', 'rb') as f: blackjack_score = pickle.load(f) except Exception as e: try: - with open('blackjack_hs.pkl', 'rb') as f: + with open('data/blackjack_hs.pkl', 'rb') as f: blackjack_score = pickle.load(f) except Exception as e: - blackjack_score = "System: blackjack_hs.pkl not found" + blackjack_score = "System: data/blackjack_hs.pkl not found" try: - with open('../videopoker_hs.pkl', 'rb') as f: + with open('../data/videopoker_hs.pkl', 'rb') as f: videopoker_score = pickle.load(f) except Exception as e: try: - with open('videopoker_hs.pkl', 'rb') as f: + with open('data/videopoker_hs.pkl', 'rb') as f: videopoker_score = pickle.load(f) except Exception as e: - videopoker_score = "System: videopoker_hs.pkl not found" + videopoker_score = "System: data/videopoker_hs.pkl not found" try: with open('../mmind_hs.pkl', 'rb') as f: @@ -75,14 +75,14 @@ except Exception as e: mmind_score = "System: mmind_hs.pkl not found" try: - with open('../golfsim_hs.pkl', 'rb') as f: + with open('../data/golfsim_hs.pkl', 'rb') as f: golfsim_score = pickle.load(f) except Exception as e: try: - with open('golfsim_hs.pkl', 'rb') as f: + with open('data/golfsim_hs.pkl', 'rb') as f: golfsim_score = pickle.load(f) except Exception as e: - golfsim_score = "System: golfsim_hs.pkl not found" + golfsim_score = "System: data/golfsim_hs.pkl not found" print ("\n Meshing-Around Database Admin Tool\n") diff --git a/etc/report_generator.py b/etc/report_generator.py index 30ed0ba..6d4ce7a 100644 --- a/etc/report_generator.py +++ b/etc/report_generator.py @@ -336,62 +336,94 @@ def get_database_info(): # Get the database information try: - with open('../lemonade_hs.pkl', 'rb') as f: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'lemonstand.pkl'), 'rb') as f: lemon_score = pickle.load(f) - f.close() + except Exception as e: + print(f"Error with database: {str(e)}") + lemon_score = 'no data' + pass - with open('../dopewar_hs.pkl', 'rb') as f: + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'dopewar.pkl'), 'rb') as f: dopewar_score = pickle.load(f) - f.close() + except Exception as e: + print(f"Error with database: {str(e)}") + dopewar_score = 'no data' + pass - with open('../blackjack_hs.pkl', 'rb') as f: + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'blackjack.pkl'), 'rb') as f: blackjack_score = pickle.load(f) - f.close() + except Exception as e: + print(f"Error with database: {str(e)}") + blackjack_score = 'no data' + pass - with open('../videopoker_hs.pkl', 'rb') as f: + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'videopoker.pkl'), 'rb') as f: videopoker_score = pickle.load(f) - f.close() + except Exception as e: + print(f"Error with database: {str(e)}") + videopoker_score = 'no data' + pass - with open('../mmind_hs.pkl', 'rb') as f: + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'mmind.pkl'), 'rb') as f: mmind_score = pickle.load(f) - f.close() - - with open('../golfsim_hs.pkl', 'rb') as f: + except Exception as e: + print(f"Error with database: {str(e)}") + mmind_score = 'no data' + + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'golfsim.pkl'), 'rb') as f: golfsim_score = pickle.load(f) - f.close() + except Exception as e: + print(f"Error with database: {str(e)}") + golfsim_score = 'no data' + pass - with open('../bbsdm.pkl', 'rb') as f: - bbsdm = pickle.load(f) - f.close() - - with open('../bbsdb.pkl', 'rb') as f: + # Get the BBSdb and BBSdm + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'bbsdb.pkl'), 'rb') as f: bbsdb = pickle.load(f) - f.close() + except Exception as e: + print(f"Error with database: {str(e)}") + bbsdb = [] + pass - # pretty print the bbsdb - prettyBBSdb = "" - try: - for i in range(len(bbsdb)): - prettyBBSdb += f'
  • {bbsdb[i]}
  • ' - except Exception as e: - print(f"Error with database: {str(e)}") - pass - - # pretty print the bbsdm - prettyBBSdm = "" - try: - for i in range(len(bbsdm)): - prettyBBSdm += f'
  • {bbsdm[i]}
  • ' - except Exception as e: - print(f"Error with database: {str(e)}") - pass + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'bbsdm.pkl'), 'rb') as f: + bbsdm = pickle.load(f) + except Exception as e: + print(f"Error with database: {str(e)}") + bbsdm = [] + pass + # pretty print the bbsdb + prettyBBSdb = "" + try: + for i in range(len(bbsdb)): + prettyBBSdb += f'
  • {bbsdb[i]}
  • ' except Exception as e: print(f"Error with database: {str(e)}") pass + # pretty print the bbsdm + prettyBBSdm = "" + try: + for i in range(len(bbsdm)): + prettyBBSdm += f'
  • {bbsdm[i]}
  • ' + except Exception as e: + print(f"Error with database: {str(e)}") + pass + + if 'no data' in [lemon_score, dopewar_score, blackjack_score, videopoker_score, mmind_score, golfsim_score]: + database = "Error(s) Detected" + else: + database = " Online" + return { - 'database': "Connected", + 'database': database, "bbsdb": prettyBBSdb, "bbsdm": prettyBBSdm, 'lemon_score': lemon_score, diff --git a/etc/report_generator5.py b/etc/report_generator5.py index ad8f1b4..abc1bd6 100644 --- a/etc/report_generator5.py +++ b/etc/report_generator5.py @@ -345,62 +345,94 @@ def get_database_info(): # Get the database information try: - with open('../lemonade_hs.pkl', 'rb') as f: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'lemonstand.pkl'), 'rb') as f: lemon_score = pickle.load(f) - f.close() + except Exception as e: + print(f"Error with database: {str(e)}") + lemon_score = 'no data' + pass - with open('../dopewar_hs.pkl', 'rb') as f: + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'dopewar.pkl'), 'rb') as f: dopewar_score = pickle.load(f) - f.close() + except Exception as e: + print(f"Error with database: {str(e)}") + dopewar_score = 'no data' + pass - with open('../blackjack_hs.pkl', 'rb') as f: + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'blackjack.pkl'), 'rb') as f: blackjack_score = pickle.load(f) - f.close() + except Exception as e: + print(f"Error with database: {str(e)}") + blackjack_score = 'no data' + pass - with open('../videopoker_hs.pkl', 'rb') as f: + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'videopoker.pkl'), 'rb') as f: videopoker_score = pickle.load(f) - f.close() + except Exception as e: + print(f"Error with database: {str(e)}") + videopoker_score = 'no data' + pass - with open('../mmind_hs.pkl', 'rb') as f: + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'mmind.pkl'), 'rb') as f: mmind_score = pickle.load(f) - f.close() - - with open('../golfsim_hs.pkl', 'rb') as f: + except Exception as e: + print(f"Error with database: {str(e)}") + mmind_score = 'no data' + + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'golfsim.pkl'), 'rb') as f: golfsim_score = pickle.load(f) - f.close() + except Exception as e: + print(f"Error with database: {str(e)}") + golfsim_score = 'no data' + pass - with open('../bbsdm.pkl', 'rb') as f: - bbsdm = pickle.load(f) - f.close() - - with open('../bbsdb.pkl', 'rb') as f: + # Get the BBSdb and BBSdm + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'bbsdb.pkl'), 'rb') as f: bbsdb = pickle.load(f) - f.close() + except Exception as e: + print(f"Error with database: {str(e)}") + bbsdb = [] + pass - # pretty print the bbsdb - prettyBBSdb = "" - try: - for i in range(len(bbsdb)): - prettyBBSdb += f'
  • {bbsdb[i]}
  • ' - except Exception as e: - print(f"Error with database: {str(e)}") - pass - - # pretty print the bbsdm - prettyBBSdm = "" - try: - for i in range(len(bbsdm)): - prettyBBSdm += f'
  • {bbsdm[i]}
  • ' - except Exception as e: - print(f"Error with database: {str(e)}") - pass + try: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'bbsdm.pkl'), 'rb') as f: + bbsdm = pickle.load(f) + except Exception as e: + print(f"Error with database: {str(e)}") + bbsdm = [] + pass + # pretty print the bbsdb + prettyBBSdb = "" + try: + for i in range(len(bbsdb)): + prettyBBSdb += f'
  • {bbsdb[i]}
  • ' except Exception as e: print(f"Error with database: {str(e)}") pass + # pretty print the bbsdm + prettyBBSdm = "" + try: + for i in range(len(bbsdm)): + prettyBBSdm += f'
  • {bbsdm[i]}
  • ' + except Exception as e: + print(f"Error with database: {str(e)}") + pass + + if 'no data' in [lemon_score, dopewar_score, blackjack_score, videopoker_score, mmind_score, golfsim_score]: + database = "Error(s) Detected" + else: + database = " Online" + return { - 'database': "Connected", + 'database': database, "bbsdb": prettyBBSdb, "bbsdm": prettyBBSdm, 'lemon_score': lemon_score, diff --git a/mesh_bot.py b/mesh_bot.py index 38ddf6b..ce7edd6 100755 --- a/mesh_bot.py +++ b/mesh_bot.py @@ -652,46 +652,19 @@ def handle_lheard(message, nodeid, deviceID, isDM): if "?" in message and isDM: return message.split("?")[0].title() + " command returns a list of the nodes that have been heard recently" - else: - # display last heard nodes add to response - bot_response = str(get_node_list(1)) - # gather telemetry - chutil1 = round(interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("channelUtilization", 0), 1) - airUtilTx = round(interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("airUtilTx", 0), 1) - uptimeSeconds = interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("uptimeSeconds", 0) - batteryLevel = interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("batteryLevel", 0) - voltage = interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("voltage", 0) - if interface2_enabled: - bot_response += "P2:\n" + str(get_node_list(2)) - chutil2 = round(interface2.nodes.get(decimal_to_hex(myNodeNum2), {}).get("deviceMetrics", {}).get("channelUtilization", 0), 1) - airUtilTx2 = round(interface2.nodes.get(decimal_to_hex(myNodeNum2), {}).get("deviceMetrics", {}).get("airUtilTx", 0), 1) - uptimeSeconds2 = interface2.nodes.get(decimal_to_hex(myNodeNum2), {}).get("deviceMetrics", {}).get("uptimeSeconds", 0) - batteryLevel2 = interface2.nodes.get(decimal_to_hex(myNodeNum2), {}).get("deviceMetrics", {}).get("batteryLevel", 0) - voltage2 = interface2.nodes.get(decimal_to_hex(myNodeNum2), {}).get("deviceMetrics", {}).get("voltage", 0) - else: - chutil2, airUtilTx2, uptimeSeconds2, batteryLevel2, voltage2 = 0, 0, 0, 0, 0 - # add the channel utilization and airUtilTx to the bot response - bot_response += "\nUse/Tx " + str(chutil1) + "%" + "/" + str(airUtilTx) + "%" - if interface2_enabled: - bot_response += " P2:" + str(chutil2) + "%" + "/" + str(airUtilTx2) + "%" - # convert uptime to minutes, hours, or days - uptimeSeconds = getPrettyTime(uptimeSeconds) - uptimeSeconds2 = getPrettyTime(uptimeSeconds2) - # add uptime and battery info to the bot response - bot_response += "\nUptime:" + str(uptimeSeconds) - if interface2_enabled: - bot_response += f" P2:" + {uptimeSeconds2} - # add battery info to the bot response - emji = "šŸ”Œ" if batteryLevel == 101 else "🪫" if batteryLevel < 10 else "šŸ”‹" - emji2 = "šŸ”Œ" if batteryLevel2 == 101 else "🪫" if batteryLevel2 < 10 else "šŸ”‹" - if not batteryLevel == 101: - bot_response += f" {emji}{batteryLevel}% Volt:{voltage}" - if interface2_enabled and not batteryLevel2 == 101: - bot_response += f" P2:{emji2}{batteryLevel2}% Volt:{voltage2}" + # display last heard nodes add to response + bot_response = "Last Heard\n" + bot_response += str(get_node_list(1)) + # show last users of the bot with the cmdHistory list history = handle_history(message, nodeid, deviceID, isDM, lheard=True) if history: - bot_response += f'\n{history}' + bot_response += f'LastSeen\n{history}' + else: + # trim the last \n + bot_response = bot_response[:-1] + + # bot_response += getNodeTelemetry(deviceID) return bot_response def handle_history(message, nodeid, deviceID, isDM, lheard=False): diff --git a/modules/bbstools.py b/modules/bbstools.py index e61178c..41a32c6 100644 --- a/modules/bbstools.py +++ b/modules/bbstools.py @@ -14,19 +14,19 @@ def load_bbsdb(): global bbs_messages # load the bbs messages from the database file try: - with open('bbsdb.pkl', 'rb') as f: + with open('data/bbsdb.pkl', 'rb') as f: bbs_messages = pickle.load(f) except Exception as e: bbs_messages = [[1, "Welcome to meshBBS", "Welcome to the BBS, please post a message!",0]] - logger.debug("System: Creating new bbsdb.pkl") - with open('bbsdb.pkl', 'wb') as f: + logger.debug("System: Creating new data/bbsdb.pkl") + with open('data/bbsdb.pkl', 'wb') as f: pickle.dump(bbs_messages, f) def save_bbsdb(): global bbs_messages # save the bbs messages to the database file - logger.debug("System: Saving bbsdb.pkl") - with open('bbsdb.pkl', 'wb') as f: + logger.debug("System: Saving data/bbsdb.pkl") + with open('data/bbsdb.pkl', 'wb') as f: pickle.dump(bbs_messages, f) def bbs_help(): @@ -100,20 +100,20 @@ def bbs_read_message(messageID = 0): def save_bbsdm(): global bbs_dm # save the bbs messages to the database file - logger.debug("System: Saving Updated BBS Direct Messages bbsdm.pkl") - with open('bbsdm.pkl', 'wb') as f: + logger.debug("System: Saving Updated BBS Direct Messages data/bbsdm.pkll") + with open('data/bbsdm.pkll', 'wb') as f: pickle.dump(bbs_dm, f) def load_bbsdm(): global bbs_dm # load the bbs messages from the database file try: - with open('bbsdm.pkl', 'rb') as f: + with open('data/bbsdm.pkll', 'rb') as f: bbs_dm = pickle.load(f) except: bbs_dm = [[1234567890, "Message", 1234567890]] - logger.debug("System: Creating new bbsdm.pkl") - with open('bbsdm.pkl', 'wb') as f: + logger.debug("System: Creating new data/bbsdm.pkll") + with open('data/bbsdm.pkll', 'wb') as f: pickle.dump(bbs_dm, f) def bbs_post_dm(toNode, message, fromNode): diff --git a/modules/games/blackjack.py b/modules/games/blackjack.py index 1074d7d..2b8a21e 100644 --- a/modules/games/blackjack.py +++ b/modules/games/blackjack.py @@ -210,22 +210,22 @@ def saveHSJack(nodeID, highScore): # Save the game state to pickle highScore = {'nodeID': nodeID, 'highScore': highScore} try: - with open('blackjack_hs.pkl', 'wb') as file: + with open('data/blackjack_hs.pkl', 'wb') as file: pickle.dump(highScore, file) except FileNotFoundError: - logger.debug("System: BlackJack: Creating new blackjack_hs.pkl file") - with open('blackjack_hs.pkl', 'wb') as file: + logger.debug("System: BlackJack: Creating new data/blackjack_hs.pkl file") + with open('data/blackjack_hs.pkl', 'wb') as file: pickle.dump(highScore, file) def loadHSJack(): try: - with open('blackjack_hs.pkl', 'rb') as file: + with open('data/blackjack_hs.pkl', 'rb') as file: highScore = pickle.load(file) return highScore except FileNotFoundError: - logger.debug("System: BlackJack: Creating new blackjack_hs.pkl file") + logger.debug("System: BlackJack: Creating new data/blackjack_hs.pkl file") highScore = {'nodeID': 0, 'highScore': 0} - with open('blackjack_hs.pkl', 'wb') as file: + with open('data/blackjack_hs.pkl', 'wb') as file: pickle.dump(highScore, file) return 0 diff --git a/modules/games/dopewar.py b/modules/games/dopewar.py index bdd1b29..b79ab6d 100644 --- a/modules/games/dopewar.py +++ b/modules/games/dopewar.py @@ -390,7 +390,7 @@ def endGameDw(nodeID): # checks if the player's score is higher than the high score and writes a new high score if it is if cash > dwHighScore.get('cash'): dwHighScore = ({'userID': nodeID, 'cash': round(cash, 2)}) - with open('dopewar_hs.pkl', 'wb') as file: + with open('data/dopewar_hs.pkl', 'wb') as file: pickle.dump(dwHighScore, file) msg = "You finished with $" + str(cash) + " and beat the high score!šŸŽ‰šŸ’°" return msg @@ -409,14 +409,14 @@ def getHighScoreDw(): global dwHighScore # Load high score table try: - with open('dopewar_hs.pkl', 'rb') as file: + with open('data/dopewar_hs.pkl', 'rb') as file: dwHighScore = pickle.load(file) except FileNotFoundError: logger.debug("System: DopeWars: No high score table found") # high score pickle file is a touple of the nodeID and the high score dwHighScore = ({"userID": 4258675309, "cash": 100}) # write a new high score file if one is not found - with open('dopewar_hs.pkl', 'wb') as file: + with open('data/dopewar_hs.pkl', 'wb') as file: pickle.dump(dwHighScore, file) return dwHighScore diff --git a/modules/games/golfsim.py b/modules/games/golfsim.py index f7b5a1b..d3fe5e3 100644 --- a/modules/games/golfsim.py +++ b/modules/games/golfsim.py @@ -102,12 +102,12 @@ def getScorecardGolf(scorecard): def getHighScoreGolf(nodeID, strokes, par): # check if player is in high score list try: - with open('golfsim_hs.pkl', 'rb') as f: + with open('data/golfsim_hs.pkl', 'rb') as f: golfHighScore = pickle.load(f) except: logger.debug("System: GolfSim: High Score file not found.") golfHighScore = [{'nodeID': nodeID, 'strokes': strokes, 'par': par}] - with open('golfsim_hs.pkl', 'wb') as f: + with open('data/golfsim_hs.pkl', 'wb') as f: pickle.dump(golfHighScore, f) if strokes < golfHighScore[0]['strokes']: @@ -115,7 +115,7 @@ def getHighScoreGolf(nodeID, strokes, par): golfHighScore[0]['nodeID'] = nodeID golfHighScore[0]['strokes'] = strokes golfHighScore[0]['par'] = par - with open('golfsim_hs.pkl', 'wb') as f: + with open('data/golfsim_hs.pkl', 'wb') as f: pickle.dump(golfHighScore, f) return golfHighScore diff --git a/modules/games/lemonade.py b/modules/games/lemonade.py index 8678a26..92ca1ba 100644 --- a/modules/games/lemonade.py +++ b/modules/games/lemonade.py @@ -41,12 +41,12 @@ def getHighScoreLemon(): high_score = {"userID": 0, "cash": 0, "success": 0} # Load high score table try: - with open('lemonade_hs.pkl', 'rb') as file: + with open('data/lemonstand.pkl', 'rb') as file: high_score = pickle.load(file) except FileNotFoundError: logger.debug("System: Lemonade: No high score table found") # write a new high score file if one is not found - with open('lemonade_hs.pkl', 'wb') as file: + with open('data/lemonstand.pkl', 'wb') as file: pickle.dump(high_score, file) return high_score @@ -548,7 +548,7 @@ def start_lemonade(nodeID, message, celsius=False): high_score['cash'] = inventory.cash high_score['success'] = success high_score['userID'] = nodeID - with open('lemonade_hs.pkl', 'wb') as file: + with open('data/lemonstand.pkl', 'wb') as file: pickle.dump(high_score, file) endGame(nodeID) diff --git a/modules/games/mmind.py b/modules/games/mmind.py index 0fc0f85..6f78bea 100644 --- a/modules/games/mmind.py +++ b/modules/games/mmind.py @@ -248,7 +248,7 @@ def playGameMMind(diff, secret_code, turn_count, nodeID, message): if high_score != 0: msg += f"\nšŸ† High Score:{high_score[0]['turns']} turns, Difficulty:{high_score[0]['diff'].upper()}" - msg += "\nWould you like to play again?\n(N)ormal, (H)ard, e(X)pert?" + msg += "\nWould you like to play again?\n(N)ormal, (H)ard, e(X)pert (E)nd?" # reset turn count in tracker for i in range(len(mindTracker)): if mindTracker[i]['nodeID'] == nodeID: diff --git a/modules/games/videopoker.py b/modules/games/videopoker.py index 381d48f..e6974a4 100644 --- a/modules/games/videopoker.py +++ b/modules/games/videopoker.py @@ -276,23 +276,23 @@ def saveHSVp(nodeID, highScore): # Save the game high_score to pickle highScore = {'nodeID': nodeID, 'highScore': highScore} try: - with open('videopoker_hs.pkl', 'wb') as file: + with open('data/videopoker_hs.pkl', 'wb') as file: pickle.dump(highScore, file) except FileNotFoundError: - logger.debug("System: BlackJack: Creating new videopoker_hs.pkl file") - with open('videopoker_hs.pkl', 'wb') as file: + logger.debug("System: BlackJack: Creating new data/videopoker_hs.pkl file") + with open('data/videopoker_hs.pkl', 'wb') as file: pickle.dump(highScore, file) def loadHSVp(): # Load the game high_score from pickle try: - with open('videopoker_hs.pkl', 'rb') as file: + with open('data/videopoker_hs.pkl', 'rb') as file: highScore = pickle.load(file) return highScore except FileNotFoundError: - logger.debug("System: VideoPoker: Creating new videopoker_hs.pkl file") + logger.debug("System: VideoPoker: Creating new data/videopoker_hs.pkl file") highScore = {'nodeID': 0, 'highScore': 0} - with open('videopoker_hs.pkl', 'wb') as file: + with open('data/videopoker_hs.pkl', 'wb') as file: pickle.dump(highScore, file) return 0 diff --git a/modules/settings.py b/modules/settings.py index b1d0b37..193a4b1 100644 --- a/modules/settings.py +++ b/modules/settings.py @@ -55,7 +55,7 @@ if 'location' not in config: config.write(open(config_file, 'w')) if 'bbs' not in config: - config['bbs'] = {'enabled': 'False', 'bbsdb': 'bbsdb.pkl', 'bbs_ban_list': '', 'bbs_admin_list': ''} + config['bbs'] = {'enabled': 'False', 'bbsdb': 'data/bbsdb.pkl', 'bbs_ban_list': '', 'bbs_admin_list': ''} config.write(open(config_file, 'w')) if 'repeater' not in config: @@ -134,7 +134,7 @@ try: # bbs bbs_enabled = config['bbs'].getboolean('enabled', False) - bbsdb = config['bbs'].get('bbsdb', 'bbsdb.pkl') + bbsdb = config['bbs'].get('bbsdb', 'data/bbsdb.pkl') bbs_ban_list = config['bbs'].get('bbs_ban_list', '').split(',') bbs_admin_list = config['bbs'].get('bbs_admin_list', '').split(',') diff --git a/modules/system.py b/modules/system.py index c133174..169a03a 100644 --- a/modules/system.py +++ b/modules/system.py @@ -643,6 +643,85 @@ def messageTrap(msg): return True return False +def getNodeFirmware(nodeID=0, nodeInt=1): + # get the firmware version of the node + # this is a workaround because .localNode.getMetadata spits out a lot of debug info which cant be suppressed + # Create a StringIO object to capture the + if nodeInt == 1: + output_capture = io.StringIO() + with contextlib.redirect_stdout(output_capture): + interface1.localNode.getMetadata() + console_output = output_capture.getvalue() + if "firmware_version" in console_output: + fwVer = console_output.split("firmware_version: ")[1].split("\n")[0] + elif nodeInt == 2: + output_capture = io.StringIO() + with contextlib.redirect_stdout(output_capture): + interface2.localNode.getMetadata() + console_output = output_capture.getvalue() + if "firmware_version" in console_output: + fwVer = console_output.split("firmware_version: ")[1].split("\n")[0] + else: + return -1 + return fwVer + +def getNodeTelemetry(nodeID=0, nodeInt=1): + dataResponse = "" + # get the telemetry data for a node + if nodeInt == 1: + chutil = round(interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("channelUtilization", 0), 1) + airUtilTx = round(interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("airUtilTx", 0), 1) + uptimeSeconds = interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("uptimeSeconds", 0) + batteryLevel = interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("batteryLevel", 0) + voltage = interface1.nodes.get(decimal_to_hex(myNodeNum1), {}).get("deviceMetrics", {}).get("voltage", 0) + elif nodeInt == 2: + chutil = round(interface2.nodes.get(decimal_to_hex(myNodeNum2), {}).get("deviceMetrics", {}).get("channelUtilization", 0), 1) + airUtilTx = round(interface2.nodes.get(decimal_to_hex(myNodeNum2), {}).get("deviceMetrics", {}).get("airUtilTx", 0), 1) + uptimeSeconds = interface2.nodes.get(decimal_to_hex(myNodeNum2), {}).get("deviceMetrics", {}).get("uptimeSeconds", 0) + batteryLevel = interface2.nodes.get(decimal_to_hex(myNodeNum2), {}).get("deviceMetrics", {}).get("batteryLevel", 0) + voltage = interface2.nodes.get(decimal_to_hex(myNodeNum2), {}).get("deviceMetrics", {}).get("voltage", 0) + else: + return -1 + + # Channel utilization and airUtilTx + dataResponse += " ChUse/Tx " + str(chutil) + "%" + "/" + str(airUtilTx) + "%" + " " + + # Uptime + uptimeSeconds = getPrettyTime(uptimeSeconds) + dataResponse += " Uptime:" + str(uptimeSeconds) + + # add battery info to the response + emji = "šŸ”Œ" if batteryLevel == 101 else "🪫" if batteryLevel < 10 else "šŸ”‹" + if batteryLevel == 101: + dataResponse += f" {emji}Volt:{voltage}" + else: + dataResponse += f" {emji}{batteryLevel}% Volt:{voltage}" + + return dataResponse + +def handleMultiPing(nodeID=0, deviceID=1): + global multiPingList + if len(multiPingList) > 1: + mPlCpy = multiPingList.copy() + for i in range(len(mPlCpy)): + message_id_from = mPlCpy[i]['message_from_id'] + count = mPlCpy[i]['count'] + type = mPlCpy[i]['type'] + deviceID = mPlCpy[i]['deviceID'] + + if count > 1 and deviceID == 1: + count -= 1 + # update count in the list + multiPingList[i]['count'] = count + + send_message(f"šŸ”‚{count} {type}", publicChannel, message_id_from, 1) + if count < 2: + # remove the item from the list + for j in range(len(multiPingList)): + if multiPingList[j]['message_from_id'] == message_id_from: + multiPingList.pop(j) + break + def exit_handler(): # Close the interface and save the BBS messages logger.debug(f"System: Closing Autoresponder") @@ -721,7 +800,6 @@ async def retry_interface(nodeID=1): except Exception as e: logger.error(f"System: closing interface2: {e}") - logger.debug(f"System: Retrying interface in 15 seconds") if max_retry_count1 == 0: logger.critical(f"System: Max retry count reached for interface1") @@ -763,84 +841,56 @@ async def retry_interface(nodeID=1): except Exception as e: logger.error(f"System: opening interface2: {e}") -async def watchdog(): - global retry_int1, retry_int2, multiPingList, int1_version, int2_version - int1_version = '' - int2_version = '' - if sentry_enabled: +async def handleSentinel(deviceID=1, loop=0): + # Locate Closest Nodes and report them to a secure channel + # async function for possibly demanding back location data + sentry_loop = loop + lastSpotted = "" + enemySpotted = "" + try: + closest_nodes = get_closest_nodes(deviceID) + if closest_nodes != ERROR_FETCHING_DATA: + if closest_nodes[0]['id'] is not None: + enemySpotted = get_name_from_number(closest_nodes[0]['id'], 'long', 1) + enemySpotted += ", " + get_name_from_number(closest_nodes[0]['id'], 'short', 1) + enemySpotted += ", " + str(closest_nodes[0]['id']) + enemySpotted += ", " + decimal_to_hex(closest_nodes[0]['id']) + enemySpotted += f" at {closest_nodes[0]['distance']}m" + except Exception as e: + pass + + if sentry_loop >= sentry_holdoff and lastSpotted != enemySpotted: + logger.warning(f"System: {enemySpotted} is close to your location on Interface1") + send_message(f"Sentry1: {enemySpotted}", secure_channel, 0, deviceID) sentry_loop = 0 - lastSpotted = "" - enemySpotted = "" - sentry_loop2 = 0 - lastSpotted2 = "" - enemySpotted2 = "" - # watchdog for connection to the interface + lastSpotted = enemySpotted + else: + sentry_loop += 1 + +async def watchdog(): + global retry_int1, retry_int2, int1Data, int2Data while True: await asyncio.sleep(20) #print(f"MeshBot System: watchdog running\r", end="") if interface1 is not None and not retry_int1: - # getmetadata request to check if the interface is still connected + # getting firmware is a heartbeat to check if the interface is still connected try: - # this is a workaround because .localNode.getMetadata spits out a lot of debug info which cant be suppressed - # Create a StringIO object to capture the output - output_capture = io.StringIO() - with contextlib.redirect_stdout(output_capture): - interface1.localNode.getMetadata() - console_output = output_capture.getvalue() - if "firmware_version" in console_output and int1_version == '': - int1_version = console_output.split("firmware_version: ")[1].split("\n")[0] - logger.debug(f"System: Interface1 Node Firmware: {int1_version}") + firmware = getNodeFirmware(0, 1) except Exception as e: logger.error(f"System: communicating with interface1, trying to reconnect: {e}") retry_int1 = True - - # Locate Closest Nodes and report them to a secure channel - if sentry_enabled: - try: - closest_nodes1 = get_closest_nodes(1) - if closest_nodes1 != ERROR_FETCHING_DATA: - if closest_nodes1[0]['id'] is not None: - enemySpotted = get_name_from_number(closest_nodes1[0]['id'], 'long', 1) - enemySpotted += ", " + get_name_from_number(closest_nodes1[0]['id'], 'short', 1) - enemySpotted += ", " + str(closest_nodes1[0]['id']) - enemySpotted += ", " + decimal_to_hex(closest_nodes1[0]['id']) - enemySpotted += f" at {closest_nodes1[0]['distance']}m" - except Exception as e: - pass - - if sentry_loop >= sentry_holdoff and lastSpotted != enemySpotted: - logger.warning(f"System: {enemySpotted} is close to your location on Interface1") - send_message(f"Sentry1: {enemySpotted}", secure_channel, 0, 1) - if interface2_enabled: - await asyncio.sleep(1.5) - send_message(f"Sentry1: {enemySpotted}", secure_channel, 0, 2) - sentry_loop = 0 - lastSpotted = enemySpotted - else: - sentry_loop += 1 - # multiPing handler - if len(multiPingList) > 1: - mPlCpy = multiPingList.copy() - for i in range(len(mPlCpy)): - message_id_from = mPlCpy[i]['message_from_id'] - count = mPlCpy[i]['count'] - type = mPlCpy[i]['type'] - deviceID = mPlCpy[i]['deviceID'] + if not retry_int1: + # Locate Closest Nodes and report them to a secure channel + if sentry_enabled: + await handleSentinel(1) - if count > 1 and deviceID == 1: - count -= 1 - # update count in the list - multiPingList[i]['count'] = count + # multiPing handler + handleMultiPing(0,1) - send_message(f"šŸ”‚{count} {type}", publicChannel, message_id_from, 1) - if count < 2: - # remove the item from the list - for j in range(len(multiPingList)): - if multiPingList[j]['message_from_id'] == message_id_from: - multiPingList.pop(j) - break + # status data + int1Data = f" int1:{firmware}, Nodes:{len(interface1.nodes)}, Telemetry:{getNodeTelemetry(0, 1)}" if retry_int1: try: @@ -850,66 +900,23 @@ async def watchdog(): if interface2_enabled: if interface2 is not None and not retry_int2: + # getting firmware is a heartbeat to check if the interface is still connected try: - # this is a workaround because .localNode.getMetadata spits out a lot of debug info which cant be suppressed - # Create a StringIO object to capture the output - output_capture = io.StringIO() - with contextlib.redirect_stdout(output_capture): - interface2.localNode.getMetadata() - console_output = output_capture.getvalue() - if "firmware_version" in console_output and int2_version == '': - int2_version = console_output.split("firmware_version: ")[1].split("\n")[0] - logger.debug(f"System: Interface2 Node Firmware: {int2_version}") + firmware2 = getNodeFirmware(0, 1) except Exception as e: - logger.error(f"System: communicating with interface2, trying to reconnect: {e}") + logger.error(f"System: communicating with interface1, trying to reconnect: {e}") retry_int2 = True - - # Locate Closest Nodes and report them to a secure channel - if sentry_enabled: - try: - closest_nodes2 = get_closest_nodes(2) - if closest_nodes2 != ERROR_FETCHING_DATA: - if closest_nodes2[0]['id'] is not None: - enemySpotted2 = get_name_from_number(closest_nodes2[0]['id'], 'long', 2) - enemySpotted2 += ", " + get_name_from_number(closest_nodes2[0]['id'], 'short', 2) - enemySpotted2 += ", " + str(closest_nodes2[0]['id']) - enemySpotted2 += ", " + decimal_to_hex(closest_nodes2[0]['id']) - enemySpotted2 += f" at {closest_nodes2[0]['distance']}m" - except Exception as e: - pass - - if sentry_loop2 >= sentry_holdoff and lastSpotted2 != enemySpotted2: - logger.warning(f"System: {enemySpotted2} is close to your location on Interface2") - # send to secure channel on both interfaces - send_message(f"Sentry2: {enemySpotted2}", secure_channel, 0, 1) - await asyncio.sleep(1.5) - send_message(f"Sentry2: {enemySpotted2}", secure_channel, 0, 2) - sentry_loop2 = 0 - lastSpotted2 = enemySpotted2 - else: - sentry_loop2 += 1 - # multiPing handler - if len(multiPingList) > 1: - mPlCpy = multiPingList.copy() - for i in range(len(mPlCpy)): - message_id_from = mPlCpy[i]['message_from_id'] - count = mPlCpy[i]['count'] - type = mPlCpy[i]['type'] - deviceID = mPlCpy[i]['deviceID'] + if not retry_int2: + # Locate Closest Nodes and report them to a secure channel + if sentry_enabled: + handleSentinel(2) - if count > 1 and deviceID == 2: - count -= 1 - # update count in the list - multiPingList[i]['count'] = count + # multiPing handler + handleMultiPing(0,2) - send_message(f"šŸ”‚{count} {type}", publicChannel, message_id_from, 2) - if count < 2: - # remove the item from the list - for j in range(len(multiPingList)): - if multiPingList[j]['message_from_id'] == message_id_from: - multiPingList.pop(j) - break + # status data + int2Data = f" int2:{firmware2}, Nodes:{len(interface2.nodes)}, Telemetry:{getNodeTelemetry(0, 2)}" if retry_int2: try: