Просмотр исходного кода

Adding default_value to CogSetting. Better config value formatting.

pull/13/head
Rocketsoup 2 месяцев назад
Родитель
Сommit
abd45c00f0

+ 17
- 7
rocketbot/cogs/autokickcog.py Просмотреть файл

33
 	"""
33
 	"""
34
 	Cog for automatically kicking ALL new joins. For temporary use during join raids.
34
 	Cog for automatically kicking ALL new joins. For temporary use during join raids.
35
 	"""
35
 	"""
36
-	SETTING_ENABLED = CogSetting('enabled', bool,
36
+	SETTING_ENABLED = CogSetting(
37
+		'enabled',
38
+		bool,
39
+		default_value=False,
37
 		brief='autokick',
40
 		brief='autokick',
38
-		description='Whether this cog is enabled for a guild.')
39
-	SETTING_BAN_COUNT = CogSetting('bancount', int,
41
+		description='Whether this cog is enabled for a guild.',
42
+	)
43
+	SETTING_BAN_COUNT = CogSetting(
44
+		'bancount',
45
+		int,
46
+		default_value=0,
40
 		brief='number of repeat kicks before a ban',
47
 		brief='number of repeat kicks before a ban',
41
 		description='The number of times a user can join and be kicked '
48
 		description='The number of times a user can join and be kicked '
42
 					'before the next rejoin will result in a ban. A value of 0 '
49
 					'before the next rejoin will result in a ban. A value of 0 '
43
 					'disables this feature (only kick, never ban).',
50
 					'disables this feature (only kick, never ban).',
44
-		usage='<count:int>',
45
-		min_value=0)
46
-	SETTING_OFFLINE_ONLY = CogSetting('offlineonly', bool,
51
+		min_value=0,
52
+	)
53
+	SETTING_OFFLINE_ONLY = CogSetting(
54
+		'offlineonly',
55
+		bool,
56
+		default_value=False,
47
 		brief='whether to only kick users whose status is offline',
57
 		brief='whether to only kick users whose status is offline',
48
 		description='Compromised accounts may have a status of offline. '
58
 		description='Compromised accounts may have a status of offline. '
49
 					'If this setting is enabled, the user\'s status will be '
59
 					'If this setting is enabled, the user\'s status will be '
50
 					'checked a few seconds after joining. If it is offline '
60
 					'checked a few seconds after joining. If it is offline '
51
 					'they will be kicked.',
61
 					'they will be kicked.',
52
-		usage='<true|false>')
62
+	)
53
 
63
 
54
 	STATE_KEY_RECENT_KICKS = "AutoKickCog.recent_joins"
64
 	STATE_KEY_RECENT_KICKS = "AutoKickCog.recent_joins"
55
 
65
 

+ 4
- 1
rocketbot/cogs/basecog.py Просмотреть файл

138
 			if value is not None:
138
 			if value is not None:
139
 				return value
139
 				return value
140
 		if use_cog_default_if_not_set:
140
 		if use_cog_default_if_not_set:
141
-			return cls.get_cog_default(setting.name)
141
+			config_default = cls.get_cog_default(setting.name)
142
+			if config_default is not None:
143
+				return None
144
+			return setting.default_value
142
 		return None
145
 		return None
143
 
146
 
144
 	@classmethod
147
 	@classmethod

+ 44
- 22
rocketbot/cogs/crosspostcog.py Просмотреть файл

45
 	often be for a reason or due to trying a failed post when connectivity is
45
 	often be for a reason or due to trying a failed post when connectivity is
46
 	poor. Minimum message length can be enforced for detection.
46
 	poor. Minimum message length can be enforced for detection.
47
 	"""
47
 	"""
