Skip to content

Instantly share code, notes, and snippets.

@toriato
Last active September 22, 2022 14:57
Show Gist options
  • Save toriato/5056e25e8eaeca8277c14fbf657df0ee to your computer and use it in GitHub Desktop.
Save toriato/5056e25e8eaeca8277c14fbf657df0ee to your computer and use it in GitHub Desktop.
Various powershell script for Arma 3 dedicated server
param (
[Parameter(HelpMessage = "서버 경로")]
[String]
$PathToServer = "$(Get-Location)\serverfiles",
[Parameter(HelpMessage = "서버 실행 파일 경로")]
[String]
$PathToServerExecutable = "$(Get-Location)\serverfiles\arma3server_x64_perf.exe",
[Parameter(HelpMessage = "프로필 경로")]
[String]
$PathToProfile = "$(Get-Location)\profiles"
)
$Mods = Get-ChildItem -Directory "$PathToServer\@*" | Foreach-Object { $_.Name }
Start-Process `
-WorkingDirectory $PathToServer `
-FilePath $PathToServerExecutable `
-ArgumentList @(
# '-netlog',
# '-crashDiag',
'-enableHT',
'-filePatching',
'-loadMissionToMemory',
'-autoInit',
# '-port=23000',
"-cfg=`"$PathToProfile\server_basic.cfg`"",
"-config=`"$PathToProfile\server.cfg`"",
"-profiles=`"$PathToProfile`"",
"-mod=`"$($Mods -Join ";")`""
)
param (
[Parameter(HelpMessage = "파일 받을 경로")]
[String]
$Path = "$(Get-Location)\serverfiles",
[Parameter(HelpMessage = "SteamCMD 실행 파일 경로")]
[String]
$PathToSteamCMD = "$(Get-Location)\bin\steamcmd\steamcmd.exe",
[Parameter(HelpMessage = "스팀 아이디")]
[String]
$SteamUser = $Env:STEAM_USER,
[Parameter(HelpMessage = "앱 아이디")]
[UInt32]
$AppId = 233780,
[Parameter(HelpMessage = "베타 브랜치 이름")]
[String]
$BetaName,
[Parameter(HelpMessage = "배타 브랜치 비밀번호")]
[Security.SecureString]
$BetaPassword
)
$AppUpdateCmd = "+app_update $AppId validate"
if ($BetaName -ne $null) { $AppUpdateCmd += " -beta $BetaName" }
if ($BetaPassword -ne $null) { $AppUpdateCmd += " -betapassword $BetaPassword" }
Start-Process -Wait -NoNewWindow -FilePath $PathToSteamCMD -ArgumentList @(
"+force_install_dir $Path",
"+login $SteamUser",
$AppUpdateCmd,
"+exit"
)
Read-Host -Prompt "작업이 완료됐습니다, 아무 키나 눌러 프로세스를 종료합니다"
param (
[Parameter(HelpMessage = "임시 파일 경로")]
[String]
$Path = "$(Get-Location)\serverfiles",
[Parameter(HelpMessage = "SteamCMD 실행 파일 경로")]
[String]
$PathToSteamCMD = "$(Get-Location)\bin\steamcmd\steamcmd.exe",
[Parameter(HelpMessage = "스팀 아이디")]
[String]
$SteamUser = $Env:STEAM_USER,
[Parameter(HelpMessage = "스팀 WebAPI 키")]
[String]
$SteamWebAPIKey = $Env:STEAM_WEBAPI_KEY,
[Parameter(HelpMessage = "앱 아이디")]
[UInt32]
$AppId = 107410,
[Parameter(HelpMessage = "창작마당 아이디")]
[String[]]
$ModIds
)
# EResult
# https://github.com/SteamRE/open-steamworks/blob/f65c0439bf06981285da1e7639de82cd760755b7/Open%20Steamworks/EResult.h#L25
# EWorkshopFileType
# https://github.com/SteamRE/open-steamworks/blob/f65c0439bf06981285da1e7639de82cd760755b7/Open%20Steamworks/RemoteStorageCommon.h#L139
function Get-CollectionDetails {
[OutputType([Hashtable])]
param (
[Parameter(Mandatory)]
[uint64[]]
$publishedFileIds
)
$params = @{
Method = "Post"
Uri = "https://api.steampowered.com/ISteamRemoteStorage/GetCollectionDetails/v1"
ContentType = "application/x-www-form-urlencoded"
Body = @{
key = $SteamWebAPIKey
collectioncount = $publishedFileIds.Count
}
}
for (($i = 0), ($len = $publishedFileIds.Count); $i -lt $len; $i++) {
$params.Body["publishedfileids[$i]"] = $publishedFileIds[$i]
}
$result = Invoke-RestMethod @params
if ($result.response.result -ne 1) {
Write-Error "서버가 결과 코드 $($res.result) 값을 반환했습니다"
}
return $result.response
}
function Get-PublishedFileDetails {
[OutputType([Hashtable])]
param (
[Parameter(Mandatory)]
[uint64[]]
$publishedFileIds
)
$params = @{
Method = "Post"
Uri = "https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1"
ContentType = "application/x-www-form-urlencoded"
Body = @{
key = $SteamWebAPIKey
itemcount = $publishedFileIds.Count
}
}
for (($i = 0), ($len = $publishedFileIds.Count); $i -lt $len; $i++) {
$params.Body["publishedfileids[$i]"] = $publishedFileIds[$i]
}
$result = Invoke-RestMethod @params
if ($result.response.result -ne 1) {
Write-Error "서버가 결과 코드 $($res.result) 값을 반환했습니다"
}
return $result.response
}
function Get-WorkshopIds {
[OutputType([uint64[]])]
param (
[Parameter(Mandatory)]
[uint64[]]
$workshopIds
)
$publishedFileIds = @()
# 창작마당 하위 모음집 모두 가져오기
while ($workshopIds.Length -gt 0) {
$resp = Get-CollectionDetails($workshopIds)
# 하위 모음집이 없으면 반복문을 종료해야하므로 배열 비우기
$workshopIds = @()
foreach ($detail in $resp.collectiondetails) {
# 모음집이 아니라면 결과 코드가 9 이므로 아이템으로 취급하기
if ($detail.result -ne 1) {
$publishedFileIds += $detail.publishedfileid
continue
}
# 하위 모음집 추가하기
foreach ($child in $detail.children) {
if ($child.filetype -eq 2) {
$workshopIds += $child.publishedfileid
continue
}
$publishedFileIds += $child.publishedfileid
}
}
}
return $publishedFileIds
}
if ($ModIds -gt 0) {
$ModIds = Get-WorkshopIds($ModIds)
Write-Output "스팀을 통해 창작마당에서 모드 $($ModIds.Count)개를 받아옵니다: $($ModIds -Join ", ")"
Start-Process -Wait -NoNewWindow -FilePath $PathToSteamCMD -ArgumentList (@(
"+force_install_dir $Path",
"+login $SteamUser"
) + ($ModIds | Foreach-Object { "+workshop_download_item $AppId $_ validate" }) + "+exit")
}
# 기존 서버 폴더 속 모드 정션 제거하기
Remove-Item -Path (Get-ChildItem -Path "$Path\@*" | Where-Object { $_.LinkType -eq "Junction" })
# 스팀CMD 창작마당 모드 폴더로부터 서버 폴더 속으로 정션 연결하기
Get-ChildItem -Directory -Path "$Path\steamapps\workshop\content\$AppId" |`
ForEach-Object {
$modName = $_.Name
# 애드온 메타 파일이 없다면 무시하기
if (-Not (Test-Path -Path "$($_.FullName)\meta.cpp" -PathType Leaf)) {
Write-Output "${modName}: 불러올 수 있는 애드온이 아닙니다"
continue
}
# 애드온 메타 파일에서 이름 가져오기
if ($groups = (Get-Content -Path "$($_.FullName)\meta.cpp" | Select-String -Pattern "name = `"([^`"]+)").Matches.Groups) {
$modName = $groups[1].Value `
-replace "[$([RegEx]::Escape([System.IO.Path]::GetInvalidFileNameChars()))]+", "_"
}
if (Test-Path -Path "$Path\@$modName") {
Write-Output "${modName}: 정션을 만들 수 없습니다, 같은 이름을 가진 파일 또는 폴더가 존재합니다"
continue
}
New-Item -ErrorAction Ignore -ItemType Junction -Path $Path -Name "@$modName" -Value $_.FullName
}
@toriato
Copy link
Author

toriato commented Apr 19, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment