feat: Add command placeholder#1186
Merged
Merged
Conversation
2 tasks
Contributor
There was a problem hiding this comment.
Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:
CommandPlaceholderHandle中的静态_resolvers列表只会在Register()中不断追加,从未被清空或加以保护,因此在重复初始化/重载插件时会注册重复的 resolver;建议让注册过程具备幂等性或改为非静态,并在需要时在插件销毁时进行清理。- 在
Handle中,当遇到未知占位符,或者某个占位符解析为空列表时,会立刻return并静默丢弃该命令;建议要么给玩家一些反馈(例如通过args.Player.SendErrorMessage),要么在失败时直接执行原始命令,而不是静默失败。 - 递归的
ExpandAndExecute会为占位符展开的每一种组合生成一条命令,这个数量可能呈组合爆炸式增长(例如,大型分组中存在多个占位符时);建议为总展开数添加上限或安全保护,以避免过量命令执行和潜在的服务器卡顿。
面向 AI 代理的提示
Please address the comments from this code review:
## Overall Comments
- The static `_resolvers` list in `CommandPlaceholderHandle` is only ever appended to in `Register()` and never cleared or guarded, so repeated plugin initialization/reload will register duplicate resolvers; consider making registration idempotent or non-static, and ensure cleanup on plugin disposal if needed.
- In `Handle`, encountering an unknown placeholder or a placeholder that resolves to an empty list causes an immediate `return` and silently drops the command; consider either giving the player feedback (e.g., via `args.Player.SendErrorMessage`) or executing the original command unchanged instead of failing silently.
- The recursive `ExpandAndExecute` will generate a command for every combination of placeholder expansions, which can grow combinatorially (e.g., large groups with multiple placeholders); consider adding a cap on total expansions or a safety guard to prevent excessive command execution and potential server lag.
## Individual Comments
### Comment 1
<location path="src/ServerTools/CommandPlaceholderHandle.cs" line_range="11-17" />
<code_context>
+{
+ private static readonly List<PlaceholderResolver> _resolvers = [];
+
+ public static void Register()
+ {
+ // *all*
+ _resolvers.Add(new PlaceholderResolver(
+ placeholder => placeholder == "*all*",
+ _ => Plugin.ActivePlayers.Select(p => p.Name)
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Guard against repeated Register calls to avoid growing the static resolver list.
Since `Register` appends to the static `_resolvers` list without checking for prior registration, calling `Plugin.Initialize` multiple times (e.g., on plugin reload) will add duplicate resolvers and cause redundant resolution. Make registration idempotent by either clearing `_resolvers` at the start of `Register` or tracking initialization (e.g., a `bool _initialized` or checking for existing resolvers before adding).
```suggestion
public static void Register()
{
// Ensure repeated registrations (e.g., on plugin reload) don't accumulate duplicate resolvers
_resolvers.Clear();
// *all*
_resolvers.Add(new PlaceholderResolver(
placeholder => placeholder == "*all*",
_ => Plugin.ActivePlayers.Select(p => p.Name)
));
```
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据这些反馈改进之后的评审。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- The static
_resolverslist inCommandPlaceholderHandleis only ever appended to inRegister()and never cleared or guarded, so repeated plugin initialization/reload will register duplicate resolvers; consider making registration idempotent or non-static, and ensure cleanup on plugin disposal if needed. - In
Handle, encountering an unknown placeholder or a placeholder that resolves to an empty list causes an immediatereturnand silently drops the command; consider either giving the player feedback (e.g., viaargs.Player.SendErrorMessage) or executing the original command unchanged instead of failing silently. - The recursive
ExpandAndExecutewill generate a command for every combination of placeholder expansions, which can grow combinatorially (e.g., large groups with multiple placeholders); consider adding a cap on total expansions or a safety guard to prevent excessive command execution and potential server lag.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The static `_resolvers` list in `CommandPlaceholderHandle` is only ever appended to in `Register()` and never cleared or guarded, so repeated plugin initialization/reload will register duplicate resolvers; consider making registration idempotent or non-static, and ensure cleanup on plugin disposal if needed.
- In `Handle`, encountering an unknown placeholder or a placeholder that resolves to an empty list causes an immediate `return` and silently drops the command; consider either giving the player feedback (e.g., via `args.Player.SendErrorMessage`) or executing the original command unchanged instead of failing silently.
- The recursive `ExpandAndExecute` will generate a command for every combination of placeholder expansions, which can grow combinatorially (e.g., large groups with multiple placeholders); consider adding a cap on total expansions or a safety guard to prevent excessive command execution and potential server lag.
## Individual Comments
### Comment 1
<location path="src/ServerTools/CommandPlaceholderHandle.cs" line_range="11-17" />
<code_context>
+{
+ private static readonly List<PlaceholderResolver> _resolvers = [];
+
+ public static void Register()
+ {
+ // *all*
+ _resolvers.Add(new PlaceholderResolver(
+ placeholder => placeholder == "*all*",
+ _ => Plugin.ActivePlayers.Select(p => p.Name)
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Guard against repeated Register calls to avoid growing the static resolver list.
Since `Register` appends to the static `_resolvers` list without checking for prior registration, calling `Plugin.Initialize` multiple times (e.g., on plugin reload) will add duplicate resolvers and cause redundant resolution. Make registration idempotent by either clearing `_resolvers` at the start of `Register` or tracking initialization (e.g., a `bool _initialized` or checking for existing resolvers before adding).
```suggestion
public static void Register()
{
// Ensure repeated registrations (e.g., on plugin reload) don't accumulate duplicate resolvers
_resolvers.Clear();
// *all*
_resolvers.Add(new PlaceholderResolver(
placeholder => placeholder == "*all*",
_ => Plugin.ActivePlayers.Select(p => p.Name)
));
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Controllerdestiny
enabled auto-merge
July 24, 2026 15:36
ACaiCat
approved these changes
Jul 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
添加插件
更新插件/修复BUG
其他
Summary by Sourcery
在玩家指令中引入命令占位符处理机制,根据当前在线玩家和玩家群组展开特殊标记。
新特性:
增强内容:
Original summary in English
Summary by Sourcery
Introduce command placeholder handling to expand special tokens in player commands based on active players and groups.
New Features:
Enhancements: