diff --git a/config.ini.example b/config.ini.example index f9b271d..15b6d18 100644 --- a/config.ini.example +++ b/config.ini.example @@ -157,6 +157,12 @@ respond_to_dms = true # Set a custom prefix length for the public keys to identify repeaters prefix_bytes = 1 +# Flood scope for channel messages (MeshCore regions; optional) +# Empty, * or 0: classic flood (default). Set to a region name (e.g. west) to limit +# channel sends to that scope. Dynamic "reply with same scope as sender" is not +# supported until the protocol exposes scope on received channel messages. +# flood_scope = + [Banned_Users] # List of banned sender names (comma-separated). Matching is prefix (starts-with): # "Awful Username" also matches "Awful Username 🍆". No bot responses in channels or DMs. diff --git a/docs/config-validation.md b/docs/config-validation.md index 7b8a72c..5f42c86 100644 --- a/docs/config-validation.md +++ b/docs/config-validation.md @@ -31,7 +31,7 @@ The bot will not start without these sections. The validator reports them as **e |----------------|----------------------------------------------| | `[Connection]` | Serial, BLE, or TCP connection parameters | | `[Bot]` | Database path, bot name, rate limits, etc. | -| `[Channels]` | Monitor channels, DM behavior | +| `[Channels]` | Monitor channels, DM behavior, optional flood_scope (scoped flooding) | ### Section names diff --git a/modules/command_manager.py b/modules/command_manager.py index d13220f..e65199b 100644 --- a/modules/command_manager.py +++ b/modules/command_manager.py @@ -890,20 +890,13 @@ class CommandManager: command_id: Optional[str] = None, skip_user_rate_limit: bool = False, rate_limit_key: Optional[str] = None, + scope: Optional[str] = None, ) -> bool: - """Send a channel message using meshcore-cli command. + """Send a channel message using meshcore_py (optional flood scope). Resolves channel names to numbers and handles rate limiting. - - Args: - channel: The channel name (e.g., "LongFast"). - content: The message content to send. - command_id: Optional command_id for repeat tracking (if not provided, one will be generated). - skip_user_rate_limit: If True, skip user rate limiter checks (for automated responses). - rate_limit_key: Optional key for per-user rate limiting (e.g. from get_rate_limit_key(message)). - - Returns: - bool: True if sent successfully, False otherwise. + If [Channels] flood_scope is set (or scope is passed), uses that scope + for this send then restores global flood. Scope values "" / "*" / "0" mean global. """ if not self.bot.connected or not self.bot.meshcore: return False @@ -943,9 +936,21 @@ class CommandManager: self.logger.debug(f"Error recording transmission for repeat tracking: {e}") # Don't fail the send if transmission tracking fails - # Use meshcore-cli send_chan_msg function - from meshcore_cli.meshcore_cli import send_chan_msg - result = await send_chan_msg(self.bot.meshcore, channel_num, content) + # Optional flood scope (region): set before send, restore after + scope_cfg = "" + if self.bot.config.has_section("Channels") and self.bot.config.has_option("Channels", "flood_scope"): + scope_cfg = (self.bot.config.get("Channels", "flood_scope") or "").strip() + scope_to_use = (scope if scope is not None else scope_cfg) or "" + scope_is_global = scope_to_use in ("", "*", "0", "None") + if not scope_is_global and hasattr(self.bot.meshcore.commands, "set_flood_scope"): + await self.bot.meshcore.commands.set_flood_scope(scope_to_use) + + try: + # Use meshcore_py directly (no meshcore-cli for channel sends) + result = await self.bot.meshcore.commands.send_chan_msg(channel_num, content) + finally: + if not scope_is_global and hasattr(self.bot.meshcore.commands, "set_flood_scope"): + await self.bot.meshcore.commands.set_flood_scope("*") # Handle result using unified handler target = f"{channel} (channel {channel_num})" diff --git a/modules/core.py b/modules/core.py index 0b9ef0e..73ccd03 100644 --- a/modules/core.py +++ b/modules/core.py @@ -23,9 +23,6 @@ from dataclasses import dataclass import meshcore from meshcore import EventType -# Import command functions from meshcore-cli -from meshcore_cli.meshcore_cli import send_cmd, send_chan_msg - # Import our modules from .rate_limiter import RateLimiter, BotTxRateLimiter, PerUserRateLimiter, NominatimRateLimiter from .message_handler import MessageHandler