48
-	SETTING_ENABLED = CogSetting('enabled', bool,
48
+	SETTING_ENABLED = CogSetting(
49
+		'enabled',
50
+		bool,
51
+		default_value=False,
49
 		brief='crosspost detection',
52
 		brief='crosspost detection',
50
-		description='Whether crosspost detection is enabled.')
51
-	SETTING_WARN_COUNT = CogSetting('warncount', int,
53
+		description='Whether crosspost detection is enabled.',
54
+	)
55
+	SETTING_WARN_COUNT = CogSetting(
56
+		'warncount',
57
+		int,
58
+		default_value=5,
52
 		brief='number of messages to trigger a warning',
59
 		brief='number of messages to trigger a warning',
53
 		description='The number of unique channels messages are ' + \
60
 		description='The number of unique channels messages are ' + \
54
 			'posted in by the same user to trigger a mod warning. The ' + \
61
 			'posted in by the same user to trigger a mod warning. The ' + \
55
 			'messages need not be identical (see dupewarncount).',
62
 			'messages need not be identical (see dupewarncount).',
56
-		usage='<count:int>',
57
-		min_value=2)
58
-	SETTING_DUPE_WARN_COUNT = CogSetting('dupewarncount', int,
63
+		min_value=2,
64
+	)
65
+	SETTING_DUPE_WARN_COUNT = CogSetting(
66
+		'dupewarncount',
67
+		int,
68
+		default_value=3,
59
 		brief='number of identical messages to trigger a warning',
69
 		brief='number of identical messages to trigger a warning',
60
 		description='The number of unique channels identical messages are ' + \
70
 		description='The number of unique channels identical messages are ' + \
61
 			'posted in by the same user to trigger a mod warning.',
71
 			'posted in by the same user to trigger a mod warning.',
62
-		usage='<count:int>',
63
-		min_value=2)
64
-	SETTING_BAN_COUNT = CogSetting('bancount', int,
72
+		min_value=2,
73
+	)
74
+	SETTING_BAN_COUNT = CogSetting(
75
+		'bancount',
76
+		int,
77
+		default_value=9999,
65
 		brief='number of messages to trigger a ban',
78
 		brief='number of messages to trigger a ban',
66
 		description='The number of unique channels messages are ' + \
79
 		description='The number of unique channels messages are ' + \
67
 			'posted in by the same user to trigger an automatic ban. The ' + \
80
 			'posted in by the same user to trigger an automatic ban. The ' + \
68
 			'messages need not be identical (see dupebancount). Set ' + \
81
 			'messages need not be identical (see dupebancount). Set ' + \
69
 			'to a large value to effectively disable, e.g. 9999.',
82
 			'to a large value to effectively disable, e.g. 9999.',
70
-		usage='<count:int>',
71
-		min_value=2)
72
-	SETTING_DUPE_BAN_COUNT = CogSetting('dupebancount', int,
83
+		min_value=2,
84
+	)
85
+	SETTING_DUPE_BAN_COUNT = CogSetting(
86
+		'dupebancount',
87
+		int,
88
+		default_value=9999,
73
 		brief='number of identical messages to trigger a ban',
89
 		brief='number of identical messages to trigger a ban',
74
 		description='The number of unique channels identical messages are ' + \
90
 		description='The number of unique channels identical messages are ' + \
75
 			'posted in by the same user to trigger an automatic ban. Set ' + \
91
 			'posted in by the same user to trigger an automatic ban. Set ' + \
76
 			'to a large value to effectively disable, e.g. 9999.',
92
 			'to a large value to effectively disable, e.g. 9999.',
77
-		usage='<count:int>',
78
-		min_value=2)
79
-	SETTING_MIN_LENGTH = CogSetting('minlength', int,
93
+		min_value=2,
94
+	)
95
+	SETTING_MIN_LENGTH = CogSetting(
96
+		'minlength',
97
+		int,
98
+		default_value=1,
80
 		brief='minimum message length',
99
 		brief='minimum message length',
81
 		description='The minimum number of characters in a message to be ' + \
100
 		description='The minimum number of characters in a message to be ' + \
82
 			'checked for duplicates. This can help ignore common short ' + \
101
 			'checked for duplicates. This can help ignore common short ' + \
83
 			'messages like "lol" or a single emoji.',
102
 			'messages like "lol" or a single emoji.',
84
-		usage='<character_count:int>',
85
-		min_value=1)
86
-	SETTING_TIMESPAN = CogSetting('timespan', timedelta,
103
+		min_value=1,
104
+	)
105
+	SETTING_TIMESPAN = CogSetting(
106
+		'timespan',
107
+		timedelta,
108
+		default_value=timedelta(seconds=60),
87
 		brief='time window to look for dupe messages',
109
 		brief='time window to look for dupe messages',
88
-		description='The number of seconds of message history to look at ' + \
89
-			'when looking for duplicates. Shorter values are preferred, ' + \
110
+		description='The number of seconds of message history to look at '
111
+			'when looking for duplicates. Shorter values are preferred, '
90
 			'both to detect bots and avoid excessive memory usage.',
112
 			'both to detect bots and avoid excessive memory usage.',
91
-		usage='<seconds:int>',
92
-		min_value=timedelta(seconds=1))
113
+		min_value=timedelta(seconds=1),
114
+	)
93
 
