-
Notifications
You must be signed in to change notification settings - Fork 21
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
Added support for input transfer during logging #92
base: master
Are you sure you want to change the base?
Conversation
Now when logging commands in the console, input transfer works, which improves user interaction with the server console, where logs are written in a thread and begin to interfere with viewing the current input.
Oh, I uploaded the changes from the wrong folder, I'll re-upload them now |
Oh, GitHub Desktop broke the commit. |
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.
Overall, this feels a bit bulky, but, as long as it can be tested on both Windows & Linux (Which I'll do now), should be ok.
Core/LocalAdmin.cs
Outdated
var headerLines = new string[] { | ||
$"SCP: Secret Laboratory - LocalAdmin v. {VersionString}", | ||
string.Empty, | ||
"Licensed under The MIT License (use command \"license\" to get license text).", | ||
"Copyright by Łukasz \"zabszk\" Jurczyk and KernelError, 2019 - 2024", | ||
string.Empty, | ||
"Type 'help' to get list of available commands.", | ||
string.Empty, | ||
}; | ||
|
||
ConsoleUtil.Clear(); | ||
ConsoleUtil.WriteLine($"SCP: Secret Laboratory - LocalAdmin v. {VersionString}", ConsoleColor.Cyan); | ||
ConsoleUtil.WriteLine(string.Empty, ConsoleColor.Cyan); | ||
ConsoleUtil.WriteLine("Licensed under The MIT License (use command \"license\" to get license text).", ConsoleColor.Cyan); | ||
ConsoleUtil.WriteLine("Copyright by Łukasz \"zabszk\" Jurczyk and KernelError, 2019 - 2024", ConsoleColor.Cyan); | ||
ConsoleUtil.WriteLine(string.Empty, ConsoleColor.Cyan); | ||
ConsoleUtil.WriteLine("Type 'help' to get list of available commands.", ConsoleColor.Cyan); | ||
ConsoleUtil.WriteLine(string.Empty, ConsoleColor.Cyan); | ||
|
||
foreach (var line in headerLines) | ||
{ | ||
ConsoleUtil.WriteLine(line, ConsoleColor.Cyan, inputIntro: false); | ||
} |
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 don't see why this needs to happen as you're doing what is effectively the same job, but I would've thought it'd be better to use a verbatim string instead which looks a bit cleaner imo.
But I'll let @zabszk decide.
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.
In my opinion it's an unnecessary array allocation and foreach loop. You use more resources just to achieve the same effect.
Core/LocalAdmin.cs
Outdated
if (_commandsHistory.Contains(command)) | ||
{ | ||
_commandsHistory.Remove(command); | ||
} | ||
else if (_commandsHistory.Count == CommandsHistorySize) | ||
{ | ||
_commandsHistory.RemoveAt(_commandsHistory.Count - 1); | ||
} |
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.
This can be crushed for better readability.
if (_commandsHistory.Contains(command)) | |
{ | |
_commandsHistory.Remove(command); | |
} | |
else if (_commandsHistory.Count == CommandsHistorySize) | |
{ | |
_commandsHistory.RemoveAt(_commandsHistory.Count - 1); | |
} | |
if (_commandsHistory.Contains(command)) | |
_commandsHistory.Remove(command); | |
else if (_commandsHistory.Count == CommandsHistorySize) | |
_commandsHistory.RemoveAt(_commandsHistory.Count - 1); |
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.
Yes, it does look better that way
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.
Then you can just hit commit to add 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.
Why do you use Contains check? It's completely redundant as Remove already checks that for you and returns a bool.
Just take a look at the docs: https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.remove?view=net-8.0
and how List.Remove() is implemented in .NET 8:
// Removes the first occurrence of the given element, if found.
// The size of the list is decreased by one if successful.
public bool Remove(T item)
{
int index = IndexOf(item);
if (index >= 0)
{
RemoveAt(index);
return true;
}
return false;
}
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.
Why do you use Contains check?
I replaced this in the improved readability
commit 4 days ago.
Core/LocalAdmin.cs
Outdated
|
||
if (!_processRefreshFail && _gameProcess != null) | ||
{ | ||
try | ||
{ | ||
if (_gameProcess.HasExited) | ||
{ | ||
ConsoleUtil.WriteLine("Failed to send command - the game process was terminated...", ConsoleColor.Red); | ||
ConsoleUtil.WriteLine("Failed to send command - the game process was terminated...", ConsoleColor.Red, inputIntro: false); |
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.
You don't really need the inputIntro
as far as I remember. I'm not gonna make the exact same comment to every single instance of this specific comment.
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.
Ok, it just seems to me that without it, an unnecessary input line will appear
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.
Interesting. I've never seen that behaviour.
Hi, Unfortunately this PR makes LA unusable in environments that support only stdin, stdout and stderr, just like Pterodactyl (which is the most popular way of launching SCP:SL servers). It doesn't support ReadKey. I just tested your PR there and it was not possible to run any command in Pterodactyl. Furthermore the output is completely broken there. I attached a few screenshots below. Additionally I have noticed a significant negative performance impact. I tested it on regular Ubuntu as well. It works, but it only prints output when you press enter key. I had to press enter key 9 times just to get this output. |
lmao. This is pretty much why these things need to be tested on both Windows & Linux before they're marked as ready for review. |
The primary issue isn't lack of testing (bugs can be fixed, of course before merging the PR), but the fact that some environments don't support ReadKey() and other used features. |
Is it possible to implement an os dependent |
It's not an OS issue. For example pterodactyl doesn't support "all interactions". It only supports stdin and stdout (and likely stderr, I'm not sure). You can't press a key there. You can only type a line of text and send it as stdin. So it's not an OS limitation (linux supports it), but specific environment limitation. Just like LA doesn't pass key presses to SCP:SL process itself. It only reads stdout and stderr. So if you for some reason call ReadKey() in SCP:SL itself (no LA), it will never be triggered, even if you press a key in LA. |
Hmm, I think we can add a check to see if the environment supports |
While you can add an argument, the change would have to be communicated with people using pterodactyl who decide to get the latest localadmin, so I'd prefer the auto detection, but how? |
Yes, I meant to implement automatic detection and, in addition to that, a startup argument. |
I read the Dotnet Runtime code, and it seems that performing additional checks besides |
I didn't see an exceptions when running in pterodactyl, but the entire output was broken, so I can't tell for sure (and there could be some try/catch somewhere in the code). Of course this will not catch all the edge cases, but the most important is to make sure it works in docker in pterodactyl. We should decide whether this feature should be opt-in (disabled by default) or opt-out (enabled by default). |
I'm thinking of making this feature enabled by default in environments that support the use of |
I think this is because the input is happening in a thread, and there's no try-catch block there. |
Is it possible for you to test it in linux and in pterodactyl? If not, I can test it after you commit fixes to this PR. Don't forget about the issue that exists on linux (outside pterodactyl) that I mentioned (the one that requires to press enter key to get new output). |
Yes, I have the ability to test in Linux, but I haven't figured out how to work with Pterodactyl yet. I have Docker Compose and Portainer, which theoretically should work in a similar way. Additional testing would definitely be useful. |
Currently partially tested on Windows, but some issues were found.
So far, I found that the |
I did the build via GitHub Actions on my fork repository. P.S.: workflow dispatch is not necessary to contribute to the main repository, it was needed for the fork. |
If you CTRL + C, does it quit the application? |
This closes SCPSL.exe, but the LocalAdmin window in Windows has to be closed manually. On Linux, everything closes correctly. |
Console apps are designed by Microsoft to terminate if there is no valid code to process meaning somewhere in your changes, your preventing the console from reaching a termination state. You’ll need to pause the application state after entering the state and discover what the JIT compiler is struggling to figure out. |
Now when logging commands in the console, input transfer works, which improves user interaction with the server console, where logs are written in a thread and begin to interfere with viewing the current input.
Tested on LocalAdmin v. 2.5.14 and Windows.