Author Topic: Soldat Shell - Shell (Bash) scripts for Soldat dedicated servers.  (Read 1894 times)

0 Members and 1 Guest are viewing this topic.

Offline BlackFire533

  • Major(1)
  • Posts: 5
Script name: Soldat Shell
Script description: Collection of shell (Bash) scripts for Soldat dedicated servers.
Original author(s): Myself.
License: GNU Affero General Public License Version 3
Full description:
Although I only wrote four scripts, more is to come; thus, a collection. They're supposed to replace Soldat's Pascal scripts. All of them work, except not perfectly, at least not (yet) for the rcon_kills and rcon_balancer scripts.

rcon_kills script: Count the kills for each player and display a message after each defined row has been reached.
rcon_announce script: Periodically display a set of three messages after five minutes + two other messages, after 30 seconds, counted from the five minutes.
rcon_commands script: Execute commands requested by a player; currently, the commands are: !date (date Unix command), !info (uname -a Unix command), !script (script information; credits), !red or !1 (change the player's team to Alpha), !blue or !2 (change the player's team to Bravo), !spec or !5 (spectate; become a spectator).
(NEW!) rcon_balancer script: Check for inconsistency in Alpha and Bravo teams and automatically switch the team of the last player who joined.

Since I made them on GNU/Linux, it is unlikely that Unix or other Unix-like operating systems (including macOS) be able to run them, because GNU programs tend to be and act different than these found in Unix and other Unix-like operating systems. However, *BSD and illumos users may already have or can install GNU programs, so they just need to adapt their environment.
Windows users may use Cygwin to run the scripts.
NOTE: Even though GNU programs are different than these found in Unix and other Unix-like operating systems, I'm writing the scripts with POSIX in mind.

The scripts can be found in my GitHub repository.
« Last Edit: June 13, 2021, 09:25:13 pm by BlackFire533 »

Offline jrgp

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 5033
Re: Soldat Shell - Shell (Bash) scripts for Soldat dedicated servers.
« Reply #1 on: June 10, 2021, 01:11:22 am »
Wow.

It's clear you put a lot of effort into this and I don't think I've seen something like this before.

Maybe the closest to this I've seen before may have been back before pascal scripts where people did similar functionality with mIRC scripts.

Few questions:

- In cases like https://github.com/Krush206/soldat-shell/blob/main/rcon_balancer#L91 why not use $( $( ) ) type nested shell execution as opposed to backticks which you had to escape?

- It seems like /tmp is hard coded in various places, might be helpful to make that customizable

- Have you considered the possibility for shell injection, eg if a player has malicious characters in their names?
There are other worlds than these

Offline jrgp

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 5033
Re: Soldat Shell - Shell (Bash) scripts for Soldat dedicated servers.
« Reply #2 on: June 10, 2021, 01:28:22 am »
Just read this some more, some more thoughts:

It looks like the main loop of these scripts is an infinite busy-wait where you check for recognizable commands in /tmp/cmds, and if there are any you take action and immediately wipe the file. I have a few concerns with this approach:

- with each iteration of the while loop (numerous per second as there are no sleeps) you'll be spawning off numerous `grep` processes, especially if none of them match (each elif). This would consume excessive resources

- if there are many incoming messages at once, some of them will get dropped/ignored as the relevant `grep` might miss them

Instead, why not find a way to pass netcat's stdin and stdout to your script's stdin and stdout, and operate on incoming lines as you receive them, using `while read line` or similar? That way you aren't busy waiting (as each loop iteration will block on reading an incoming message), won't drop messages, and will consume far fewer resources.


There are other worlds than these

Offline Furai

  • Administrator
  • Veteran
  • *****
  • Posts: 1907
    • TransHuman Design
Re: Soldat Shell - Shell (Bash) scripts for Soldat dedicated servers.
« Reply #3 on: June 10, 2021, 01:38:10 am »
When writing Bash script I cannot recommend ShellCheck enough. It checks your code for best practices and errors. There's command line version and many text editors support it, at the very least I know for sure that Visual Studio Code does support it.
« Last Edit: June 10, 2021, 02:10:36 am by jrgp »
"My senses are so powerful that I can hear the blood pumping through your veins."

Offline BlackFire533

  • Major(1)
  • Posts: 5