115
 
94
 	STATE_KEY_RECENT_MESSAGES = "CrossPostCog.recent_messages"
116
 	STATE_KEY_RECENT_MESSAGES = "CrossPostCog.recent_messages"
95
 	STATE_KEY_SPAM_CONTEXT = "CrossPostCog.spam_context"
117
 	STATE_KEY_SPAM_CONTEXT = "CrossPostCog.spam_context"

+ 27
- 17
rocketbot/cogs/joinraidcog.py Просмотреть файл

29
 	"""
29
 	"""
30
 	Cog for monitoring member joins and detecting potential bot raids.
30
 	Cog for monitoring member joins and detecting potential bot raids.
31
 	"""
31
 	"""
32
-	SETTING_ENABLED = CogSetting('enabled', bool,
33
-			brief='join raid detection',
34
-			description='Whether this cog is enabled for a guild.')
35
-	SETTING_JOIN_COUNT = CogSetting('joincount', int,
36
-			brief='number of joins to trigger a warning',
37
-			description='The number of joins occuring within the time ' + \
38
-				'window to trigger a mod warning.',
39
-			usage='<count:int>',
40
-			min_value=2)
41
-	SETTING_JOIN_TIME = CogSetting('jointime', timedelta,
42
-			brief='time window length to look for joins',
43
-			description='The number of seconds of join history to look ' + \
44
-				'at when counting recent joins. If joincount or more ' + \
45
-				'joins occur within jointime seconds a mod warning is issued.',
46
-			usage='<seconds:float>',
47
-			min_value=timedelta(seconds=1.0),
48
-			max_value=timedelta(seconds=900.0))
32
+	SETTING_ENABLED = CogSetting(
33
+		'enabled',
34
+		bool,
35
+		default_value=False,
36
+		brief='join raid detection',
37
+		description='Whether this cog is enabled for a guild.',
38
+	)
39
+	SETTING_JOIN_COUNT = CogSetting(
40
+		'joincount',
41
+		int,
42
+		default_value=5,
43
+		brief='number of joins to trigger a warning',
44
+		description='The number of joins occurring within the time '
45
+					'window to trigger a mod warning.',
46
+		min_value=2,
47
+	)
48
+	SETTING_JOIN_TIME = CogSetting(
49
+		'jointime',
50
+		timedelta,
51
+		default_value=timedelta(seconds=5),
52
+		brief='time window length to look for joins',
53
+		description='The number of seconds of join history to look '
54
+					'at when counting recent joins. If joincount or more '
55
+				    'joins occur within jointime seconds a mod warning is issued.',
56
+		min_value=timedelta(seconds=1.0),
57
+		max_value=timedelta(seconds=900.0),
58
+	)
49
 
59
 
50
 	STATE_KEY_RECENT_JOINS = "JoinRaidCog.recent_joins"
60
 	STATE_KEY_RECENT_JOINS = "JoinRaidCog.recent_joins"
51
 	STATE_KEY_LAST_RAID = "JoinRaidCog.last_raid"
61
 	STATE_KEY_LAST_RAID = "JoinRaidCog.last_raid"

+ 7
- 3
rocketbot/cogs/logcog.py Просмотреть файл

38
 	"""
38
 	"""
39
 	Cog for logging notable events to a designated logging channel.
39
 	Cog for logging notable events to a designated logging channel.
40
 	"""
40
 	"""
41
-	SETTING_ENABLED = CogSetting('enabled', bool,
42
-			brief='logging',
43
-			description='Whether this cog is enabled for a guild.')
41
+	SETTING_ENABLED = CogSetting(
42
+		'enabled',
43
+		bool,
44
+		default_value=False,
45
+		brief='logging',
46
+		description='Whether this cog is enabled for a guild.',
47
+	)
44
 
48
 
45
 	STATE_EVENT_BUFFER = 'LoggingCog.eventBuffer'
49
 	STATE_EVENT_BUFFER = 'LoggingCog.eventBuffer'
46
 
50
 

+ 1
- 1
rocketbot/cogs/patterncog.py Просмотреть файл

