-
-
Notifications
You must be signed in to change notification settings - Fork 443
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AmbiguousMenu: Automagically create menu when multiple targets match #1069
base: master
Are you sure you want to change the base?
Conversation
c410502
to
0bda47d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Politics aside this is a pretty cool feature. It looks like this may crash a lot. Can you address the licensing issues so we can proceed forward?
info.flags = params[5]; | ||
pContext->LocalToString(params[6], &info.target_name); | ||
info.target_name_maxlength = params[7]; | ||
pContext->LocalToString(params[1], (char **) &g_ProcessTargetString_info.pattern); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe these are messed up 😿 you'll crash or use an old buffer from pawn if not invoked immediately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely, if I call GetLastProcessTargetString when the SourcePawn locals of the last ProcessTargetString call are already gone then something weird will definitely happen.
Could copy the data I need to a different struct instead to be safe.
@@ -47,6 +47,92 @@ struct Plugin | |||
public const char[] url; /**< Plugin URL */ | |||
}; | |||
|
|||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you unmove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These definitions need to exist before #include <commandfilters>
I think.
So either move them to the top or move the commandfilters include to the bottom.
Actually why not move all of the includes to the bottom so they can use these sourcemod natives.
I use these natives in commandfilters here:
BotoX@6f38356#diff-04ed686e7e10bc10466c487fadc9ea8eR151
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The feature is awesome but as discussed previously I'd be super reluctant to take this implementation in-tree - the coupling between core and the plugin is very tight, it's requiring a couple of odd escape hatches to the internal implementation and I don't see an alternative implementation of the plugin ever really being viable. As it changes a stock it also requires plugins to be recompiled to pick it up.
A better option might be for this to live entirely in C++ land, triggered internally from ProcessTargetString, with a core.cfg option to enable it and possibly a targeting flag to skip it if required. Or even just a separate native plugins could use as a starting position (which could be added to the FindTarget simple wrapper.)
In an ideal world we'd be able to have async behaviour inline here, but anything re-calling the command is always going to need to be super cooperative, and there is a lot of odd command callback implementations out there.
…eplyToTargetError COMMAND_TARGET_AMBIGUOUS. Explanation: There are two clients in the server, one named gene, the other one "Ene ~special characters~". An admin issues "sm_slay Ene" and gets following error message: More than one client matched the given pattern. What this hack will do is: Use GetCmdArg(0, ...); to get the command name "sm_slay". Use GetCmdArgString(...); to get the arguments supplied to the command. Use GetLastProcessTargetString(...); (which was implemented in this commit) to retrieve the arguments that were passed to the last ProcessTargetString call. It will then pass this data to the DynamicTargeting plugin through its AmbiguousMenu native. The plugin will open up a menu on the client and list all targets which match the pattern that was supplied to ProcessTargetString. If the client selects a menu entry, FakeClientCommand will be used to re-execute the command with the correct target.
0bda47d
to
6f38356
Compare
The implementation is indeed hacky, it also requires a plugin recompile to make use of this feature. if((target_count = ProcessTargetString(...)) <= 0) {
ReplyToTargetError(client, target_count);
return Plugin_Handled;
} I haven't encountered a single plugin which does this different. Then again I also can't guarantee that the plugin will return after calling ReplyToTargetError. How would you go about adding this in I don't see the recompiling thing as a dealbreaker, at least that way if this would break a certain plugin it'd only do so if the author/user compiles it with the current SM codebase. It'd be easy for them to fix it and simply recompile. Looking over this again I still really like the way I've done this, minimal changes to SM and zero changes needed to plugin code. |
@asherkin what are your current thoughts for this one? I'm apathetic between either method as they're both improvements, but I'm optimistic that this will hopefully land and improve the targeting situation that's beneficial for all end-users. |
Added hack to make plugins open a menu with all possible targets on ReplyToTargetError COMMAND_TARGET_AMBIGUOUS.
Explanation:
There are two clients in the server, one named gene, the other one "Ene
special characters".An admin issues "sm_slay Ene" and gets following error message: More than one client matched the given pattern.
What this hack will do is: Use GetCmdArg(0, ...); to get the command name "sm_slay".
Use GetCmdArgString(...); to get the arguments supplied to the command.
Use GetLastProcessTargetString(...); (which was implemented in this commit) to retrieve the arguments that were passed to the last ProcessTargetString call.
It will then pass this data to the DynamicTargeting plugin through its AmbiguousMenu native.
The plugin will open up a menu on the client and list all targets which match the pattern that was supplied to ProcessTargetString.
If the client selects a menu entry, FakeClientCommand will be used to re-execute the command with the correct target.
sourcemod.inc is kinda ugly