diff --git a/mesh_bot.py b/mesh_bot.py index c9b3ede..a1b07d0 100755 --- a/mesh_bot.py +++ b/mesh_bot.py @@ -9,7 +9,6 @@ except ImportError: exit(1) import asyncio -import sys import time # for sleep, get some when you can :) import random from modules.log import * @@ -19,22 +18,13 @@ from modules.system import * restrictedCommands = ["blackjack", "videopoker", "dopewars", "lemonstand", "golfsim", "mastermind", "hangman", "hamtest", "tictactoe"] restrictedResponse = "🤖only available in a Direct Message📵" # "" for none cmdHistory = [] # list to hold the command history for lheard and history commands +msg_history = [] # list to hold the message history for the messages command def auto_response(message, snr, rssi, hop, pkiStatus, message_from_id, channel_number, deviceID, isDM): global cmdHistory #Auto response to messages message_lower = message.lower() bot_response = "🤖I'm sorry, I'm afraid I can't do that." - - # Manage cmdHistory size to prevent memory bloat - try: - from modules.system import MAX_CMD_HISTORY - max_cmd_history = MAX_CMD_HISTORY - except ImportError: - max_cmd_history = 1000 - - if len(cmdHistory) >= max_cmd_history: - cmdHistory = cmdHistory[-(max_cmd_history-1):] # Command List processes system.trap_list. system.messageTrap() sends any commands to here default_commands = { @@ -1089,7 +1079,6 @@ def handle_moon(message_from_id, deviceID, channel_number): location = get_node_location(message_from_id, deviceID, channel_number) return get_moon(str(location[0]), str(location[1])) - def handle_whoami(message_from_id, deviceID, hop, snr, rssi, pkiStatus): try: loc = [] @@ -1443,18 +1432,13 @@ def onReceive(packet, interface): timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") else: timestamp = datetime.now().strftime("%Y-%m-%d %I:%M:%S%p") - - # Use the safer MAX_MSG_HISTORY limit to prevent unbounded growth - try: - from modules.system import MAX_MSG_HISTORY - max_history = MAX_MSG_HISTORY - except ImportError: - max_history = storeFlimit - - if len(msg_history) >= max_history: - # Remove oldest entries to maintain size limit - msg_history = msg_history[-(max_history-1):] - + + # trim the history list if it exceeds max_history + if len(msg_history) >= MAX_MSG_HISTORY: + # Remove oldest entries by cutting in half + msg_history = msg_history[len(msg_history)//2:] + + # add the message to the history list msg_history.append((get_name_from_number(message_from_id, 'long', rxNode), message_string, channel_number, timestamp, rxNode)) # print the message to the log and sdout @@ -1550,7 +1534,7 @@ async def start_rx(): if highfly_enabled: logger.debug(f"System: HighFly Enabled using {highfly_altitude}m limit reporting to channel:{highfly_channel}") if store_forward_enabled: - logger.debug(f"System: Store and Forward Enabled using limit: {storeFlimit}") + logger.debug(f"System: S&F(messages command) Enabled using limit: {storeFlimit}") if useDMForResponse: logger.debug(f"System: Respond by DM only") if enableEcho: diff --git a/modules/smtp.py b/modules/smtp.py index c4e3ab6..b469eb8 100644 --- a/modules/smtp.py +++ b/modules/smtp.py @@ -152,6 +152,12 @@ def store_sms(nodeID, sms): global sms_db try: logger.debug("System: Setting SMS for " + str(nodeID)) + # if the nodeID has over 5 sms addresses warn and return + for item in sms_db: + if item['nodeID'] == nodeID: + if len(item['sms']) >= 5: + logger.warning("System: 📵SMS limit reached for " + str(nodeID)) + return False # if not in db, add it if nodeID not in sms_db: sms_db.append({'nodeID': nodeID, 'sms': sms}) diff --git a/modules/system.py b/modules/system.py index 4947941..0401429 100644 --- a/modules/system.py +++ b/modules/system.py @@ -7,9 +7,10 @@ import meshtastic.ble_interface import time import asyncio import random +# not ideal but needed? import contextlib # for suppressing output on watchdog import io # for suppressing output on watchdog -import atexit # for graceful shutdown +# homebrew 'modules' from modules.log import * # Global Variables @@ -21,22 +22,22 @@ multiPingList = [{'message_from_id': 0, 'count': 0, 'type': '', 'deviceID': 0, ' interface_retry_count = 3 # Memory Management Constants -MAX_CMD_HISTORY = 1000 -MAX_SEEN_NODES = 500 MAX_MSG_HISTORY = 100 -CLEANUP_INTERVAL = 3600 # 1 hour -last_cleanup_time = 0 +MAX_CMD_HISTORY = 200 +MAX_SEEN_NODES = 200 +CLEANUP_INTERVAL = 86400 # 24 hours in seconds +GAMEDELAY = CLEANUP_INTERVAL # the age of game entries in seconds before they are cleaned up def cleanup_memory(): """Clean up memory by limiting list sizes and removing stale entries""" - global cmdHistory, seenNodes, last_cleanup_time + global cmdHistory, seenNodes, multiPingList current_time = time.time() try: # Limit cmdHistory size if 'cmdHistory' in globals() and len(cmdHistory) > MAX_CMD_HISTORY: - cmdHistory = cmdHistory[-MAX_CMD_HISTORY:] - logger.debug(f"System: Trimmed cmdHistory to {MAX_CMD_HISTORY} entries") + cmdHistory = cmdHistory[-(MAX_CMD_HISTORY - 50):] # keep the most recent 50 entries + logger.debug(f"System: Trimmed cmdHistory to {len(cmdHistory)} entries") # Clean up old seenNodes entries (older than 24 hours) if 'seenNodes' in globals(): @@ -55,8 +56,6 @@ def cleanup_memory(): if ping.get('message_from_id', 0) != 0 and ping.get('count', 0) > 0] - last_cleanup_time = current_time - except Exception as e: logger.error(f"System: Error during memory cleanup: {e}") @@ -1480,6 +1479,10 @@ async def watchdog(): load_bbsdm() load_bbsdb() + # perform memory cleanup every 10 minutes + if datetime.now().minute % 10 == 0: + cleanup_memory() + def exit_handler(): # Close the interface and save the BBS messages logger.debug(f"System: Closing Autoresponder") diff --git a/pong_bot.py b/pong_bot.py index ef282dc..f74c7ae 100755 --- a/pong_bot.py +++ b/pong_bot.py @@ -204,14 +204,6 @@ def handle_lheard(message, nodeid, deviceID, isDM): 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'LastSeen\n{history}' - else: - # trim the last \n - bot_response = bot_response[:-1] - # bot_response += getNodeTelemetry(deviceID) return bot_response @@ -453,7 +445,7 @@ async def start_rx(): if sentry_enabled: logger.debug(f"System: Sentry Mode Enabled {sentry_radius}m radius reporting to channel:{secure_channel}") if store_forward_enabled: - logger.debug(f"System: Store and Forward Enabled using limit: {storeFlimit}") + logger.debug(f"System: S&F(messages command) Enabled using limit: {storeFlimit}") if useDMForResponse: logger.debug(f"System: Respond by DM only") if repeater_enabled and multiple_interface: