Jump to content
Sign in to follow this  
tissue901

Dedicated Windows Server Updater (Steam Workshop and Game)

Recommended Posts

Hey Guys,

I made a python script to automate updating my server and figured I'd share. I've only tested it on Python 3.6 but I think it would work for any version. Just update the directories and files section to where your stuff is located.  The "Steam Workshop IDs.txt" file just contains the workshop item number and a human readable string which automatically gets changed to a lowercase name without spaces. It uses a symbolic link to add the mods to the server's addons folder instead of moving it so updating works without redownloading everything. I know theres a bunch of GUI server managers out there, but I don't like the complexity that adds and this way I can just SSH from any device to update/boot my server.

 

Update.py

import os
import sys
from subprocess import Popen, PIPE, CalledProcessError, DEVNULL, STDOUT, check_call
import glob

armaServerAppId = "233780"
armaClientAppId = "107410"

modsDirectory = "C:\\Users\\arma\\Desktop\\Arma\\Master\\addons\\"
keysDirectory = "C:\\Users\\arma\\Desktop\\Arma\\Master\\keys\\"
armaDirectory = "C:\\Users\\arma\\Desktop\\Arma\\Master"
steamCMD = "C:\\Users\\arma\\Desktop\\steamcmd\\steamcmd.exe"
steamContentDirectory = "C:\\Users\\arma\\Desktop\\steamcmd\\steamapps\\workshop\\content\\" + armaClientAppId + "\\"
steamTempScript = "C:\\Users\\arma\\Desktop\\steamcmd\\tempUpdateScript.txt"
steamAuth = "C:\\Users\\arma\\Desktop\\steamcmd\\auth.txt"
workshopItems = "C:\\Users\\arma\\Desktop\\Arma\\Steam Workshop IDs.txt"

userLogin = ""
userPass = ""

def updateServer():
    print("Updating Server...")
    # Get the users login
    checkUserLogin()
    os.system(steamCMD + ' +login ' + userLogin + ' ' + userPass + ' +force_install_dir ' + armaDirectory + ' "+app_update ' + armaServerAppId + '" validate +quit')

def checkUserLogin():
    global userLogin
    global userPass
    
    if userLogin == "":
        userLogin = input("Steam> Username: ")
    if userPass == "":
        userPass = input("Steam> Password: ")
        
def copyKeys():
    for filename in glob.iglob(modsDirectory+'**\\*.bikey', recursive=True):
        os.system("xcopy " + filename + " " + keysDirectory + " /s /y")
        
error = ""

os.system('cls')

try:
    with open(steamAuth) as f:
        for line in f:
            info = line.split(" ")
            if len(info) == 2:
                userLogin = info[0]
                userPass = info[1]
except:
    pass

while True:
    userInput = input("Main Menu \n1. Update Server\n2. Update Mods\n4. Update Keys\n4. Exit\n" + error + ">> ")

    error = ""
    
    if userInput == "1":
        updateServer()
        input("Press any key to continue...")
        os.system('cls')
        
    elif userInput == "2":
        # Get the users login
        checkUserLogin()

        # Clear the temp script
        file = open(steamTempScript, 'w')

        script = "@ShutdownOnFailedCommand 1\n"
        script += "@NoPromptForPassword 1\n"
        script += "login " + userLogin + " " + userPass + "\n"
        script += "force_install_dir " + armaDirectory + "\n"

        mods = {}

        # Loop through each item in the workshop file
        with open(workshopItems) as f:
            for line in f:
                modInfo = line.split(" ", 1)
                steamWorkshopId = modInfo[0].strip()
                modName = modInfo[1].strip()
                modFolder = "@"+modName.replace(" ", "_").lower()

                mods[steamWorkshopId] = {"name": modName, "folder": modFolder}
                
                script += 'workshop_download_item ' + armaClientAppId + ' ' + steamWorkshopId + ' validate\n'

                # Make a link to the downloaded content (way better than moving...)
                symLink = modsDirectory + modFolder
                if not os.path.exists(symLink):
                    os.system('mklink /J ' + symLink + ' ' + steamContentDirectory + steamWorkshopId + '\n')

        script += "quit"
         
        file.write(script)
        file.close()

        # Run the script
        print("\n=====================================\nLogging into Steam...\n=====================================")
        
        with Popen(steamCMD + " +runscript " + steamTempScript, stdout=PIPE, bufsize=1, universal_newlines=True) as p:
            for line in p.stdout:
                line = line.strip()
                if line != "":
                    if line.find("Downloading item") != -1:
                        downloadingLine = line.split("Downloading item")
                        if downloadingLine[0]:  
                            print(downloadingLine[0])

                        try:
                            modIdLine = downloadingLine[1].strip().split(" ")
                            steamWorkshopId = modIdLine[0]
                            print("\n=====================================\nDownloading "+mods[steamWorkshopId]["name"] + " ["+str(steamWorkshopId)+"]...\n=====================================")
                        except:
                            pass
                            
                    else:
                        print(line)
        
        # Automatically copy bikeys over
        print("\n=====================================\nCopying addon keys...\n=====================================")
        copyKeys()
        
        input("\nPress any key to continue...")
        os.system('cls')
 
    elif userInput == "3":
        # Search for any bikeys and copy them into keys folder
        copyKeys()
        input("Press any key to continue...")
        os.system('cls')
    elif userInput == "4":
        sys.exit(0)
    elif userInput == "":
        os.system('cls')
    else:
        error = "[ERROR] Unknown choice. Try again\n"

 

Steam Workshop IDs.txt

450814997 CBA
463939057 ACE
708250744 ACEX
773131200 ACE Compat RHSAFRF
773125288 ACE Compat RHSUSAF
689845793 ACD
853743366 CUP Terrains CWA
583496184 CUP Terrains Core
583544987 CUP Terrains Maps
671539540 EM Buildings
753946944 Murshun Cigs
498740884 Shacktac
698078148 Spec4gear
696177964 VSM WARFIGHTERS
... and so on ...

example.png

  • Like 1

Share this post


Link to post
Share on other sites

Apologies for the 10 month necro but i feel this deserves some recognition - this works brilliantly and in my opinion is much more versatile than a batch script or some of the .sh scripts I've used.

 

Adding new mods to the list is so much easier for me via your Steam Workshop IDs.txt method, so thanks for the script!

Share this post


Link to post
Share on other sites

For the life of me @tissue901 I hope you are still around. I tried the above but the symlink do not seem to be working correctly. 

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×