Add WIP workshop stuff

This commit is contained in:
James
2022-02-03 18:21:49 +00:00
parent ea9ff8ef90
commit e408e7cf31

View File

@@ -1,7 +1,11 @@
import argparse import argparse
from gettext import install
from http import server
from logging import exception from logging import exception
import os import os
from posixpath import split
import requests import requests
import shutil
import subprocess import subprocess
import zipfile import zipfile
@@ -24,8 +28,8 @@ import zipfile
STEAM_CMD_URL = "https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip" STEAM_CMD_URL = "https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip"
SERVER_APP_ID = 400300 SERVER_APP_ID = "400300"
GAME_APP_ID = 365960 GAME_APP_ID = "365960"
# 917387157 - Silverstone 2012 # 917387157 - Silverstone 2012
# 1515650133 - McLaren MP4/13 # 1515650133 - McLaren MP4/13
@@ -98,7 +102,7 @@ def download_server(steamcmd_path: str) -> bool:
"+login", "+login",
"anonymous", "anonymous",
"+app_update", "+app_update",
"400300", SERVER_APP_ID,
"validate", "validate",
"+quit" "+quit"
] ]
@@ -107,53 +111,175 @@ def download_server(steamcmd_path: str) -> bool:
return True return True
def read_steam_credentials(credentials_file: str) -> tuple: def read_steam_credentials(credentials_file: str) -> tuple:
return (False, {}) print("Reading Steam credentials file...")
with open(credentials_file, "rt") as creds:
credentials = creds.readline()
def read_workshop(content_file: str) -> tuple: split_creds = credentials.split(" ", 1)
if len(split_creds) != 2:
print("Error: Could not parse username and password!")
return (False, []) return (False, [])
def download_workshop(server_base_path: str, workshop_content: list) -> bool: return (True, split_creds)
return False
def move_workshop(server_base_path: str, workshop_content: list) -> bool: def read_workshop(content_file: str) -> tuple:
return False print("Reading Steam Workshop content file...")
def install_workshop(server_base_path: str, workshop_content: list) -> bool: out_content = []
return False
def uninstall_workshop(server_base_path: str, workshop_content: list) -> bool: with open(content_file, "rt") as content:
return False content_ids = content.readlines()
for content_id in content_ids:
if content_id.strip() == "":
break
def open_mas2(server_base_path: str) -> bool: if not content_id.isnumeric():
print(f"Error: Invalid content ID '{content_id}', all IDs should be numeric!")
return (False, [])
out_content.append(content_id)
print(f"Found {len(out_content)} content IDs")
return (True, out_content)
def download_workshop(steamcmd_path: str, workshop_content: list, credentials: list) -> bool:
args = [
f"{steamcmd_path}/steamcmd.exe",
"+login",
credentials[0],
credentials[1]
]
for content_id in workshop_content:
args.append("+workshop_download_item")
args.append(GAME_APP_ID)
args.append(content_id)
args.append("validate")
args.append("+quit")
subprocess.run(args)
return True
def move_workshop(server_path: str, steamcmd_path: str, workshop_content: list) -> tuple:
print("Moving workshop files...")
workshop_path = f"{steamcmd_path}/steamapps/workshop/content/{SERVER_APP_ID}"
packages_path = f"{server_path}/Packages"
moved_files = []
for content_id in workshop_content:
content_path = f"{workshop_path}/{content_id}"
if not os.path.exists(content_path):
print(f"Error: '{content_path}' does not exist!")
return (False, [])
files = os.listdir(content_path)
for file in files:
if os.path.splitext(file)[1] == ".rfcmp":
file_path = f"{content_path}/{file}"
print(f"Moving '{file}'...")
shutil.move(file_path, f"{packages_path}/{file}")
moved_files.append(file)
return (True, moved_files)
def install_workshop(server_path: str, workshop_files: list) -> bool:
print("Installing workshop files...")
mod_mgr_path = f"{server_path}/Bin64/ModMgr.exe"
working_dir = server_path
packages_dir = f"{server_path}/Packages"
install_dir = f"{server_path}/Installed"
args = [
mod_mgr_path,
"-c",
working_dir,
"-p",
packages_dir,
"-d",
install_dir
]
for file in workshop_files:
args.append(file)
subprocess.run(args)
return True
def uninstall_workshop(server_path: str, workshop_content: list) -> bool:
print("Can't uninstall yet!")
return True
def open_mas2(server_path: str) -> bool:
# MIGHT be able to create MAS files using the ModMgr it seems # MIGHT be able to create MAS files using the ModMgr it seems
print("Opening MAS2 tool...")
mas2_path = f"{server_path}/Support/Tools/MAS2_x64.exe"
subprocess.run(
[
mas2_path
]
)
return True
def start_server(server_path: str) -> bool:
print("Starting server...")
subprocess.run(
[
f"{server_path}/Bin64/rFactor 2 Dedicated.exe"
]
)
return True
def server_keys(server_path: str, steamcmd_path: str, credentials: list) -> bool:
print("Downloading setup content so a server can be created...")
if not download_workshop(steamcmd_path, SERVER_SETUP_CONTENT, credentials):
return False return False
def start_server(server_base_path: str) -> bool: result, workshop_files = move_workshop(server_path, steamcmd_path, SERVER_SETUP_CONTENT)
if not result:
return False return False
def server_keys(server_base_path: str) -> bool: if not install_workshop(server_path, workshop_files):
# download + install basic content here return False
if not open_mas2(server_path):
return False
print("Starting server to get server keys file") print("Starting server to get server keys file")
print("\t1 - Create a server using basic content") print("\t1 - Create a server using basic content")
print(f"\t2 - Once the server is running, ServerKeys.bin should exist at {server_base_path}/UserData/ServerKeys.bin") print(f"\t2 - Once the server is running, ServerKeys.bin should exist at {server_path}/UserData/ServerKeys.bin")
print("\t3 - Copy this file to your main rFactor 2 installation which owns the paid DLC you are installing") print("\t3 - Close the server")
print("\t4 - Copy this file to your main rFactor 2 installation which owns the paid DLC you are installing")
print("\t\t<steam_games_dir>\\steamapps\\common\\rFactor 2\\UserData\\ServerKeys.bin") print("\t\t<steam_games_dir>\\steamapps\\common\\rFactor 2\\UserData\\ServerKeys.bin")
print("\t4 - Start a single player race (any content I think)") print("\t5 - Start a single player race (any content I think)")
print("\t5 - There should not be a ServerUnlock.bin file in the folder you copied ServerKeys.bin to") print("\t6 - There should not be a ServerUnlock.bin file in the folder you copied ServerKeys.bin to")
print("\t\t<steam_games_dir>\\steamapps\\common\\rFactor 2\\UserData\\ServerUnlock.bin") print("\t\t<steam_games_dir>\\steamapps\\common\\rFactor 2\\UserData\\ServerUnlock.bin")
print(f"\t6 - Copy ServerUnlock.bin back to {server_base_path}/UserData/ServerUnlock.bin") print(f"\t7 - Copy ServerUnlock.bin back to {server_path}/UserData/ServerUnlock.bin")
# start server here - dont think this can be scripted? if not start_server():
return False
input("\nPress Enter once you have completed those steps...") input("\nPress Enter once you have completed those steps: ")
return True return True
def setup_server(server_name: str, server_path: str, content_file: str, credentials_file: str) -> bool: def setup_server(server_name: str, parent_path: str, content_file: str, credentials_file: str) -> bool:
server_base_path = f"{server_path}/{server_name}" server_base_path = f"{parent_path}/{server_name}"
steamcmd_path = f"{server_base_path}/steamcmd" steamcmd_path = f"{server_base_path}/steamcmd"
server_path = f"{steamcmd_path}/steamapps/common/rFactor 2 Dedicated Server"
if not create_server_dir(server_base_path, server_path): if not create_server_dir(server_base_path, parent_path):
return False return False
if not download_steamcmd(steamcmd_path): if not download_steamcmd(steamcmd_path):
@@ -165,7 +291,31 @@ def setup_server(server_name: str, server_path: str, content_file: str, credenti
if not download_server(steamcmd_path): if not download_server(steamcmd_path):
return False return False
if not server_keys(server_base_path): result, credentials = read_steam_credentials(credentials_file)
if not result:
return False
result, content = read_workshop(content_file)
if not result:
return False
if not server_keys(server_path, steamcmd_path, credentials):
return False
if not download_workshop(steamcmd_path, content, credentials):
return False
result, workshop_files = move_workshop(server_path, steamcmd_path, content)
if not result:
return False
if not install_workshop(server_path, workshop_files):
return False
if not open_mas2(server_path):
return False
if not start_server():
return False return False
return True return True
@@ -176,7 +326,7 @@ if __name__ == "__main__":
parser.add_argument("name", type=str, help="Friendly name for the server") parser.add_argument("name", type=str, help="Friendly name for the server")
parser.add_argument("path", type=str, help="Path to download the server to") parser.add_argument("path", type=str, help="Path to download the server to")
parser.add_argument("content_file", type=str, help="Path to a list of workshop IDs to download and install onto the server") parser.add_argument("content_file", type=str, help="Path to a list of workshop IDs to download and install onto the server")
parser.add_argument("credentials_file", type=str, help="Path to file containing Steam username and password in format username:password") parser.add_argument("credentials_file", type=str, help="Path to file containing Steam username and password in format 'username password'")
args = parser.parse_args() args = parser.parse_args()