91
 	various criteria. Patterns can be defined by mods for each guild.
91
 	various criteria. Patterns can be defined by mods for each guild.
92
 	"""
92
 	"""
93
 
93
 
94
-	SETTING_PATTERNS = CogSetting('patterns', None)
94
+	SETTING_PATTERNS = CogSetting('patterns', None, default_value=None)
95
 
95
 
96
 	shared: Optional['PatternCog'] = None
96
 	shared: Optional['PatternCog'] = None
97
 
97
 

+ 38
- 23
rocketbot/cogs/urlspamcog.py Просмотреть файл

29
 	Can be configured to take immediate action or just warn the mods.
29
 	Can be configured to take immediate action or just warn the mods.
30
 	"""
30
 	"""
31
 
31
 
32
-	SETTING_ENABLED = CogSetting('enabled', bool,
33
-			brief='URL spam detection',
34
-			description='Whether URLs posted soon after joining are flagged.')
35
-	SETTING_ACTION = CogSetting('action', Literal['nothing', 'modwarn', 'delete', 'kick', 'ban'],
36
-			brief='action to take on spam',
37
-			description='The action to take on detected URL spam.',
38
-			enum_values={'nothing', 'modwarn', 'delete', 'kick', 'ban'})
39
-	SETTING_JOIN_AGE = CogSetting('joinage', timedelta,
40
-			brief='seconds since member joined',
41
-			description='The minimum seconds since the user joined the '
42
-				'server before they can post URLs. URLs posted by users '
43
-				'who joined too recently will be flagged. Keep in mind '
44
-				'many servers have a minimum 10 minute cooldown before '
45
-				'new members can say anything. Setting to 0 effectively '
46
-				'disables URL spam detection.',
47
-			usage='<seconds:int>',
48
-			min_value=timedelta(seconds=0))
49
-	SETTING_DECEPTIVE_ACTION = CogSetting('deceptiveaction', Literal['nothing', 'modwarn', 'modwarndelete', 'chatwarn', 'chatwarndelete', 'delete', 'kick', 'ban'],
50
-			brief='action to take on deceptive link markdown',
51
-			description='The action to take on chat messages with links '
52
-				'where the text looks like a different URL than the actual link.',
53
-			enum_values={'nothing', 'modwarn', 'modwarndelete',
54
-				'chatwarn', 'chatwarndelete', 'delete', 'kick', 'ban'})
32
+	SETTING_ENABLED = CogSetting(
33
+		'enabled',
34
+		bool,
35
+		default_value=False,
36
+		brief='URL spam detection',
37
+		description='Whether URLs posted soon after joining are flagged.',
38
+	)
39
+	SETTING_ACTION = CogSetting(
40
+		'action',
41
+		Literal['nothing', 'modwarn', 'delete', 'kick', 'ban'],
42
+		default_value='nothing',
43
+		brief='action to take on spam',
44
+		description='The action to take on detected URL spam.',
45
+		enum_values={'nothing', 'modwarn', 'delete', 'kick', 'ban'},
46
+	)
47
+	SETTING_JOIN_AGE = CogSetting(
48
+		'joinage',
49
+		timedelta,
50
+		default_value=timedelta(minutes=15),
51
+		brief='seconds since member joined',
52
+		description='The minimum seconds since the user joined the '
53
+					'server before they can post URLs. URLs posted by users '
54
+				    'who joined too recently will be flagged. Keep in mind '
55
+				    'many servers have a minimum 10 minute cooldown before '
56
+				    'new members can say anything. Setting to 0 effectively '
57
+				    'disables URL spam detection.',
58
+		min_value=timedelta(seconds=0),
59
+	)
60
+	SETTING_DECEPTIVE_ACTION = CogSetting(
61
+		'deceptiveaction',
62
+		Literal['nothing', 'modwarn', 'modwarndelete', 'chatwarn', 'chatwarndelete', 'delete', 'kick', 'ban'],
63
+		default_value='nothing',
64
+		brief='action to take on deceptive link markdown',
65
+		description='The action to take on chat messages with links '
66
+					'where the text looks like a different URL than the actual link.',
67
+		enum_values={'nothing', 'modwarn', 'modwarndelete',
68
+					 'chatwarn', 'chatwarndelete', 'delete', 'kick', 'ban'},
69
+	)
55
 
70
 
56
 	def __init__(self, bot):
71
 	def __init__(self, bot):
