Skip to content

Commit

Permalink
Merge pull request #149 from MythicApp/dev
Browse files Browse the repository at this point in the history
Mythic v0.4.0 | "Silver Chariot"
  • Loading branch information
vapidinfinity authored Oct 21, 2024
2 parents 6993b0f + 3e49a6d commit ac61435
Show file tree
Hide file tree
Showing 65 changed files with 1,720 additions and 1,401 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ on:

jobs:
build:
runs-on: macos-14
runs-on: macos-15
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand Down
56 changes: 32 additions & 24 deletions Mythic.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

115 changes: 97 additions & 18 deletions Mythic/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//

// MARK: - Copyright
// Copyright © 2023 blackxfiied, Jecta
// Copyright © 2023 blackxfiied

// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Expand All @@ -31,27 +31,14 @@ class AppDelegate: NSObject, NSApplicationDelegate { // https://arc.net/l/quote/
"quitOnAppClose": false
])

// MARK: Bottle cleanup in the event of external deletion
Wine.bottleURLs = Wine.bottleURLs.filter { files.fileExists(atPath: $0.path(percentEncoded: false)) }

// MARK: Refresh legendary metadata
Task(priority: .utility) {
try? await Legendary.command(arguments: ["status"], identifier: "refreshMetadata") { _ in }
}

// MARK: Autosync Epic savedata
Task(priority: .utility) {
try? await Legendary.command(arguments: ["sync-saves"], identifier: "sync-saves") { _ in }
}

