mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 05:28:56 +02:00
203 lines
9.2 KiB
Swift
203 lines
9.2 KiB
Swift
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, Stossy11
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
import SwiftUI
|
|
import Foundation
|
|
import UIKit
|
|
import Zip
|
|
|
|
struct Core : Comparable, Hashable {
|
|
|
|
let name = "Yuzu"
|
|
var games: [EmulationGame]
|
|
let root: URL
|
|
|
|
static func < (lhs: Core, rhs: Core) -> Bool {
|
|
lhs.name < rhs.name
|
|
}
|
|
|
|
func AddFirmware(at fileURL: URL) {
|
|
do {
|
|
let fileManager = FileManager.default
|
|
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
|
|
let destinationURL = documentsDirectory.appendingPathComponent("nand/system/Contents/registered")
|
|
|
|
|
|
if !fileManager.fileExists(atPath: destinationURL.path) {
|
|
try fileManager.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil)
|
|
}
|
|
|
|
|
|
try Zip.unzipFile(fileURL, destination: destinationURL, overwrite: true, password: nil)
|
|
print("File unzipped successfully to \(destinationURL.path)")
|
|
|
|
} catch {
|
|
print("Failed to unzip file: \(error)")
|
|
}
|
|
}
|
|
}
|
|
|
|
enum LibManError : Error {
|
|
case ripenum, urlgobyebye
|
|
}
|
|
|
|
class LibraryManager {
|
|
static let shared = LibraryManager()
|
|
let documentdir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("roms", conformingTo: .folder)
|
|
|
|
func removerom(_ game: EmulationGame) throws {
|
|
do {
|
|
try FileManager.default.removeItem(at: game.fileURL)
|
|
} catch {
|
|
throw error
|
|
}
|
|
}
|
|
|
|
func homebrewroms() -> [EmulationGame] {
|
|
// TODO(lizzie): this is horrible
|
|
var urls: [URL] = []
|
|
let sdmc = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("sdmc", conformingTo: .folder)
|
|
let sdfolder = sdmc.appendingPathComponent("switch", conformingTo: .folder)
|
|
if FileManager.default.fileExists(atPath: sdfolder.path) {
|
|
if let dirContents = FileManager.default.enumerator(at: sdmc, includingPropertiesForKeys: nil, options: []) {
|
|
do {
|
|
try dirContents.forEach() { files in
|
|
if let file = files as? URL {
|
|
let getaboutfile = try file.resourceValues(forKeys: [.isRegularFileKey])
|
|
if let isfile = getaboutfile.isRegularFile, isfile {
|
|
if ["nso", "nro"].contains(file.pathExtension.lowercased()) {
|
|
urls.append(file)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch {
|
|
if let dirContents = FileManager.default.enumerator(at: documentdir, includingPropertiesForKeys: nil, options: []) {
|
|
do {
|
|
try dirContents.forEach() { files in
|
|
if let file = files as? URL {
|
|
let getaboutfile = try file.resourceValues(forKeys: [.isRegularFileKey])
|
|
if let isfile = getaboutfile.isRegularFile, isfile {
|
|
if ["nso", "nro"].contains(file.pathExtension.lowercased()) {
|
|
urls.append(file)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch {
|
|
print("damn")
|
|
if let dirContents = FileManager.default.enumerator(at: documentdir, includingPropertiesForKeys: nil, options: []) {
|
|
do {
|
|
try dirContents.forEach() { files in
|
|
if let file = files as? URL {
|
|
let getaboutfile = try file.resourceValues(forKeys: [.isRegularFileKey])
|
|
if let isfile = getaboutfile.isRegularFile, isfile {
|
|
if ["nso", "nro"].contains(file.pathExtension.lowercased()) {
|
|
urls.append(file)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch {
|
|
return []
|
|
}
|
|
} else {
|
|
return []
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if let dirContents = FileManager.default.enumerator(at: documentdir, includingPropertiesForKeys: nil, options: []) {
|
|
do {
|
|
try dirContents.forEach() { files in
|
|
if let file = files as? URL {
|
|
let getaboutfile = try file.resourceValues(forKeys: [.isRegularFileKey])
|
|
if let isfile = getaboutfile.isRegularFile, isfile {
|
|
if ["nso", "nro"].contains(file.pathExtension.lowercased()) {
|
|
urls.append(file)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch {
|
|
return []
|
|
}
|
|
} else {
|
|
return []
|
|
}
|
|
func games(from urls: [URL]) -> [EmulationGame] {
|
|
var pomelogames: [EmulationGame] = []
|
|
pomelogames = urls.reduce(into: [EmulationGame]()) { partialResult, element in
|
|
let iscustom = element.startAccessingSecurityScopedResource()
|
|
let information = AppUI.shared.information(for: element)
|
|
let game = EmulationGame(developer: information.developer, fileURL: element, imageData: information.iconData, title: information.title)
|
|
if iscustom {
|
|
element.stopAccessingSecurityScopedResource()
|
|
}
|
|
partialResult.append(game)
|
|
}
|
|
return pomelogames
|
|
}
|
|
return games(from: urls)
|
|
}
|
|
|
|
func library() throws -> Core {
|
|
func getromsfromdir() throws -> [URL] {
|
|
guard let dirContents = FileManager.default.enumerator(at: documentdir, includingPropertiesForKeys: nil, options: []) else {
|
|
print("uhoh how unfortunate for some reason FileManager.default.enumerator aint workin")
|
|
throw LibManError.ripenum
|
|
}
|
|
let appui = AppUI.shared
|
|
var urls: [URL] = []
|
|
try dirContents.forEach() { files in
|
|
if let file = files as? URL {
|
|
let getaboutfile = try file.resourceValues(forKeys: [.isRegularFileKey])
|
|
if let isfile = getaboutfile.isRegularFile, isfile {
|
|
if ["nca", "nro", "nsp", "nso", "xci"].contains(file.pathExtension.lowercased()) {
|
|
urls.append(file)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
let sdmc = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("sdmc", conformingTo: .folder)
|
|
let sdfolder = sdmc.appendingPathComponent("switch", conformingTo: .folder)
|
|
if FileManager.default.fileExists(atPath: sdfolder.path) {
|
|
if let dirContents = FileManager.default.enumerator(at: sdmc, includingPropertiesForKeys: nil, options: []) {
|
|
try dirContents.forEach() { files in
|
|
if let file = files as? URL {
|
|
let getaboutfile = try file.resourceValues(forKeys: [.isRegularFileKey])
|
|
if let isfile = getaboutfile.isRegularFile, isfile {
|
|
if ["nso", "nro"].contains(file.pathExtension.lowercased()) {
|
|
urls.append(file)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
appui.insert(games: urls)
|
|
return urls
|
|
}
|
|
|
|
func games(from urls: [URL], core: inout Core) {
|
|
core.games = urls.reduce(into: [EmulationGame]()) { partialResult, element in
|
|
let iscustom = element.startAccessingSecurityScopedResource()
|
|
let information = AppUI.shared.information(for: element)
|
|
let game = EmulationGame(developer: information.developer, fileURL: element, imageData: information.iconData, title: information.title)
|
|
if iscustom {
|
|
element.stopAccessingSecurityScopedResource()
|
|
}
|
|
partialResult.append(game)
|
|
}
|
|
}
|
|
let directory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
|
var YuzuCore = Core(games: [], root: directory)
|
|
games(from: try getromsfromdir(), core: &YuzuCore)
|
|
return YuzuCore
|
|
}
|
|
}
|