Skip to content

Commit

Permalink
Musixmatch Invalid Token Alert, better token input, Overwrite Configu…
Browse files Browse the repository at this point in the history
…ration Option
  • Loading branch information
whoeevee committed Jun 4, 2024
1 parent e258ebc commit 3c5509e
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 48 deletions.
37 changes: 25 additions & 12 deletions Sources/EeveeSpotify/Lyrics/CustomLyrics.x.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,36 @@ func getCurrentTrackLyricsData(originalLyrics: Lyrics? = nil) throws -> Data {
)
}

catch {

if source != .genius && UserDefaults.geniusFallback {
catch let error as LyricsError {

switch error {

case .InvalidMusixmatchToken:

NSLog("[EeveeSpotify] Unable to load lyrics from \(source): \(error), trying Genius as fallback")
source = .genius

plainLyrics = try LyricsRepository.getLyrics(
title: track.trackTitle(),
artist: track.artistTitle(),
spotifyTrackId: track.URI().spt_trackIdentifier(),
source: source
PopUpHelper.showPopUp(
delayed: false,
message: "The tweak is unable to load lyrics from Musixmatch due to Unauthorized error. Please check or update your Musixmatch token.",
buttonText: "OK"
)
break

default:
break
}
else {

if source == .genius || !UserDefaults.geniusFallback {
throw error
}

NSLog("[EeveeSpotify] Unable to load lyrics from \(source): \(error), trying Genius as fallback")
source = .genius

plainLyrics = try LyricsRepository.getLyrics(
title: track.trackTitle(),
artist: track.artistTitle(),
spotifyTrackId: track.URI().spt_trackIdentifier(),
source: source
)
}

let lyrics = try Lyrics.with {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ struct MusixmatchLyricsDataSource {
else {
throw LyricsError.DecodingError
}

if let header = message["header"] as? [String: Any],
header["status_code"] as? Int == 401 {
throw LyricsError.InvalidMusixmatchToken
}

if let trackSubtitlesGet = macroCalls["track.subtitles.get"] as? [String: Any],
let subtitlesMessage = trackSubtitlesGet["message"] as? [String: Any],
Expand Down
3 changes: 2 additions & 1 deletion Sources/EeveeSpotify/Lyrics/Models/LyricsError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Foundation

enum LyricsError: Swift.Error {
case NoCurrentTrack
case InvalidMusixmatchToken
case DecodingError
case NoSuchSong
}
}
15 changes: 15 additions & 0 deletions Sources/EeveeSpotify/Models/Extensions/String+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,19 @@ extension String {
withTemplate: ""
)
}

var hexadecimal: Data? {
var data = Data(capacity: count / 2)

let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive)
regex.enumerateMatches(in: self, range: NSRange(startIndex..., in: self)) { match, _, _ in
let byteString = (self as NSString).substring(with: match!.range)
let num = UInt8(byteString, radix: 16)!
data.append(num)
}

guard data.count > 0 else { return nil }

return data
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ extension UserDefaults {
private static let geniusFallbackKey = "geniusFallback"
private static let darkPopUpsKey = "darkPopUps"
private static let patchTypeKey = "patchType"
private static let overwriteConfigurationKey = "overwriteConfiguration"

static var lyricsSource: LyricsSource {
get {
Expand Down Expand Up @@ -62,4 +63,13 @@ extension UserDefaults {
defaults.set(patchType.rawValue, forKey: patchTypeKey)
}
}

static var overwriteConfiguration: Bool {
get {
defaults.bool(forKey: overwriteConfigurationKey)
}
set (overwriteConfiguration) {
defaults.set(overwriteConfiguration, forKey: overwriteConfigurationKey)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import Foundation

func modifyRemoteConfiguration(_ configuration: inout UcsResponse) {

if UserDefaults.overwriteConfiguration {
configuration.resolve.configuration = try! BundleHelper.shared.resolveConfiguration()
}

modifyAttributes(&configuration.attributes.accountAttributes)
}

Expand Down
28 changes: 13 additions & 15 deletions Sources/EeveeSpotify/Premium/DynamicPremium.x.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ class SPTCoreURLSessionDataDelegateHook: ClassHook<NSObject> {

var bootstrapMessage = try BootstrapMessage(serializedData: buffer)

if UserDefaults.patchType == .notSet {

if bootstrapMessage.attributes["type"]?.stringValue == "premium" {
UserDefaults.patchType = .disabled
showHavePremiumPopUp()
}
else {
UserDefaults.patchType = .requests
}

NSLog("[EeveeSpotify] Fetched bootstrap, \(UserDefaults.patchType) was set")
}

if UserDefaults.patchType == .requests {

modifyRemoteConfiguration(&bootstrapMessage.ucsResponse)
Expand All @@ -75,21 +88,6 @@ class SPTCoreURLSessionDataDelegateHook: ClassHook<NSObject> {
NSLog("[EeveeSpotify] Modified bootstrap data")
}
else {

if UserDefaults.patchType == .notSet {

if bootstrapMessage.attributes["type"]?.stringValue == "premium" {
UserDefaults.patchType = .disabled
showHavePremiumPopUp()
}
else {
UserDefaults.patchType = .offlineBnk
showOfflineBnkMethodSetPopUp()
}

NSLog("[EeveeSpotify] Fetched bootstrap, \(UserDefaults.patchType) was set")
}

orig.URLSession(session, dataTask: task, didReceiveData: buffer)
}

Expand Down
11 changes: 11 additions & 0 deletions Sources/EeveeSpotify/Premium/Helpers/BundleHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,15 @@ class BundleHelper {
)!
)
}

func resolveConfiguration() throws -> ResolveConfiguration {
return try ResolveConfiguration(
serializedData: try Data(
contentsOf: self.bundle.url(
forResource: "resolveconfiguration",
withExtension: "bnk"
)!
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import SwiftUI

extension EeveeSettingsView {

@ViewBuilder func PremiumSection() -> some View {
@ViewBuilder func PremiumSections() -> some View {

Section(footer: patchType == .disabled ? nil : Text("""
You can select the Premium patching method you prefer. App restart is required after changing.
Expand All @@ -17,7 +17,7 @@ If you have an active Premium subscription, you can turn on Do Not Patch Premium
"Do Not Patch Premium",
isOn: Binding<Bool>(
get: { patchType == .disabled },
set: { patchType = $0 ? .disabled : .offlineBnk }
set: { patchType = $0 ? .disabled : .requests }
)
)

Expand All @@ -31,5 +31,16 @@ If you have an active Premium subscription, you can turn on Do Not Patch Premium
}
}
}

if patchType == .requests {
Section(
footer: Text("Replace remote configuration with the dumped Premium one. It might fix some issues, such as appearing ads, but it's not guaranteed.")
) {
Toggle(
"Overwrite Configuration",
isOn: $overwriteConfiguration
)
}
}
}
}
62 changes: 45 additions & 17 deletions Sources/EeveeSpotify/Settings/Views/EeveeSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ struct EeveeSettingsView: View {
@State var musixmatchToken = UserDefaults.musixmatchToken
@State var patchType = UserDefaults.patchType
@State var lyricsSource = UserDefaults.lyricsSource
@State var overwriteConfiguration = UserDefaults.overwriteConfiguration

private func getMusixmatchToken(_ input: String) -> String? {

if let match = input.firstMatch("\\[UserToken\\]: ([a-f0-9]+)"),
let tokenRange = Range(match.range(at: 1), in: input) {
return String(input[tokenRange])
}
else if input ~= "^[a-f0-9]+$" {
return input
}

return nil
}

private func showMusixmatchTokenAlert(_ oldSource: LyricsSource) {

Expand All @@ -25,16 +39,8 @@ struct EeveeSettingsView: View {

alert.addAction(UIAlertAction(title: "OK", style: .default) { _ in
let text = alert.textFields!.first!.text!
let token: String

if let match = text.firstMatch("\\[UserToken\\]: ([a-f0-9]+)"),
let tokenRange = Range(match.range(at: 1), in: text) {
token = String(text[tokenRange])
}
else if text ~= "^[a-f0-9]+$" {
token = text
}
else {

guard let token = getMusixmatchToken(text) else {
lyricsSource = oldSource
return
}
Expand All @@ -50,7 +56,7 @@ struct EeveeSettingsView: View {

List {

PremiumSection()
PremiumSections()

LyricsSections()

Expand All @@ -73,14 +79,26 @@ struct EeveeSettingsView: View {
}
}
}

.padding(.bottom, 45)

.listStyle(GroupedListStyle())

.padding(.bottom, 60)
.ignoresSafeArea(.keyboard)

.animation(.default, value: lyricsSource)
.animation(.default, value: patchType)

.onChange(of: musixmatchToken) { token in
UserDefaults.musixmatchToken = token
.onChange(of: musixmatchToken) { input in

if input.isEmpty { return }

if let token = getMusixmatchToken(input) {
UserDefaults.musixmatchToken = token
self.musixmatchToken = token
}
else {
self.musixmatchToken = ""
}
}

.onChange(of: lyricsSource) { [lyricsSource] newSource in
Expand All @@ -104,8 +122,18 @@ struct EeveeSettingsView: View {
NSLog("Unable to reset offline.bnk: \(error)")
}
}

.listStyle(GroupedListStyle())

.onChange(of: overwriteConfiguration) { overwriteConfiguration in

UserDefaults.overwriteConfiguration = overwriteConfiguration

do {
try OfflineHelper.resetOfflineBnk()
}
catch {
NSLog("Unable to reset offline.bnk: \(error)")
}
}

.onAppear {
UIView.appearance(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ If the tweak is unable to find a song or process the lyrics, you'll see a "Could

Text("Musixmatch User Token")

TextField("Enter User Token", text: $musixmatchToken)
TextField("Enter User Token or Paste Debug Info", text: $musixmatchToken)
.foregroundColor(.gray)
}
.frame(maxWidth: .infinity, alignment: .leading)
Expand Down
Binary file not shown.

0 comments on commit 3c5509e

Please sign in to comment.