Add WIP workshop stuff
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
import argparse
|
||||
from gettext import install
|
||||
from http import server
|
||||
from logging import exception
|
||||
import os
|
||||
from posixpath import split
|
||||
import requests
|
||||
import shutil
|
||||
import subprocess
|
||||
import zipfile
|
||||
|
||||
@@ -24,8 +28,8 @@ import zipfile
|
||||
|
||||
STEAM_CMD_URL = "https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip"
|
||||
|
||||
SERVER_APP_ID = 400300
|
||||
GAME_APP_ID = 365960
|
||||
SERVER_APP_ID = "400300"
|
||||
GAME_APP_ID = "365960"
|
||||
|
||||
# 917387157 - Silverstone 2012
|
||||
# 1515650133 - McLaren MP4/13
|
||||
@@ -98,7 +102,7 @@ def download_server(steamcmd_path: str) -> bool:
|
||||
"+login",
|
||||
"anonymous",
|
||||
"+app_update",
|
||||
"400300",
|
||||
SERVER_APP_ID,
|
||||
"validate",
|
||||
"+quit"
|
||||
]
|
||||
@@ -107,53 +111,175 @@ def download_server(steamcmd_path: str) -> bool:
|
||||
return True
|
||||
|
||||
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()
|
||||
|
||||
split_creds = credentials.split(" ", 1)
|
||||
if len(split_creds) != 2:
|
||||
print("Error: Could not parse username and password!")
|
||||
return (False, [])
|
||||
|
||||
return (True, split_creds)
|
||||
|
||||
def read_workshop(content_file: str) -> tuple:
|
||||
return (False, [])
|
||||
print("Reading Steam Workshop content file...")
|
||||
|
||||
def download_workshop(server_base_path: str, workshop_content: list) -> bool:
|
||||
return False
|
||||
out_content = []
|
||||
|
||||
def move_workshop(server_base_path: str, workshop_content: list) -> bool:
|
||||
return False
|
||||
with open(content_file, "rt") as content:
|
||||
content_ids = content.readlines()
|
||||
for content_id in content_ids:
|
||||
if content_id.strip() == "":
|
||||
break
|
||||
|
||||
def install_workshop(server_base_path: str, workshop_content: list) -> bool:
|
||||
return False
|
||||
if not content_id.isnumeric():
|
||||
print(f"Error: Invalid content ID '{content_id}', all IDs should be numeric!")
|
||||
return (False, [])
|
||||
|
||||
def uninstall_workshop(server_base_path: str, workshop_content: list) -> bool:
|
||||
return False
|
||||
out_content.append(content_id)
|
||||
|
||||
def open_mas2(server_base_path: str) -> bool:
|
||||
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
|
||||
return False
|
||||
print("Opening MAS2 tool...")
|
||||
mas2_path = f"{server_path}/Support/Tools/MAS2_x64.exe"
|
||||
|
||||
def start_server(server_base_path: str) -> bool:
|
||||
return False
|
||||
subprocess.run(
|
||||
[
|
||||
mas2_path
|
||||
]
|
||||
)
|
||||
|
||||
def server_keys(server_base_path: str) -> bool:
|
||||
# download + install basic content here
|
||||
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
|
||||
|
||||
result, workshop_files = move_workshop(server_path, steamcmd_path, SERVER_SETUP_CONTENT)
|
||||
if not result:
|
||||
return False
|
||||
|
||||
if not install_workshop(server_path, workshop_files):
|
||||
return False
|
||||
|
||||
if not open_mas2(server_path):
|
||||
return False
|
||||
|
||||
print("Starting server to get server keys file")
|
||||
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("\t3 - Copy this file to your main rFactor 2 installation which owns the paid DLC you are installing")
|
||||
print(f"\t2 - Once the server is running, ServerKeys.bin should exist at {server_path}/UserData/ServerKeys.bin")
|
||||
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("\t4 - 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("\t5 - Start a single player race (any content I think)")
|
||||
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(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
|
||||
|
||||
def setup_server(server_name: str, server_path: str, content_file: str, credentials_file: str) -> bool:
|
||||
server_base_path = f"{server_path}/{server_name}"
|
||||
def setup_server(server_name: str, parent_path: str, content_file: str, credentials_file: str) -> bool:
|
||||
server_base_path = f"{parent_path}/{server_name}"
|
||||
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
|
||||
|
||||
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):
|
||||
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 True
|
||||
@@ -176,7 +326,7 @@ if __name__ == "__main__":
|
||||
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("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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user