Skip to content

Commit

Permalink
Various fixes and enhancements
Browse files Browse the repository at this point in the history
- Fix an issue when issuing WHO on a target we share nothing with.
- Fix traceback messages leaking data inside of the exception message
  portion when user/channel data level is set to anonymize data.
- Add configuration to disable automatic warnings from the reaper.
  • Loading branch information
skizzerz committed Mar 29, 2024
1 parent 4aeeb6d commit 2f68f83
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 6 deletions.
11 changes: 11 additions & 0 deletions botconfig.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,14 @@ gameplay:
notice: true
# Include which user is spectating in the above alert, if enabled.
include_user: false

# Reaper. Users that leave during the game or are otherwise idle will be automatically removed from the game
# after a period of time (by killing them in-game). This allows a game to continue onwards with the active players
# rather than being in a standstill. It is recommended to keep the reaper enabled for this reason, however the reaper
# will also automatically issue warning points to users by default, which can eventually cause stasis (aka time-outs)
# or temporary bans from the channel.
reaper:
# Whether or not the reaper is enabled. If disabled, idle or disconnected users are NOT automatically killed
enabled: true
# If the reaper is enabled, should it issue automatic warning points to people it kills?
autowarn: true
13 changes: 11 additions & 2 deletions src/debug/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ def __exit__(self, exc_type: Optional[type], exc_value: Optional[BaseException],
if _local.handler is None:
_local.handler = chain_exceptions(exc_value)

user_data_level = config.Main.get("telemetry.errors.user_data_level")
channel_data_level = config.Main.get("telemetry.errors.user_data_level")
traceback_verbosity = config.Main.get("telemetry.errors.traceback_verbosity")
if traceback_verbosity > 0:
word = "\nLocal variables from frame #{0} (in {1}):\n"
Expand Down Expand Up @@ -159,7 +161,7 @@ def __exit__(self, exc_type: Optional[type], exc_value: Optional[BaseException],
variables.append("{0} = {1!r}".format(key, value))

# dump full list of known users with verbose output, as everything above has truncated output for readability
if config.Main.get("telemetry.errors.user_data_level") > 1:
if user_data_level > 1:
import src.users
variables.append("\nAll connected users:\n")
for user in src.users.users():
Expand All @@ -183,7 +185,14 @@ def __exit__(self, exc_type: Optional[type], exc_value: Optional[BaseException],

# sanitize paths in tb: convert backslash to forward slash and remove prefixes from src and library paths
variables[1] = variables[1].replace("\\", "/")
variables[1] = re.sub(r'File "[^"]*/(src|gamemodes|oyoyo|roles|[Ll]ib|wolfbot)', r'File "/\1', variables[1])
variables[1] = re.sub(r'File "[^"]*?/(src|gamemodes|oyoyo|messages|hooks|roles|[Ll]ib|wolfbot)', r'File "/\1', variables[1])

# the exception message may leak user/channel data since it was stringified without our custom "for_tb" format
if user_data_level < 2:
variables[1] = re.sub(r'User\(([^,]+),.*\)', r'User(\1)' if user_data_level == 1 else "User(?)", variables[1])

if channel_data_level < 1:
variables[1] = re.sub(r'Channel\(.*\)', "Channel(?)", variables[1])

# sanitize values within local frames
if len(variables) > 3:
Expand Down
8 changes: 8 additions & 0 deletions src/defaultsettings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,14 @@ reaper: &reaper
_desc: Whether or not the reaper is enabled. If disabled, nobody will idle out or get automatic warnings.
_type: bool
_default: true
autowarn:
_desc: >
Whether or not to automatically issue warnings to users who are killed by the reaper. If disabled,
users will still be removed from the game and are guaranteed a game loss, but there will be no further
consequences applied to them. If this setting is disabled, the various points settings elsewhere in reaper
settings have no effect.
_type: bool
_default: true
idle:
_desc: >
Idle time is defined as how long it has been since the user has spoken in channel. If gameplay.nightchat
Expand Down
4 changes: 3 additions & 1 deletion src/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,9 @@ def end_who(cli, bot_server, bot_nick, target, rest):
else:
target.dispatch_queue()

old = _who_old.get(target.name, target)
old = None
if target is not None:
old = _who_old.get(target.name, target)
_who_old.clear()
Event("who_end", {}, old=old).dispatch(target)

Expand Down
6 changes: 3 additions & 3 deletions src/reaper.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def reaper(var: GameState, gameid: int):
# part_death, part_death_no_reveal, part_warning
# account_death, account_death_no_reveal, account_warning
channels.Main.send(messages[f"{what}_death{reveal}"].format(dcedplayer, revealrole))
if var.current_phase != "join":
if config.Main.get("reaper.autowarn") and var.current_phase != "join":
NIGHT_IDLED.discard(dcedplayer) # don't double-dip if they idled out night as well
add_warning(dcedplayer,
config.Main.get(f"reaper.{what}.points"),
Expand Down Expand Up @@ -120,7 +120,7 @@ def reaper(var: GameState, gameid: int):
channels.Main.send(messages[f"idle_death{reveal}"].format(user, get_reveal_role(var, user)))
if var.in_game:
DCED_LOSERS.add(user)
if config.Main.get("reaper.idle.enabled"):
if config.Main.get("reaper.autowarn") and config.Main.get("reaper.idle.enabled"):
NIGHT_IDLED.discard(user) # don't double-dip if they idled out night as well
add_warning(user, config.Main.get("reaper.idle.points"), users.Bot, messages["idle_warning"], expires=config.Main.get("reaper.idle.expiration"))
add_dying(var, user, "bot", "idle", death_triggers=False)
Expand Down Expand Up @@ -198,7 +198,7 @@ def on_del_player(evt: Event, var: GameState, player: User, all_roles: set[str],
@event_listener("reset")
def on_reset(evt: Event, var: GameState):
# Add warnings for people that idled out night
if config.Main.get("reaper.night_idle.enabled"):
if config.Main.get("reaper.autowarn") and config.Main.get("reaper.night_idle.enabled"):
for player in NIGHT_IDLED:
if player.is_fake:
continue
Expand Down

0 comments on commit 2f68f83

Please sign in to comment.