// MARK: 0.1.x bottle migration
if let data = defaults.data(forKey: "allBottles"),
let decodedData = try? PropertyListSerialization.propertyList(from: data, format: nil) as? [String: [String: Any]] {

Logger.app.log("Older bottle format detected, commencing bottle management system migration")

var iterations = 0
var convertedBottles: [Wine.Bottle] = .init()
var convertedBottles: [Wine.Container] = .init()

for (name, bottle) in decodedData {
guard let urlArray = bottle["url"] as? [String: String], // unable to cast directly to URL
Expand All @@ -60,15 +47,15 @@ class AppDelegate: NSObject, NSApplicationDelegate { // https://arc.net/l/quote/
return
}

var settings = Wine.defaultBottleSettings
var settings = Wine.defaultContainerSettings
guard let oldSettings = bottle["settings"] as? [String: Bool] else { Logger.file.warning("Unable to read old bottle settings; using default"); continue }
settings.metalHUD = oldSettings["metalHUD"] ?? settings.metalHUD
settings.msync = oldSettings["msync"] ?? settings.msync
settings.retinaMode = oldSettings["retinaMode"] ?? settings.retinaMode

Task { @MainActor in
convertedBottles.append(.init(name: name, url: url, settings: settings))
Wine.bottleURLs.insert(url)
Wine.containerURLs.insert(url)
}

iterations += 1
Expand All @@ -80,6 +67,92 @@ class AppDelegate: NSObject, NSApplicationDelegate { // https://arc.net/l/quote/
defaults.removeObject(forKey: "allBottles")
}

// MARK: >= 0.3.2 Bottle → Container migration
let oldBottles = Bundle.appContainer!.appending(path: "Bottles")
let newBottles = Bundle.appContainer!.appending(path: "Containers")

if defaults.integer(forKey: "defaultsVersion") == 0 {
Logger.app.log("Commencing bottle renaming (Bottle → Container)")

do {
try files.moveItem(at: oldBottles, to: newBottles)
if let contents = try? files.contentsOfDirectory(at: newBottles, includingPropertiesForKeys: nil) {
contents.forEach { containerURL in
Logger.app.debug("Migrating container object: \(String(describing: Wine.Container(knownURL: containerURL)))")
}
}

// Migrate bottleURLs to containerURLs
if let bottleURLs = try? defaults.decodeAndGet([URL].self, forKey: "bottleURLs") {
let containerURLs = bottleURLs.map { bottleURL -> URL in
let currentPath = bottleURL.path(percentEncoded: false)
if currentPath.contains(oldBottles.path(percentEncoded: false)) {
let newPath = currentPath.replacingOccurrences(of: oldBottles.path(percentEncoded: false), with: newBottles.path(percentEncoded: false))
Logger.app.debug("Migrating bottle (modifying bottle URL from \(bottleURL) to \(newPath))...")
return URL(fileURLWithPath: newPath)
} else {
return bottleURL
}
}

do {
try defaults.encodeAndSet(containerURLs, forKey: "containerURLs")
defaults.removeObject(forKey: "bottleURLs")
} catch {
Logger.app.error("Unable to re-encode default 'bottleURLs' as 'containerURLs': \(error.localizedDescription)")
}
}

// Game-specific bottleURL migration
defaults.dictionaryRepresentation()
.filter { $0.key.hasSuffix("_bottleURL") }
.forEach { key, value in
guard let currentURL = value as? URL else { return }
let currentPath = currentURL.path(percentEncoded: false)
guard files.fileExists(atPath: currentPath) else { return }

let filteredURL: URL
if currentPath.contains(oldBottles.path(percentEncoded: false)) {
let newPath = currentPath.replacingOccurrences(of: oldBottles.path(percentEncoded: false), with: newBottles.path(percentEncoded: false))
filteredURL = URL(fileURLWithPath: newPath)
} else {
filteredURL = currentURL
}

let gameKey = key.replacingOccurrences(of: "_bottleURL", with: "")
Logger.app.debug("Migrating game \(gameKey)'s container URL...")
defaults.set(filteredURL, forKey: key.replacingOccurrences(of: "_bottleURL", with: "_containerURL"))
defaults.removeObject(forKey: key)
}

Logger.app.notice("Container renaming complete.")
} catch {
Logger.app.error("Unable to rename Bottles to Containers: \(error.localizedDescription) -- Mythic may not function correctly.")
}
}

// MARK: Container cleanup in the event of external deletion
Wine.containerURLs = Wine.containerURLs.filter { files.fileExists(atPath: $0.path(percentEncoded: false)) }

// MARK: <0.3.2 Config folder rename (Config → Epic)
let legendaryOldConfig: URL = Bundle.appHome!.appending(path: "Config")
if files.fileExists(atPath: legendaryOldConfig.path) {
try? files.moveItem(at: legendaryOldConfig, to: Legendary.configurationFolder)
}

Task(priority: .utility) {
Legendary.updateMetadata()

Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { _ in
Legendary.updateMetadata()
}
}

// MARK: Autosync Epic savedata
Task(priority: .utility) {
try? await Legendary.command(arguments: ["sync-saves"], identifier: "sync-saves") { _ in }
}

// MARK: DiscordRPC Connection and Delegation Setting
discordRPC.delegate = self
if defaults.bool(forKey: "discordRPC") { _ = discordRPC.connect() }
Expand Down Expand Up @@ -136,7 +209,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { // https://arc.net/l/quote/
}
}

if defaults.bool(forKey: "engineAutomaticallyChecksForUpdates"), Engine.needsUpdate() == true {
if defaults.bool(forKey: "engineAutomaticallyChecksForUpdates"), Engine.needsUpdate() == true, Engine.isLatestVersionReadyForDownload() == true {
let alert = NSAlert()
if let currentEngineVersion = Engine.version,
let latestEngineVersion = Engine.fetchLatestVersion() {
Expand Down Expand Up @@ -185,6 +258,12 @@ class AppDelegate: NSObject, NSApplicationDelegate { // https://arc.net/l/quote/
}
}
}

/*
MARK: Defaults version
Useful for migration after non-backwards-compatible update
*/
defaults.register(defaults: ["defaultsVersion": 1])
}

func applicationDidBecomeActive(_: Notification) {
Expand Down
6 changes: 3 additions & 3 deletions Mythic/Assets.xcassets/Steam.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"images" : [
{
"filename" : "Steam@1x.png",
"filename" : "steam.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Steam@2x.png",
"filename" : "steam@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Steam@3x.png",
"filename" : "steam@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
Expand Down
Binary file removed Mythic/Assets.xcassets/Steam.imageset/Steam@1x.png
Binary file not shown.
Binary file modified Mythic/Assets.xcassets/Steam.imageset/Steam@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Mythic/Assets.xcassets/Steam.imageset/Steam@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Mythic/Assets.xcassets/Steam.imageset/steam.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit ac61435

Please sign in to comment.