palworld-server-docker icon indicating copy to clipboard operation
palworld-server-docker copied to clipboard

add Auto Pause feature

Open MusclePr opened this issue 9 months ago • 0 comments

Context

AUTO_PAUSE_ENABLED=true

  • We can save power when there are no online players.
  • We can stop the game progress without bringing down the server.
  • Even in a paused state, it will not disappear from the community server list.
  • Fast resume, but lazy pause.
    • There is no need to reconnect to resume, it resumes immediately.
    • The auto-pause service tries to pause at the safest possible time, so it doesn't pause immediately.
  • I hope this helps reduce SSD deterioration even a little.

Choices

My implementation steps

  • I have experience using AUTOPAUSE from itzg/docker-minecraft-server and it was very effective in saving power, so I tried a similar implementation.
  • I confirmed that the PalServer-Linux-Shipping process can be stopped and restarted without problems using SIGSTOP and SIGCONT.
  • I confirmed that when I tried to connect to a paused PalServer, the knockd resumed the PalServer and I was able to connect as is.
  • Since the processing behavior overlaps with player_logging.sh, I decided to implement an automatic pause service in player_logging.sh.
  • I judged that it would be risky to enter a pause state with save timing every 30 seconds, so I implemented the is_safe_timing command to enter the pause state at a safe timing.
  • I have implemented the autopause resume command so that you can resume manually.
  • The REST_API and RCON ports were also targets of "knockd", but for some reason knock could not be detected from within the container, so I implemented a method to wake up PalServer in advance for rcon-cli and rest-cli.
  • In order to prevent it from entering a pause state during shutdown, we have implemented it so that it will not enter a pause state while the /palworld/.skip-pause file exists.
  • Implemented the autopause stop command to avoid entering a pause state on shutdown or reboot. I'm calling it from countdown_message and term_handler. This also supports AUTO_UPDATE and AUTO_REBOOT.
  • The presence of the /palworld/.paused file indicates that the server is in a paused state. Deleting this file will resume the server. You can also resume the server using the following command: autopause resume [reason] I recommend using this command, as it allows you to resume the server while leaving the reason in the log.
  • Added examples/docker-compose-autopause.yml as an example.

implementation for COMMINITY

  • When PalServer is paused, the community server list cannot be updated and disappears from the list, so APComm_proc now maintains communication with api.palworldgames.com on its behalf.
  • Since I wasn't sure what data to send, I decided to use mitmproxy, which is MIT licensed, to capture it.
  • The sending procedure was to first register with server/register, then use server_id and update_key included in the response to perform server/update every 30 seconds.
  • I implemented /home/steam/autopause/addons/PalIntercept.py as an add-on for mitmproxy to capture only the data necessary for transmission.
  • The captured data is always overwritten and saved in /home/steam/autopause/ as register.json or update.json.
  • The captured data is used to send it using the curl command while in the pause state. All I need to capture is the data that PalServer sends.
  • PalServer is sent over HTTP/1.1, but the curl command is sent over HTTP/2.0, so I'm only capturing HTTP/1.1. Originally, I think it would be desirable to embed custom header in the data to be sent on behalf of the user and then remove it using a proxy while forwarding it, but I have omitted this as it is not really necessary.
  • If an error occurred, I restarted from server/register and was able to maintain it.

for Tester

  • I committed the test environment because the data the server is communicating may change in the future.
  • When AUTO_PAUSE_DEBUG=true, mitmweb starts and communication data can be monitored in real time at http://localhost:8081/ . -The tests directory has common.yml for sharing purposes. This file is referenced from tests/autopause/docker-compose.yml.
tests/
    common.yml ... base rule for all tests.
    autopause/
        docker-compose.yml ... It is used by extending from common.yml.
        test-manually.sh ... Always build and test.

Test instructions

  1. run test
$ cd tests/autopause
$ ./test-manually.sh
  1. Leave it alone for a while and confirm that it enters the pause state.
  2. Confirm that you can resume the server by login.
  3. Check with by RCON as well.
  4. Check with by REST API as well.
  5. Make sure to stop safely with CTRL+C.

Checklist before requesting a review

  • It's been working fine for about two weeks, but since it's a major change, we still need to test it.

  • ~~Running without root is unconfirmed.~~

  • [x] I have performed a self-review/test of my code

  • [x] I've added documentation about this change to the docs.

  • [x] I've not introduced breaking changes. This is a risky feature addition, but it will have no effect unless you set AUTO_PAUSE_ENABLED=true.

  • [x] My changes do not violate linting rules.

MusclePr avatar May 16 '24 09:05 MusclePr