Re: Soldat Shell - Shell (Bash) scripts for Soldat dedicated servers.
« Reply #4 on: June 10, 2021, 11:30:49 am »
- In cases like https://github.com/Krush206/soldat-shell/blob/main/rcon_balancer#L91 why not use $( $( ) ) type nested shell execution as opposed to backticks which you had to escape?
I have always been used to backticks, but I will consider to replace them.
- It seems like /tmp is hard coded in various places, might be helpful to make that customizable
Since this is the default directory for temporary files, I did not really want to use something random/unknown. Regardless, I may implement custom variables. However, the recommendation to have a tmpfs mount will always remain.
- Have you considered the possibility for shell injection, eg if a player has malicious characters in their names?
Not really, but I'm making a note of and considering this, too.
It looks like the main loop of these scripts is an infinite busy-wait where you check for recognizable commands in /tmp/cmds, and if there are any you take action and immediately wipe the file. I have a few concerns with this approach:

- with each iteration of the while loop (numerous per second as there are no sleeps) you'll be spawning off numerous `grep` processes, especially if none of them match (each elif). This would consume excessive resources

- if there are many incoming messages at once, some of them will get dropped/ignored as the relevant `grep` might miss them

Instead, why not find a way to pass netcat's stdin and stdout to your script's stdin and stdout, and operate on incoming lines as you receive them, using `while read line` or similar? That way you aren't busy waiting (as each loop iteration will block on reading an incoming message), won't drop messages, and will consume far fewer resources.
You are right. I have always been concerned of the same reasons, too. Thanks for the input, I will replace the loop statement and implement netcat within the script.
When writing Bash script I cannot recommend ShellCheck enough. It checks your code for best practices and errors. There's command line version and many text editors support it, at the very least I know for sure that Visual Studio Code does support it.
This may come handy. Thanks.

Offline Savage

  • Soldier
  • **
  • Posts: 155
Re: Soldat Shell - Shell (Bash) scripts for Soldat dedicated servers.
« Reply #5 on: June 10, 2021, 12:36:09 pm »
Backticks are old and some shenanigans can happen with them and they are still there only for backward compatibility afaik.

Offline jrgp

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 5033
Re: Soldat Shell - Shell (Bash) scripts for Soldat dedicated servers.
« Reply #6 on: June 11, 2021, 01:52:26 am »
Backticks are old and some shenanigans can happen with them and they are still there only for backward compatibility afaik.

To be fair, that's most of Unix and computing in general.

Personally, I think backticks are cooler and I usually go for them first, and then switch to $( ) when I need to nest something.
There are other worlds than these

Offline BlackFire533

  • Major(1)
  • Posts: 5
Re: Soldat Shell - Shell (Bash) scripts for Soldat dedicated servers.
« Reply #7 on: June 11, 2021, 05:35:49 pm »
Instead, why not find a way to pass netcat's stdin and stdout to your script's stdin and stdout, and operate on incoming lines as you receive them, using `while read line` or similar? That way you aren't busy waiting (as each loop iteration will block on reading an incoming message), won't drop messages, and will consume far fewer resources.
I have done what you suggested and seems to be working well. As a side note, since netcat cannot run programs within a socket, I had to use socat to attach stdin and stdout to the script. Busybox's netcat and Nmap's Ncat are two other options, but I did not opt to use them, since socat is more of a complete, advanced tool and I'm mostly used to it.
I will upload the sources to GitHub as soon as I reimplement the other scripts (have reimplemented only rcon_commands as of now).

Offline BlackFire533

  • Major(1)
  • Posts: 5
Re: Soldat Shell - Shell (Bash) scripts for Soldat dedicated servers.
« Reply #8 on: November 24, 2021, 01:29:29 pm »
NEW: Ported to C Shell. (Still need to work on rcon_kills and rcon_commands.)
[As of now, all scripts have been ported.]

The C Shell is powerful, more reliable and suitable for this project.
The code relies in the same repository, but in a new branch.
https://github.com/Krush206/soldat-shell/tree/csh
« Last Edit: November 25, 2021, 08:33:35 am by BlackFire533 »

Offline BlackFire533

  • Major(1)
  • Posts: 5
Re: Soldat Shell - Shell (Bash) scripts for Soldat dedicated servers.
« Reply #9 on: November 24, 2021, 08:58:26 pm »
Some might wonder, "Why C Shell?"
Various reasons: C-like syntax, better built-ins, better scripting, a rich set of mathematical and logical operators, many convenient features (auto-correct, history substitution, built-in math).
It's also very secure; being "limited" makes it secure. (E.g: Nesting is minimal, thus preventing Shell injections at all costs; there are better ways to achieve what one want.)

The C Shell teaches how to safely write scripts. It's very cool. :)
The limitations aren't drawbacks.
http://parallel.vub.ac.be/documentation/linux/unixdoc_download/Scripts.html