Last active
October 17, 2024 19:27
-
-
Save dinhani/3ce1bf3b47fb3de283f7ba5e35e02dea to your computer and use it in GitHub Desktop.
LaunchBox to Playnite data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ------------------------------------------------------------------------------ | |
# Connect | |
# ------------------------------------------------------------------------------ | |
# $PlayniteRunspace = Get-Runspace -Name 'PSInteractive' | |
# $PlayniteApi = $PlayniteRunspace.SessionStateProxy.GetVariable('PlayniteApi') | |
# D:\codigos\automacoes\jogos\launchbox-to-playnite.ps1 | |
# ------------------------------------------------------------------------------ | |
# Constants | |
# ------------------------------------------------------------------------------ | |
$LAUNCHBOX_DIR = "C:/_emu/launchbox" | |
$LAUNCHBOX_IMAGE_CACHE_DIR = "C:/_emu/launchbox/Images/Cache-LB" | |
$PLAYNITE_IMAGES_DIR = "C:/_emu/playnite/library/files-launchbox" | |
# ------------------------------------------------------------------------------ | |
# Functions | |
# ------------------------------------------------------------------------------ | |
# Returns the platform directory name based on the platform name. | |
function PlatformDir { | |
param( | |
[Parameter(Mandatory = $true)] | |
[string]$PlatformName | |
) | |
$dir = $PlatformName.ToLower() -replace '\s+', '-' | |
switch ($dir) { | |
"3do-interactive-multiplayer" { return "3do" } | |
default { return $dir } | |
} | |
} | |
# Returns the image filename based on the game title. | |
function GameImage { | |
param( | |
[Parameter(Mandatory = $true)] | |
[string]$GameTitle | |
) | |
return $GameTitle.Replace("'", "_").Replace(":", "_").Replace("?", "_").Replace("<", "_").Replace(">", "_").Replace(" - ", "_") | |
} | |
# Copies a file if source exists and destination does not. | |
function CopyIfPossible { | |
param( | |
[Parameter(Mandatory = $true)] | |
[string]$Source, | |
[Parameter(Mandatory = $true)] | |
[string]$Destination | |
) | |
try { | |
if (-not (Test-Path -LiteralPath $Source)) { | |
return $false | |
} | |
if (Test-Path -LiteralPath $Destination) { | |
return $false | |
} | |
New-Item -ItemType File -Path $Destination -Force | Out-Null | |
Copy-Item -Path $Source -Destination $Destination -Force | |
return $true | |
} | |
catch { | |
Write-Error "Error copying file: $_" | |
return $false | |
} | |
} | |
# ------------------------------------------------------------------------------ | |
# Reference data | |
# ------------------------------------------------------------------------------ | |
$AGE_RATINGS = @{} | |
$PlayniteApi.Database.AgeRatings | ForEach-Object { $AGE_RATINGS[$_.Name] = $_ } | |
$COMPANIES = @{} | |
$PlayniteApi.Database.Companies | ForEach-Object { $COMPANIES[$_.Name] = $_ } | |
$EMULATORS = @{} | |
$PlayniteApi.Database.Emulators | ForEach-Object { $EMULATORS[$_.Name] = $_ } | |
$EMULATORS_SPECS = @{} | |
$PlayniteApi.Emulation.Emulators | ForEach-Object { $EMULATORS_SPECS[$_.Name] = $_ } | |
$FEATURES = @{} | |
$PlayniteApi.Database.Features | ForEach-Object { $FEATURES[$_.Name] = $_ } | |
$GAMES = @{} | |
$PlayniteApi.Database.Games | ForEach-Object { $GAMES[$_.GameId] = $_ } | |
$GENRES = @{} | |
$PlayniteApi.Database.Genres | ForEach-Object { $GENRES[$_.Name] = $_ } | |
$PLATFORMS = @{} | |
$PlayniteApi.Database.Platforms | ForEach-Object { $PLATFORMS[$_.Name] = $_ } | |
$PLATFORMS_SPECS = @{} | |
$PlayniteApi.Emulation.Platforms | ForEach-Object { $PLATFORMS_SPECS[$_.Name] = $_ } | |
$PLATFORMS_SPECS["Super Nintendo Entertainment System"] = ($PlayniteApi.Emulation.Platforms | Where-Object Id -eq "nintendo_super_nes")[0] | |
$REGIONS = @{} | |
$PlayniteApi.Database.Regions | ForEach-Object { $REGIONS[$_.Name] = $_ } | |
$SERIES = @{} | |
$PlayniteApi.Database.Series | ForEach-Object { $SERIES[$_.Name] = $_ } | |
$TAGS = @{} | |
$PlayniteApi.Database.Tags | ForEach-Object { $TAGS[$_.Name] = $_ } | |
# ------------------------------------------------------------------------------ | |
# Import Emulators | |
# ------------------------------------------------------------------------------ | |
[xml]$emulatorsXml = Get-Content "$LAUNCHBOX_DIR/Data/Emulators.xml" -Encoding UTF8 | |
$emulatorsXml.LaunchBox.Emulator | ForEach-Object { | |
$emulatorXml = $_ | |
Write-Host "Emulator: $($emulatorXml.Title)" | |
# get emulator | |
$emulator = $EMULATORS[$emulatorXml.Title] | |
if ($emulator -eq $null) { | |
$emulator = New-Object Playnite.SDK.Models.Emulator | |
$new = $true | |
} | |
else { | |
$new = $false | |
} | |
# fill emulator info | |
$emulator.Name = $emulatorXml.Title | |
$emulator.InstallDir = [System.IO.Path]::GetDirectoryName($emulatorXml.ApplicationPath) | |
$emulator.BuiltInConfigId = $EMULATORS_SPECS[$emulator.Name].Id | |
$emulator.BuiltinProfiles = New-Object System.Collections.Generic.List[Playnite.SDK.Models.BuiltInEmulatorProfile] | |
$EMULATORS_SPECS[$emulator.Name].Profiles | ForEach-Object { | |
$refProfile = $_ | |
$emulatorProfile = New-Object Playnite.SDK.Models.BuiltInEmulatorProfile | |
$emulatorProfile.Name = $refProfile.Name | |
$emulatorProfile.BuiltInProfileName = $refProfile.Name | |
$emulator.BuiltinProfiles.Add($emulatorProfile) | |
} | |
# save emulator | |
if ($new) { | |
$PlayniteApi.Database.Emulators.Add($emulator) | |
} | |
else { | |
$PlayniteApi.Database.Emulators.Update($emulator) | |
} | |
$EMULATORS[$emulator.Name] = $PlayniteApi.Database.Emulators.Get($emulator.ID) | |
} | |
# ------------------------------------------------------------------------------ | |
# Import Games | |
# ------------------------------------------------------------------------------ | |
Get-ChildItem "$LAUNCHBOX_DIR/Data/Platforms" | ForEach-Object { | |
Write-Host "Platform: $($_.FullName)" | |
[xml]$platformXml = Get-Content $_.FullName -Encoding UTF8 | |
$platformXml.launchbox.Game | Sort-Object -Property Title | ForEach-Object { | |
$gameXml = $_ | |
# ---------------------------------------------------------------------- | |
# Game | |
# ---------------------------------------------------------------------- | |
$game = $GAMES[$gameXml.ID] | |
if ($game -eq $null) { | |
$game = New-Object Playnite.SDK.Models.Game | |
$new = $true | |
} | |
else { | |
$new = $false | |
} | |
$game.GameId = $gameXml.ID | |
# ---------------------------------------------------------------------- | |
# Images (disabled because Playnite delete files on game deletion) | |
# ---------------------------------------------------------------------- | |
# create game images dir for game | |
$gameImages = "$PLAYNITE_IMAGES_DIR/$($game.GameId)" | |
New-Item -Path $gameImages -ItemType Directory -Force | Out-Null | |
$coverSource = Join-Path $LAUNCHBOX_IMAGE_CACHE_DIR ".Boxes-$($game.GameId)-372-745" | |
$coverTarget = Join-Path $gameImages "cover" | |
if (CopyIfPossible "$coverSource.jpg" "$coverTarget.jpg") { | |
$game.CoverImage = "$coverTarget.jpg" | |
} | |
elseif (CopyIfPossible "$coverSource.png" "$coverTarget.png") { | |
$game.CoverImage = "$coverTarget.png" | |
} | |
$backgroundSource = Join-Path $LAUNCHBOX_IMAGE_CACHE_DIR ".Screenshots-$($game.GameId)-372-745" | |
$backgroundTarget = Join-Path $gameImages "background" | |
if (CopyIfPossible "$backgroundSource.jpg" "$backgroundTarget.jpg") { | |
$game.BackgroundImage = "$backgroundTarget.jpg" | |
} | |
elseif (CopyIfPossible "$backgroundSource.png" "$backgroundTarget.png") { | |
$game.BackgroundImage = "$backgroundTarget.png" | |
} | |
# ---------------------------------------------------------------------- | |
# ROMs | |
# ---------------------------------------------------------------------- | |
$gamePath = $gameXml.ApplicationPath | |
$game.Roms = New-Object System.Collections.Generic.List[Playnite.SDK.Models.GameRom] | |
$rom = New-Object Playnite.SDK.Models.GameRom -ArgumentList $gameXml.Region, $gamePath | |
$game.Roms.Add($rom) | |
# ---------------------------------------------------------------------- | |
# Links | |
# ---------------------------------------------------------------------- | |
$game.Links = New-Object System.Collections.Generic.List[Playnite.SDK.Models.Link] | |
if (-not [string]::IsNullOrEmpty($gameXml.WikipediaURL)) { | |
$linkWikipedia = New-Object Playnite.SDK.Models.Link -ArgumentList Wikipedia, $gameXml.WikipediaURL | |
$game.Links.Add($linkWikipedia) | |
} | |
if (-not [string]::IsNullOrEmpty($gameXml.VideoUrl)) { | |
$linkVideo = New-Object Playnite.SDK.Models.Link -ArgumentList Video, $gameXml.VideoUrl | |
$game.Links.Add($linkVideo) | |
} | |
# ---------------------------------------------------------------------- | |
# Platform | |
# ---------------------------------------------------------------------- | |
$platformName = $gameXml.Platform | |
if ($PLATFORMS[$platformName] -eq $null) { | |
Write-Warning "Creating platform: $platformName" | |
$platform = New-Object Playnite.SDK.Models.Platform | |
$platform.Id = [System.Guid]::NewGuid() | |
$platform.Name = $platformName | |
$platform.SpecificationId = $PLATFORMS_SPECS[$platformName].Id | |
$PlayniteApi.Database.Platforms.Add($platform) | |
$PLATFORMS[$platformName] = $PlayniteApi.Database.Platforms.Get($platform.Id) | |
} | |
$game.PlatformIds = $PLATFORMS[$platformName].Id | |
# ---------------------------------------------------------------------- | |
# Release Date | |
# ---------------------------------------------------------------------- | |
$releaseDate = $gameXml.ReleaseDate | |
if (-not [string]::IsNullOrEmpty($releaseDate)) { | |
$game.ReleaseDate = [datetime]::Parse($releaseDate) | |
} | |
# ---------------------------------------------------------------------- | |
# Genre | |
# ---------------------------------------------------------------------- | |
$game.GenreIds = New-Object System.Collections.Generic.List[System.Guid] | |
$gameXml.Genre -Split "; " | ForEach-Object { | |
$genreName = $_ | |
if ($genreName -eq "") { | |
return | |
} | |
if ($GENRES[$genreName] -eq $null) { | |
Write-Warning "Creating genre: $genreName" | |
$GENRES[$genreName] = $PlayniteApi.Database.Genres.Add($genreName) | |
} | |
$game.GenreIds.Add($GENRES[$genreName].Id) | |
} | |
# ---------------------------------------------------------------------- | |
# Features | |
# ---------------------------------------------------------------------- | |
$game.FeatureIds = New-Object System.Collections.Generic.List[System.Guid] | |
# PlayMode | |
$gameXml.PlayMode -Split "; " | ForEach-Object { | |
$playmodeName = $_ | |
if ($playmodeName -eq "") { | |
return | |
} | |
if ($FEATURES[$playmodeName] -eq $null) { | |
Write-Warning "Creating feature: $playmodeName" | |
$FEATURES[$playmodeName] = $PlayniteApi.Database.Features.Add($playmodeName) | |
} | |
$game.FeatureIds.Add($FEATURES[$playmodeName].Id) | |
} | |
# ---------------------------------------------------------------------- | |
# Developer / Publisher | |
# ---------------------------------------------------------------------- | |
$developerName = $gameXml.Developer | |
if (-not [string]::IsNullOrEmpty($developerName)) { | |
if ($COMPANIES[$developerName] -eq $null) { | |
Write-Warning "Creating developer: $developerName" | |
$COMPANIES[$developerName] = $PlayniteApi.Database.Companies.Add($developerName) | |
} | |
$game.DeveloperIds = $COMPANIES[$developerName].Id | |
} | |
$publisherName = $gameXml.Publisher | |
if (-not [string]::IsNullOrEmpty($publisherName)) { | |
if ($COMPANIES[$publisherName] -eq $null) { | |
Write-Warning "Creating publisher: $publisherName" | |
$COMPANIES[$publisherName] = $PlayniteApi.Database.Companies.Add($publisherName) | |
} | |
$game.PublisherIds = $COMPANIES[$publisherName].Id | |
} | |
# ---------------------------------------------------------------------- | |
# Region | |
# ---------------------------------------------------------------------- | |
$game.RegionIds = New-Object System.Collections.Generic.List[System.Guid] | |
$gameXml.Region -Split ", " | ForEach-Object { | |
$regionName = $_ | |
if ($regionName -eq "") { | |
return | |
} | |
if ($REGIONS[$regionName] -eq $null) { | |
Write-Warning "Creating region: $regionName" | |
$REGIONS[$regionName] = $PlayniteApi.Database.Regions.Add($regionName) | |
} | |
$game.RegionIds.Add($REGIONS[$regionName].Id) | |
} | |
# ---------------------------------------------------------------------- | |
# Age Rating | |
# ---------------------------------------------------------------------- | |
$ageRatingName = $gameXml.Rating | |
if (-not [string]::IsNullOrEmpty($ageRatingName)) { | |
if ($AGE_RATINGS[$ageRatingName] -eq $null) { | |
Write-Warning "Creating age rating: $ageRatingName" | |
$AGE_RATINGS[$ageRatingName] = $PlayniteApi.Database.AgeRatings.Add($ageRatingName) | |
} | |
$game.AgeRatingIds = $AGE_RATINGS[$ageRatingName].Id | |
} | |
# ---------------------------------------------------------------------- | |
# Series | |
# ---------------------------------------------------------------------- | |
$seriesName = $gameXml.Series | |
if (-not [string]::IsNullOrEmpty($seriesName)) { | |
if ($SERIES[$seriesName] -eq $null) { | |
Write-Warning "Creating series: $seriesName" | |
$SERIES[$seriesName] = $PlayniteApi.Database.Series.Add($seriesName) | |
} | |
$game.SeriesIds = $SERIES[$seriesName].Id | |
} | |
# ---------------------------------------------------------------------- | |
# Actions | |
# ---------------------------------------------------------------------- | |
$game.GameActions = New-Object System.Collections.Generic.List[Playnite.SDK.Models.GameAction] | |
$action = New-Object Playnite.SDK.Models.GameAction | |
$action.Name = "Play" | |
$action.IsPlayAction = $true | |
$action.Type = "Emulator" | |
$game.GameActions = $action | |
# ---------------------------------------------------------------------- | |
# Basic Info | |
# ---------------------------------------------------------------------- | |
$game.Name = $gameXml.Title | |
$game.Description = $gameXml.Notes | |
$game.IsInstalled = $platformName -ne "Windows" | |
$game.InstallDirectory = [System.IO.Path]::GetDirectoryName($gamePath) | |
$game.InstallSize = $(Get-ChildItem $gamePath).Length | |
$game.CommunityScore = 10 * [double]::Parse($gameXml.CommunityStarRating, [System.Globalization.CultureInfo]::InvariantCulture) | |
# ---------------------------------------------------------------------- | |
# Save | |
# ---------------------------------------------------------------------- | |
if ($new) { | |
$PlayniteApi.Database.Games.Add($game) | |
} | |
else { | |
$PlayniteApi.Database.Games.Update($game) | |
} | |
$GAMES[$game.GameId] = $PlayniteApi.Database.Games.Get($game.GameID) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment