[WIP] dedicated servers

Discussion in 'Work-In-Progress Mods' started by cola_colin, October 10, 2014.

  1. ch1ll4x

    ch1ll4x New Member

    Messages:
    5
    Likes Received:
    2
    I'm using AWS images to host servers as needed with crazy hardware. It'd be an awful pain if all of a sudden my PA account stopped working because I had an id-10-t error and lost track of a security step. :)
  2. cola_colin

    cola_colin Moderator Alumni

    Messages:
    12,074
    Likes Received:
    16,221
    What I am saying is that getting a second PA account during a sale isn't very expensive. So just use a dedicated account for it.
  3. ch1ll4x

    ch1ll4x New Member

    Messages:
    5
    Likes Received:
    2
    I'm down with the idea, in fact I already have four PA accounts because they're so reasonable!

    That said, the argument still applies whether I keep buying more accounts or not. :)

    Another bonus of not including authentication details in the AWS image, is it could be made public and anyone can spin up private servers without much/any work.
  4. SXX

    SXX Post Master General

    Messages:
    6,896
    Likes Received:
    1,812
    You can modify any update script so it's would use sessionID instead of your credentials. As long as server IP remain the same it's will work.

    Though I think Uber may add new server-only depot for PA on Steam so it's will be possible to update server-side using SteamCMD that allow anonymous login.
  5. fuzzels

    fuzzels Member

    Messages:
    90
    Likes Received:
    34
    The below misses the trigger for a new version, but it mostly automates updating and re-insterting the beacon code so one shows up on pa-stats. Such a trigger would be doable, know current edition, query for

    Use "update-rc.d" for creating proper init links for the init script (unless one is using silly systemd ;) ) that way it autostarts at boot of the box. Use
    Code:
    /etc/init.d/pa start
    for starting it

    As the 'pa' user shut down pa ("screen -rd" and just ctrl-c it) and then run the below update.sh, then call /etc/init.d/pa as root to start it again.

    Install papatcher into /home/papatcher/ so that /home/papatcher/papatcher.go is there
    (I am using the one from https://bitbucket.org/papatcher/papatcher)

    The add the following files:

    /home/pa/update.sh (set +x, the executable bit):
    Code:
    #!/bin/bash
    USERNAME=yourubername
    PASSWORD=youruberpass
    
    cd /home/pa/
    rm -rf .local
    
    papatcher/papatcher.go ${USERNAME} ${PASSWORD}
    
    FILE="/home/pa/.local/Uber Entertainment/Planetary Annihilation/stable/media/server-script/states/lobby.js"
    
    mv "${FILE}" "${FILE}.org"
    awk '/var DISCONNECT_TIMEOUT/ && c == 0 {c = 1; system("cat /home/pa/beacon.txt") }; {print} ' "${FILE}.org" >"${FILE}"
    
    echo "DONE"
    
    /home/pa/beacon.txt
    Code:
    setInterval(function() {
        if (server.beacon) {
            console.log("<BACON>"+JSON.stringify(server.beacon)+"</BACON>");
        }
    }, 5000);
    
    /home/pa/start.sh
    Code:
    #!/bin/bash
    
    cd ~/NodePAMaster/src
    nodejs control.js
    
    /etc/init.d/pa (set +x, thus the executable bit set)
    Code:
    #!/bin/sh
    ### BEGIN INIT INFO
    # Provides:          planetary-annihilation-server
    # Required-Start:    $remote_fs $syslog
    # Required-Stop:
    # Should-Start:
    # Default-Start:     2 3 4 5
    # Default-Stop:
    # Short-Description: Planetary Annihilation Server
    # Description:       Controller for the Planetary Annihilation Server
    ### END INIT INFO
    
    PATH=/sbin:/usr/sbin:/bin:/usr/bin
    . /lib/init/vars.sh
    
    do_start () {
    	su -l -s /bin/sh -c 'exec "$0" "$@"' pa -- screen -dmS pa /home/pa/start.sh
    }
    
    case "$1" in
      start|"")
    	do_start
    	;;
      restart|reload|force-reload)
    	echo "Error: argument '$1' not supported" >&2
    	exit 3
    	;;
      stop)
    	# No-op
    	;;
      *)
    	echo "Usage: pa [start|stop|status]" >&2
    	exit 3
    	;;
    esac
    
    cola_colin likes this.
  6. cola_colin

    cola_colin Moderator Alumni

    Messages:
    12,074
    Likes Received:
    16,221
    that looks nice

    You can never have enough PA accounts.
    Such an image would have the issue that it contains a full copy of PA. Can't just distribute that.
  7. fuzzels

    fuzzels Member

    Messages:
    90
    Likes Received:
    34
    In an image situation you would not want to distribute that anyway, just fetch the initial part with papatcher too, which you'll do anyway when a newer versions comes out.
  8. BobChaos

    BobChaos New Member

    Messages:
    9
    Likes Received:
    4
    In a previous post Fuzzels mentioned he was missing a trigger for the updates to the PA server, so I cooked up a little script that check the latest vs current.

    Code:
    #!/bin/bash
    autht=`curl --data '{TitleId: 4, AuthMethod: "UberCredentials", UberName: "username", Password: "password"}' --header "Content-Type: application/json" https://uberent.com/GC/Authenticate | cut -d "\"" -f4`
    aversion=`curl --header "X-Authorization: $autht" https://uberent.com/Launcher/ListStreams?Platform=Linux | cut -d "\"" -f12`
    cversion=`cat ~/.local/Uber\ Entertainment/Planetary\ Annihilation/stable/version.txt`
    if [ $aversion -gt $cversion ]
    then
    echo "New PA server build $aversion available, updating from $cversion" && echo
    #Code to notify users?
    /etc/init.d/pa stop
    /home/pa/update.sh #Fuzzels script
    /etc/init.d/pa start
    fi
    You of course will need to add that script to your crontab and edit the username and password from the $autht and possibly path for the current version depending how you installed PA.

    The shutdown is a bit brutal, so there's room for improvement there among other things. If someone knows of a way to monitor active users for instance you could wait until everyone leaves.
    cola_colin likes this.
  9. cola_colin

    cola_colin Moderator Alumni

    Messages:
    12,074
    Likes Received:
    16,221
    look at how NodePAMaster handles the "tasty bacon I described in earlier posts". You could check if the beacon has 0 players and if it has trigger your script from there.
  10. smithygotlost

    smithygotlost New Member

    Messages:
    2
    Likes Received:
    2
    Hey guys,

    First off absolutely stunning work ive spent all day getting down and dirty with my server to have a good crack at a game. However is there any way at current for me to enable a server side mod ??

    The mod is in the /server_mods folder

    Thanks again
    Mike
    zihuatanejo likes this.
  11. stuart98

    stuart98 Post Master General

    Messages:
    6,009
    Likes Received:
    3,888
    Make a backup of your PA directory and replace the files in the actual PA directory with those from the server mod.
  12. cola_colin

    cola_colin Moderator Alumni

    Messages:
    12,074
    Likes Received:
    16,221
    that won't fully work, as it will not push out the changes to the clients. "server mods" usually require the host to have them and push them to the server on joining
    cwarner7264 likes this.
  13. smithygotlost

    smithygotlost New Member

    Messages:
    2
    Likes Received:
    2
    Got it working in the end i custom modded the files in the PA directories to do what the mod was doing anyways. :) Currently testing the strenth of the server run 100 player game no lag atall.. about to launch a 200 player one :)
    guest1 likes this.
  14. mikeyh

    mikeyh Post Master General

    Messages:
    1,869
    Likes Received:
    1,509
    Here's a couple of snippets from my updater scripts based on the following files:
    • color_table.js (copied by updater)
    • beacon.js (prepended to lobby.js by updater)
    stable-update.sh

    You could save your login details in the script to automate as part of a deployment script.

    Code:
    cd /root/
    
    go run papatcher.go -stream="stable" -update-only=true
    
    cp /root/color_table.js /root/.local/Uber\ Entertainment/Planetary\ Annihilation/stable/media/server-script/lobby/color_table.js
    
    lobbyjs="/root/.local/Uber Entertainment/Planetary Annihilation/stable/media/server-script/states/lobby.js"
    
    echo '0r /root/beacon.js
    .
    w' | ed --quiet "$lobbyjs"
    
    /root/stable-settings.sh 32 10
    stable-settings.sh

    Code:
    lobbyjs="/root/.local/Uber Entertainment/Planetary Annihilation/stable/media/server-script/states/lobby.js"
    
    players=$1
    
    sed -i.bak "s/var MAX_PLAYERS = [0-9][0-9]*;/var MAX_PLAYERS = $players;/" "$lobbyjs"
    
    spectators=$2
    
    sed -i.bak "s/var MAX_SPECTATORS = [0-9][0-9]*;/var MAX_SPECTATORS = $spectators;/" "$lobbyjs"
    
    zihuatanejo and DeathByDenim like this.
  15. DeathByDenim

    DeathByDenim Post Master General

    Messages:
    4,327
    Likes Received:
    2,125
    That's pretty neat. I wonder if you can take it one level up with auto-updating. As in putting an update check in a cron script such as
    Code:
    LATEST=`curl -s https://uberent.com/launcher/clientversion?titleid=4`
    CURRENT=`cat /root/.local/Uber Entertainment/Planetary Annihilation/stable/version.txt`
    if [ "$LATEST" != "$CURRENT" ]; then
      stable-update.sh
    fi
    
    Although in retrospect it may need to check if the server is being used I guess. Well, or let the cron job run at night.
  16. mikeyh

    mikeyh Post Master General

    Messages:
    1,869
    Likes Received:
    1,509
    Here's how I create and manage replays with the following changes to control.js:

    Code:
    var serverExe = conf.server;
    var params = conf.serverparams;
    
    params.push( '--output-dir' );
    params.push( '/root/logs/stable/' + (new Date()).toISOString() );
    Code:
    paserver.setServerDiedListener(function() {
        lobbyId = (Math.random() * 999999999999999).toFixed(0);
        setTimeout(function() {
            params.pop()
            params.push( '/root/logs/stable/' + (new Date()).toISOString() );
            paserver.init(serverExe, params);
        }, 3000);
    });
  17. h4rm0n1c

    h4rm0n1c New Member

    Messages:
    1
    Likes Received:
    4
    Hello all, this is my first post here, I'm not one for participating in the community but I thought that the following was too useful to not post it here.

    I've retrofitted some of the shell script snippets here into an older service control script for Minecraft that I had banging around in my shell scripts folder (which also uses screen, so not that big a change), creating a new init.d service script that seems to work quite well.

    All the basic things that would need to be changed for each different setup are broken out into variables at the top of the script for easy editing.

    There's only a placeholder for the update command, getting something generic in place that can be modified depending on what files people want copied out/back is my next goal.

    Code:
    #!/bin/bash
    # /etc/init.d/planetary
    # version 0.0.2 2015-04-25 (YYYY-MM-DD)
    # caveat emptor, don't copy and paste and just hope it'll work, READ AND COMPREHEND.
    
    ### BEGIN INIT INFO
    # Provides:     planetary
    # Required-Start: $local_fs $remote_fs
    # Required-Stop:  $local_fs $remote_fs
    # Should-Start:     $network
    # Should-Stop:     $network
    # Default-Start:  2 3 4 5
    # Default-Stop:     0 1 6
    # Short-Description:    planetary annihilation server
    # Description:     Starts the planetary annihilation server
    ### END INIT INFO
    
    #Settings
    #set this a word out of the server's name as specified in your nodepamaster config, do not put in spaces, just one word or pgrep will be unhappy.
    #this just helps the script to find the server process itself via its name, for status monitoring.
    SERVICE='GOAT'
    #this is the user the server is running under
    USERNAME='planetary'
    #base home dir for pa user, papatcher should be here, not using this yet, but prep for update command being written.
    PAPATH='/home/planetary'
    #nodepamaster folder should be in the pa user's home dir
    NODEPAMASTER="${PAPATH}"/NodePAMaster/src
    #nodepamaster invocation command
    INVOCATION="nodejs control.js"
    ME=`whoami`
    
    as_user() {
      if [ $ME == $USERNAME ] ; then
        bash -c "$1"
      else
        su - $USERNAME -c "$1"
      fi
    }
    
    pa_start() {
      if pgrep -u $USERNAME -f "${SERVICE}" > /dev/null
      then
        echo "$SERVICE is already running!"
      else
        echo "Starting $SERVICE..."
        cd "${NODEPAMASTER}"
        as_user "cd '${NODEPAMASTER}' && screen -dmS planetary $INVOCATION"
        sleep 2
        if pgrep -u $USERNAME -f "${SERVICE}" > /dev/null
        then
         echo "$SERVICE is now running."
        else
         echo "Error! Could not start $SERVICE!"
        fi
      fi
    }
    
    pa_stop() {
      if pgrep -u $USERNAME -f "${SERVICE}" > /dev/null
      then
        echo "Stopping $SERVICE"
        as_user "screen -p 0 -S planetary -X quit"
      else
        echo "$SERVICE was not running."
      fi
      if pgrep -u $USERNAME -f "${SERVICE}" > /dev/null
      then
        echo "Error! $SERVICE could not be stopped."
      else
        echo "$SERVICE is stopped."
      fi
    }
    
    pa_update() {
      if pgrep -u $USERNAME -f "${SERVICE}" > /dev/null
      then
        echo "$SERVICE is running! Will not start update."
      else
        echo "TODO: Update Script"
      fi
    }
    
    #Start-Stop here
    case "$1" in
      start)
        pa_start
        ;;
      stop)
        pa_stop
        ;;
      restart)
        pa_stop
        pa_start
        ;;
      update)
        pa_stop
        pa_update
        pa_start
        ;;
      status)
        if pgrep -u $USERNAME -f "${SERVICE}" > /dev/null
        then
         echo "$SERVICE is running."
        else
         echo "$SERVICE is not running."
        fi
        ;;
    
      *)
      echo "Usage: /etc/init.d/planetary {start|stop|update|status|restart}"
      exit 1
      ;;
    esac
    
    exit 0
    
    I'll try to post updates here, I can't post the link to my github page for this right now, because the default forum security settings won't let me post links yet.

    I'm h4rm0n1c on github, this is listed under my public "gists", I will consider merging pull requests if people want to improve this script.

    Cheers!

    Edit: Changed around a few variables in preparation for an update command being added.

    Edit2: I herped and then I derped, I forgot to change $PAPATH to $NODEPAMASTER in the script, this is what you get for editing bash scripts at 1am, fixed.

    Edit3: Check out my github gists, there's a nodepamaster-less fork of this script that I use for servers that don't need pastats, this makes setup simpler for the small private server use case.
    Last edited: April 25, 2015
  18. uggla88

    uggla88 New Member

    Messages:
    29
    Likes Received:
    14
    Last edited: May 9, 2015
  19. fuzzels

    fuzzels Member

    Messages:
    90
    Likes Received:
    34
    "Time to have a coffee. Image is ~5 GB, so time for building depends from your internet connection."

    Which means you have embedded all of PA. Which is useless as there is no update script.
    Next to that... Docker is the useless bit as people tend to include too much crud and then never update that crud, it will just sit their being vulnerable.
  20. uggla88

    uggla88 New Member

    Messages:
    29
    Likes Received:
    14
    Hello,

    Not sure I understand your points.
    The Dockerfile uses papatcher to download PA and will update the conf files with some scripting to come out with a full functional image ready to run. (this is not a "static" image).
    As well, the latest base image for Ubuntu 15.04 is downloaded and required packages are downloaded/updated with apt-get.

    So each time you create a paserver image, system and apps are updated to latest releases avoiding vulnerabilities.

    Of course it means you have to recreate an image and run it to upgrade.
    Note 1 : You will keep the old image, so in case of issue you can roll back easily.
    Note 2 : Image will run in a container completely isolated with non root account, so far better than running paserver as root on a dedicated server from a security point of view.



    Best regards.
    Last edited: May 10, 2015

Share This Page