57
 		super().__init__(
72
 		super().__init__(

+ 8
- 4
rocketbot/cogs/usernamecog.py Просмотреть файл

47
 	message on a match.
47
 	message on a match.
48
 	"""
48
 	"""
49
 
49
 
50
-	SETTING_ENABLED = CogSetting('enabled', bool,
51
-			brief='username pattern detection',
52
-			description='Whether new users are checked for common patterns.')
50
+	SETTING_ENABLED = CogSetting(
51
+		'enabled',
52
+		bool,
53
+		default_value=False,
54
+		brief='username pattern detection',
55
+		description='Whether new users are checked for common patterns.',
56
+	)
53
 
57
 
54
-	SETTING_PATTERNS = CogSetting('patterns', None)
58
+	SETTING_PATTERNS = CogSetting('patterns', None, default_value=None)
55
 
59
 
56
 	def __init__(self, bot):
60
 	def __init__(self, bot):
57
 		super().__init__(
61
 		super().__init__(

+ 22
- 11
rocketbot/cogsetting.py Просмотреть файл

11
 
11
 
12
 from config import CONFIG
12
 from config import CONFIG
13
 from rocketbot.storage import Storage
13
 from rocketbot.storage import Storage
14
-from rocketbot.utils import bot_log, TimeDeltaTransformer, MOD_PERMISSIONS, dump_stacktrace
14
+from rocketbot.utils import bot_log, TimeDeltaTransformer, MOD_PERMISSIONS, dump_stacktrace, str_from_timedelta
15
+
15
 
16
 
16
 # def _fix_command(command: Command) -> None:
17
 # def _fix_command(command: Command) -> None:
17
 # 	"""
18
 # 	"""
35
 	def __init__(self,
36
 	def __init__(self,
36
 			name: str,
37
 			name: str,
37
 			datatype: Optional[Type],
38
 			datatype: Optional[Type],
39
+			default_value: Any,
38
 			brief: Optional[str] = None,
40
 			brief: Optional[str] = None,
39
 			description: Optional[str] = None,
41
 			description: Optional[str] = None,
40
-			usage: Optional[str] = None,
41
 			min_value: Optional[Any] = None,
42
 			min_value: Optional[Any] = None,
42
 			max_value: Optional[Any] = None,
43
 			max_value: Optional[Any] = None,
43
 			enum_values: Optional[set[Any]] = None):
44
 			enum_values: Optional[set[Any]] = None):
48
 			Setting identifier. Must follow variable naming conventions.
49
 			Setting identifier. Must follow variable naming conventions.
49
 		datatype: Optional[Type]
50
 		datatype: Optional[Type]
50
 		    Datatype of the setting. E.g. int, float, str
51
 		    Datatype of the setting. E.g. int, float, str
52
+		default_value: Any
53
+			Value to use in the absence of a specified value for the guild and
54
+			no value in config.py.
51
 		brief: Optional[str]
55
 		brief: Optional[str]
52
 			Description of the setting, starting with lower case.
56
 			Description of the setting, starting with lower case.
53
 			Will be inserted into phrases like "Sets <brief>" and
57
 			Will be inserted into phrases like "Sets <brief>" and
55
 		description: Optional[str]
59
 		description: Optional[str]
56
 		  	Long-form description. Min, max, and enum values will be
60
 		  	Long-form description. Min, max, and enum values will be
57
 		    appended to the end, so does not need to include these.
61
 		    appended to the end, so does not need to include these.
58
-		usage: Optional[str]
59
-		    Description of the value argument in a set command, e.g. "<maxcount:int>"
60
 		min_value: Optional[Any]
62
 		min_value: Optional[Any]
61
 		    Smallest allowable value. Must be of the same datatype as
63
 		    Smallest allowable value. Must be of the same datatype as
62
 		    the value. None for no minimum.
64
 		    the value. None for no minimum.
67
 		"""
69
 		"""
68
 		self.name: str = name
70
 		self.name: str = name
69
 		self.datatype: Type = datatype
71
 		self.datatype: Type = datatype
72
+		self.default_value = default_value
70
 		self.brief: Optional[str] = brief
73
 		self.brief: Optional[str] = brief
71
 		self.description: str = description or ''  # Can't be None
74
 		self.description: str = description or ''  # Can't be None
72
-		self.usage: Optional[str] = usage
73
 		self.min_value: Optional[Any] = min_value
75
 		self.min_value: Optional[Any] = min_value
74
 		self.max_value: Optional[Any] = max_value
76
 		self.max_value: Optional[Any] = max_value
75
 		self.enum_values: Optional[set[Any]] = enum_values
77
 		self.enum_values: Optional[set[Any]] = enum_values
117
 			return timedelta(seconds=stored_value)
119
 			return timedelta(seconds=stored_value)
118
 		return stored_value
120
 		return stored_value
119
 
121
 
122
+	def native_value_to_str(self, native_value: Any) -> str:
123
+		if native_value is None:
124
+			return '<no value>'
125
+		if isinstance(native_value, timedelta):
126
+			return str_from_timedelta(native_value)
127
+		if isinstance(native_value, bool):
128
+			return 'true' if native_value else 'false'
129
+		return f'{native_value}'
130
+
120
 	def __make_getter_command(self, cog: 'BaseCog') -> Command:
131
 	def __make_getter_command(self, cog: 'BaseCog') -> Command:
121
 		setting: CogSetting = self
132
 		setting: CogSetting = self
122
 		setting_name = setting.name
133
 		setting_name = setting.name
130
 			if value is None:
141
 			if value is None:
131
 				value = setting.to_native_value(cog0.get_cog_default(setting.name))
142
 				value = setting.to_native_value(cog0.get_cog_default(setting.name))
132
 				await interaction.response.send_message(
143
 				await interaction.response.send_message(
133
-					f'{CONFIG["info_emoji"]} `{setting_name}` is using default of `{value}`',
144
+					f'{CONFIG["info_emoji"]} `{setting_name}` is using default of `{setting.native_value_to_str(value)}`',
134
 					ephemeral=True
145
 					ephemeral=True
135
 				)
146
 				)
136
 			else:
147
 			else:
137
 				await interaction.response.send_message(
148
 				await interaction.response.send_message(
138
-					f'{CONFIG["info_emoji"]} `{setting_name}` is set to `{value}`',
149
+					f'{CONFIG["info_emoji"]} `{setting_name}` is set to `{setting.native_value_to_str(value)}`',
139
 					ephemeral=True
150
 					ephemeral=True
140
 				)
151
 				)
141
 
152
 
178
 			key = f'{cog0.__class__.__name__}.{setting.name}'
189
 			key = f'{cog0.__class__.__name__}.{setting.name}'
179
 			Storage.set_config_value(interaction.guild, key, setting.to_stored_value(new_value))
190
 			Storage.set_config_value(interaction.guild, key, setting.to_stored_value(new_value))
180
 			await interaction.response.send_message(
191
 			await interaction.response.send_message(
181
-				f'{CONFIG["success_emoji"]} `{setting_name}` is now set to `{new_value}`',
192
+				f'{CONFIG["success_emoji"]} `{setting_name}` is now set to `{setting.to_native_value(new_value)}`',
182
 				ephemeral=True
193
 				ephemeral=True
183
 			)
194
 			)
184
 			await cog0.on_setting_updated(interaction.guild, setting)
195
 			await cog0.on_setting_updated(interaction.guild, setting)
410
 							if value is not None:
421
 							if value is not None:
411
 								text += '**' + ('enabled' if value else 'disabled') + '**'
422
 								text += '**' + ('enabled' if value else 'disabled') + '**'
412
 							else:
423
 							else:
413
-								text += ('enabled' if deflt else 'disabled') + ' _(using default)_'
424
+								text += ('enabled' if deflt else 'disabled') + ' _(default)_'
414
 						else:
425
 						else:
415
 							if value is not None:
426
 							if value is not None:
416
-								text += f'\n- `{bcog.config_prefix}_{setting.name}` = **{value}**'
427
+								text += f'\n- `{bcog.config_prefix}_{setting.name}` = **{setting.native_value_to_str(value)}**'
417
 							else:
428
 							else:
418
-								text += f'\n- `{bcog.config_prefix}_{setting.name}` = {deflt} _(using default)_'
429
+								text += f'\n- `{bcog.config_prefix}_{setting.name}` = {setting.native_value_to_str(deflt)} _(using default)_'
419
 				await interaction.response.send_message(
430
 				await interaction.response.send_message(
420
 					text,
431
 					text,
421
 					ephemeral=True,
432
 					ephemeral=True,

Загрузка…
Отмена
Сохранить