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