Skip to content
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

Core: Text Processor Echo #2760

Conversation

MatthewMarinets
Copy link
Contributor

@MatthewMarinets MatthewMarinets commented Jan 24, 2024

What is this fixing or adding?

This is a small change to core / MultiServer.py, to the text command processor. I'm noticing while working on the starcraft 2 client that it's very difficult to tell where output in response to one command ends and the next starts. I've started putting little markers to help me see things while testing, and decided before adding it to a second or third command I should probably try to turn this into a global feature instead.
image

I've made this feature opt-in by setting the echo_commands property to true, with the possibility of adding prefixes and suffixes to the output (defaults to "$ " prefix and no suffix).

Note: I go by "Phanerus" on the discord if you need to contact me there. I've mostly only worked on starcraft 2 development.

How was this tested?

I've added a unit test for this that monkey-patches CommandProcessor.output to collect output messages and analyze it's behaving correctly.

Locally, I tried setting StarcraftClientProcessor.echo_commands to true, and playing around with some output. Commands were echoed as expected.
image

If this makes graphical changes, please attach screenshots.

@MatthewMarinets MatthewMarinets changed the title Text Processor Echo Core: Text Processor Echo Jan 24, 2024
@ScipioWright ScipioWright added is: enhancement Issues requesting new features or pull requests implementing new features. affects: core Issues/PRs that touch core and may need additional validation. labels Jan 26, 2024
@PoryGone PoryGone added the waiting-on: peer-review Issue/PR has not been reviewed by enough people yet. label Feb 10, 2024
Copy link
Contributor

@benny-dreamly benny-dreamly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me

command = '/help'

processor(command)
assert f'>{command}<' not in logged_outputs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use the syntax self.AssertNotIn() and such, instead of directly using the assert keyword

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

@MatthewMarinets MatthewMarinets force-pushed the mm/text_processor_echo branch from e228300 to 38fcc4e Compare March 5, 2024 22:19
@MatthewMarinets MatthewMarinets force-pushed the mm/text_processor_echo branch from 38fcc4e to d07a6a4 Compare March 5, 2024 22:21
@agilbert1412 agilbert1412 added waiting-on: core-review Issue/PR has been peer-reviewed and is ready to be merged or needs input from a core maintainer. and removed waiting-on: peer-review Issue/PR has not been reviewed by enough people yet. labels Mar 5, 2024
@@ -38,3 +39,19 @@ def test_resolve(self) -> None:
assert p.resolve_player("ABC") == (1, 2, "abc"), "case insensitive resolves when 1 match"
assert p.resolve_player("abcd") == (1, 3, "abCD"), "case insensitive resolves when 1 match"
assert not p.resolve_player("aB"), "partial name shouldn't resolve to player"

def test_echo_commands_on_request(self) -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be in a separate class/TestCase, not in TestResolvePlayerName, to avoid confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't notice the name on that, good catch. Updated.

@black-sliver
Copy link
Member

black-sliver commented Mar 10, 2024

Can I ask what you plan on using this for? I feel like typical solutions would have the parent process handle echoing the stdin.


Oh nvmd that question, I guess, it's to allow the same code to be reused across all CommandProcessors. I think I'd personally still do that in CommonClient instead, unless there is a reason this should be in CommandProcessor instead?

@MatthewMarinets
Copy link
Contributor Author

Can I ask what you plan on using this for? I feel like typical solutions would have the parent process handle echoing the stdin.

Oh nvmd that question, I guess, it's to allow the same code to be reused across all CommandProcessors. I think I'd personally still do that in CommonClient instead, unless there is a reason this should be in CommandProcessor instead?

I started my search for adding this in CommonClient; per my understanding, all the clients inherit from ClientCommandProcessor in that file, but there's no obvious place to add this code there. Instead, it inherits from CommandProcessor, which lives in MultiServer.py. That makes this the most obvious place to add this. I'm not too terribly familiar with metaclasses so there may be some way to do some modification further down the inheritance tree; I generally do my best to avoid inheritance as much as possible in my own code, so I don't really want to add anything to make the inheritance complexity problem worse in future.

As for a wrapping process handling this, it doesn't. This code gets used by our GUI client, which doesn't echo commands. Running the GUI process from the command-line also makes an interactive console there, which also doesn't echo. Unless I'm missing something, the Archipelago code is less a command processor and more a complete terminal, and it's not fulfilling all the responsibilities I'd expect of a terminal.

My original intention with this is as I say in the description -- I was finding myself adding something like this per-command in Starcraft 2 code, but once you add something like this 2~3 times you start asking if there's a good way to factor it out. Unless I want to basically branch all the client / command processor code from both CommonClient.py and MultiServer.py for starcraft use, I have to modify one of those files. I'm not really familiar with core dev, so I kept my changes as concise and unobtrusive as possible.

@Berserker66
Copy link
Member

Haven't tested this yet, but does it and do we want it to echo _cmd_admin too?

@MatthewMarinets
Copy link
Contributor Author

Haven't tested this yet, but does it and do we want it to echo _cmd_admin too?

I'm not familiar with that command, but I didn't do any special treatment of any commands. Reading the description, it looks like it has a password field so it probably shouldn't be echoed. It's been over a month so I don't remember all the details of my initial testing, but I think this echo also finds its way to logs, and that's not somewhere passwords should live.

How should I approach this? I see admin has a password field and it looks like some options can contain passwords. I could make a decorator similar to @raw_text, maybe something like @no_echo which will prevent a command from being logged. This blanket approach may be irritating for /option as only some things have passwords. I could do special treatment of the !admin command, and otherwise just search for the substring "password" and print some default prompt like "command containing a password".

@black-sliver
Copy link
Member

I feel like typical solutions would have the parent process handle echoing the stdin.

This code gets used by our GUI client, which doesn't echo commands

Well, that's kind of the point. I feel like the client should echo them, not the CommandProcessor. If you use --nogui (or use the stdin in parallel), you already get the echo while typing in the console. If berserker is fine with this, I won't block it though.

@MatthewMarinets
Copy link
Contributor Author

I feel like typical solutions would have the parent process handle echoing the stdin.

This code gets used by our GUI client, which doesn't echo commands

Well, that's kind of the point. I feel like the client should echo them, not the CommandProcessor. If you use --nogui (or use the stdin in parallel), you already get the echo while typing in the console. If berserker is fine with this, I won't block it though.

Ah I see, in that case I'd be fine with declining this PR and taking another stab at this on the console-side. I could look into getting that "hitting up brings up the last command" behaviour while I'm there. I assume that's accomplished by adding some handler on a widget within GameManager in kvui.py, to post some json message to the context?

@MatthewMarinets MatthewMarinets deleted the mm/text_processor_echo branch May 18, 2024 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects: core Issues/PRs that touch core and may need additional validation. is: enhancement Issues requesting new features or pull requests implementing new features. waiting-on: core-review Issue/PR has been peer-reviewed and is ready to be merged or needs input from a core maintainer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants