mirror of
https://github.com/whoeevee/EeveeSpotifyReborn.git
synced 2026-01-08 23:23:20 +00:00
premium plan info and improvements
This commit is contained in:
@@ -6,11 +6,17 @@ class SPTDataLoaderServiceHook: ClassHook<NSObject>, SpotifySessionDelegate {
|
||||
|
||||
// orion:new
|
||||
func shouldModify(_ url: URL) -> Bool {
|
||||
let isModifyingCustomizeResponse = PremiumPatchingGroup.isActive
|
||||
let isModifyingLyrics = LyricsGroup.isActive
|
||||
let shouldPatchPremium = PremiumPatchingGroup.isActive
|
||||
let shouldReplaceLyrics = LyricsGroup.isActive
|
||||
|
||||
return (url.isLyrics && isModifyingLyrics)
|
||||
|| (url.isCustomize && isModifyingCustomizeResponse)
|
||||
return (shouldReplaceLyrics && url.isLyrics)
|
||||
|| (shouldPatchPremium && (url.isCustomize || url.isPremiumPlanRow || url.isPlanOverview))
|
||||
}
|
||||
|
||||
// orion:new
|
||||
func respondWithCustomData(_ data: Data, task: URLSessionDataTask, session: URLSession) {
|
||||
orig.URLSession(session, dataTask: task, didReceiveData: data)
|
||||
orig.URLSession(session, task: task, didCompleteWithError: nil)
|
||||
}
|
||||
|
||||
func URLSession(
|
||||
@@ -18,58 +24,65 @@ class SPTDataLoaderServiceHook: ClassHook<NSObject>, SpotifySessionDelegate {
|
||||
task: URLSessionDataTask,
|
||||
didCompleteWithError error: Error?
|
||||
) {
|
||||
guard
|
||||
let request = task.currentRequest,
|
||||
let url = request.url
|
||||
else {
|
||||
guard let url = task.currentRequest?.url else {
|
||||
return
|
||||
}
|
||||
|
||||
if error == nil,
|
||||
shouldModify(url),
|
||||
let buffer = URLSessionHelper.shared.obtainData(for: url)
|
||||
{
|
||||
if url.isLyrics {
|
||||
do {
|
||||
orig.URLSession(
|
||||
session,
|
||||
dataTask: task,
|
||||
didReceiveData: try getLyricsDataForCurrentTrack(
|
||||
guard error == nil, shouldModify(url) else {
|
||||
orig.URLSession(session, task: task, didCompleteWithError: error)
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
if let buffer = URLSessionHelper.shared.obtainData(for: url) {
|
||||
if url.isLyrics {
|
||||
respondWithCustomData(
|
||||
try getLyricsDataForCurrentTrack(
|
||||
originalLyrics: try? Lyrics(serializedBytes: buffer)
|
||||
)
|
||||
),
|
||||
task: task,
|
||||
session: session
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if url.isPremiumPlanRow {
|
||||
respondWithCustomData(
|
||||
try getPremiumPlanRowData(
|
||||
originalPremiumPlanRow: try PremiumPlanRow(serializedBytes: buffer)
|
||||
),
|
||||
task: task,
|
||||
session: session
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var customizeMessage = try CustomizeMessage(serializedBytes: buffer)
|
||||
modifyRemoteConfiguration(&customizeMessage.response)
|
||||
|
||||
respondWithCustomData(try customizeMessage.serializedData(), task: task, session: session)
|
||||
return
|
||||
}
|
||||
|
||||
if url.isPlanOverview {
|
||||
do {
|
||||
orig.URLSession(session, dataTask: task, didReceiveData: try getPlanOverviewData())
|
||||
orig.URLSession(session, task: task, didCompleteWithError: nil)
|
||||
}
|
||||
catch {
|
||||
orig.URLSession(session, task: task, didCompleteWithError: error)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
var customizeMessage = try CustomizeMessage(serializedBytes: buffer)
|
||||
modifyRemoteConfiguration(&customizeMessage.response)
|
||||
|
||||
orig.URLSession(
|
||||
session,
|
||||
dataTask: task,
|
||||
didReceiveData: try customizeMessage.serializedBytes()
|
||||
)
|
||||
|
||||
orig.URLSession(session, task: task, didCompleteWithError: nil)
|
||||
|
||||
NSLog("[EeveeSpotify] Modified customize data")
|
||||
return
|
||||
}
|
||||
catch {
|
||||
NSLog("[EeveeSpotify] Unable to modify customize data: \(error)")
|
||||
}
|
||||
}
|
||||
catch {
|
||||
orig.URLSession(session, task: task, didCompleteWithError: error)
|
||||
}
|
||||
|
||||
orig.URLSession(session, task: task, didCompleteWithError: error)
|
||||
|
||||
}
|
||||
|
||||
func URLSession(
|
||||
@@ -79,47 +92,23 @@ class SPTDataLoaderServiceHook: ClassHook<NSObject>, SpotifySessionDelegate {
|
||||
completionHandler handler: @escaping (URLSession.ResponseDisposition) -> Void
|
||||
) {
|
||||
guard
|
||||
let request = task.currentRequest,
|
||||
let url = request.url
|
||||
let url = task.currentRequest?.url,
|
||||
url.isLyrics,
|
||||
response.statusCode != 200
|
||||
else {
|
||||
orig.URLSession(session, dataTask: task, didReceiveResponse: response, completionHandler: handler)
|
||||
return
|
||||
}
|
||||
|
||||
if shouldModify(url), url.isLyrics, response.statusCode != 200 {
|
||||
let okResponse = HTTPURLResponse(
|
||||
url: url,
|
||||
statusCode: 200,
|
||||
httpVersion: "2.0",
|
||||
headerFields: [:]
|
||||
)!
|
||||
|
||||
do {
|
||||
let data = try getLyricsDataForCurrentTrack()
|
||||
let okResponse = HTTPURLResponse(url: url, statusCode: 200, httpVersion: "2.0", headerFields: [:])!
|
||||
|
||||
do {
|
||||
let lyricsData = try getLyricsDataForCurrentTrack()
|
||||
|
||||
orig.URLSession(
|
||||
session,
|
||||
dataTask: task,
|
||||
didReceiveResponse: okResponse,
|
||||
completionHandler: handler
|
||||
)
|
||||
|
||||
orig.URLSession(session, dataTask: task, didReceiveData: lyricsData)
|
||||
orig.URLSession(session, task: task, didCompleteWithError: nil)
|
||||
|
||||
return
|
||||
}
|
||||
catch {
|
||||
orig.URLSession(session, task: task, didCompleteWithError: error)
|
||||
return
|
||||
}
|
||||
orig.URLSession(session, dataTask: task, didReceiveResponse: okResponse, completionHandler: handler)
|
||||
respondWithCustomData(data, task: task, session: session)
|
||||
} catch {
|
||||
orig.URLSession(session, task: task, didCompleteWithError: error)
|
||||
}
|
||||
|
||||
orig.URLSession(
|
||||
session,
|
||||
dataTask: task,
|
||||
didReceiveResponse: response,
|
||||
completionHandler: handler
|
||||
)
|
||||
}
|
||||
|
||||
func URLSession(
|
||||
@@ -127,10 +116,7 @@ class SPTDataLoaderServiceHook: ClassHook<NSObject>, SpotifySessionDelegate {
|
||||
dataTask task: URLSessionDataTask,
|
||||
didReceiveData data: Data
|
||||
) {
|
||||
guard
|
||||
let request = task.currentRequest,
|
||||
let url = request.url
|
||||
else {
|
||||
guard let url = task.currentRequest?.url else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ import UIKit
|
||||
|
||||
class SPTPlayerTrackHook: ClassHook<NSObject> {
|
||||
typealias Group = LyricsGroup
|
||||
static let targetName = "SPTPlayerTrack"
|
||||
static let targetName = EeveeSpotify.hookTarget == .latest
|
||||
? "SPTPlayerTrackImplementation"
|
||||
: "SPTPlayerTrack"
|
||||
|
||||
func metadata() -> [String: String] {
|
||||
var meta = orig.metadata()
|
||||
@@ -31,7 +33,7 @@ class NowPlayingScrollViewControllerHook: ClassHook<NSObject> {
|
||||
withDifferentProviders: Bool,
|
||||
scrollEnabledValueChanged: Bool
|
||||
) -> NowPlayingScrollViewController {
|
||||
var controller = orig.nowPlayingScrollViewModelWithDidLoadComponentsFor(
|
||||
let controller = orig.nowPlayingScrollViewModelWithDidLoadComponentsFor(
|
||||
track,
|
||||
withDifferentProviders: withDifferentProviders,
|
||||
scrollEnabledValueChanged: scrollEnabledValueChanged
|
||||
|
||||
@@ -143,7 +143,7 @@ func getLyricsDataForCurrentTrack(originalLyrics: Lyrics? = nil) throws -> Data
|
||||
color = Color(hex: extractedColor)
|
||||
.normalized(lyricsColorsSettings.normalizationFactor)
|
||||
}
|
||||
else if let uiColor = nowPlayingScrollViewController?.backgroundViewController.color() {
|
||||
else if let uiColor = nowPlayingScrollViewController?.backgroundViewModel.color() {
|
||||
color = Color(uiColor)
|
||||
.normalized(lyricsColorsSettings.normalizationFactor)
|
||||
}
|
||||
|
||||
@@ -41,9 +41,15 @@ extension NowPlayingScrollViewController {
|
||||
|
||||
//
|
||||
|
||||
var backgroundViewController: SPTNowPlayingBackgroundViewController {
|
||||
private var backgroundViewController: NSObject {
|
||||
get {
|
||||
Ivars<SPTNowPlayingBackgroundViewController>(self).backgroundViewController
|
||||
Ivars<NSObject>(self).backgroundViewController
|
||||
}
|
||||
}
|
||||
|
||||
var backgroundViewModel: SPTNowPlayingBackgroundViewModel {
|
||||
get {
|
||||
Ivars<SPTNowPlayingBackgroundViewModel>(self.backgroundViewController).viewModel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import UIKit
|
||||
|
||||
@objc protocol SPTNowPlayingBackgroundViewController {
|
||||
func color() -> UIColor
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import UIKit
|
||||
|
||||
@objc protocol SPTNowPlayingBackgroundViewModel {
|
||||
func color() -> UIColor
|
||||
}
|
||||
@@ -9,79 +9,103 @@ func modifyRemoteConfiguration(_ configuration: inout UcsResponse) {
|
||||
}
|
||||
|
||||
func modifyAttributes(_ attributes: inout [String: AccountAttribute]) {
|
||||
attributes["type"] = AccountAttribute.with {
|
||||
$0.stringValue = "premium"
|
||||
}
|
||||
attributes["player-license"] = AccountAttribute.with {
|
||||
$0.stringValue = "premium"
|
||||
}
|
||||
attributes["financial-product"] = AccountAttribute.with {
|
||||
$0.stringValue = "pr:premium,tc:0"
|
||||
}
|
||||
attributes["name"] = AccountAttribute.with {
|
||||
$0.stringValue = "Spotify Premium"
|
||||
}
|
||||
attributes["payments-initial-campaign"] = AccountAttribute.with {
|
||||
$0.stringValue = "default"
|
||||
}
|
||||
let oneYearFromNow = Calendar.current.date(byAdding: .year, value: 1, to: Date())!
|
||||
|
||||
//
|
||||
|
||||
attributes["unrestricted"] = AccountAttribute.with {
|
||||
$0.boolValue = true
|
||||
}
|
||||
attributes["catalogue"] = AccountAttribute.with {
|
||||
$0.stringValue = "premium"
|
||||
}
|
||||
attributes["streaming-rules"] = AccountAttribute.with {
|
||||
$0.stringValue = ""
|
||||
}
|
||||
attributes["pause-after"] = AccountAttribute.with {
|
||||
$0.longValue = 0
|
||||
}
|
||||
attributes["on-demand"] = AccountAttribute.with {
|
||||
$0.boolValue = true
|
||||
}
|
||||
|
||||
//
|
||||
let formatter = ISO8601DateFormatter()
|
||||
formatter.timeZone = TimeZone(abbreviation: "UTC")
|
||||
|
||||
attributes["ads"] = AccountAttribute.with {
|
||||
$0.boolValue = false
|
||||
}
|
||||
|
||||
attributes.removeValue(forKey: "ad-use-adlogic")
|
||||
attributes.removeValue(forKey: "ad-catalogues")
|
||||
|
||||
//
|
||||
|
||||
attributes["shuffle-eligible"] = AccountAttribute.with {
|
||||
$0.boolValue = true
|
||||
}
|
||||
attributes["high-bitrate"] = AccountAttribute.with {
|
||||
$0.boolValue = true
|
||||
}
|
||||
attributes["offline"] = AccountAttribute.with {
|
||||
$0.boolValue = true // allow downloading
|
||||
}
|
||||
attributes["nft-disabled"] = AccountAttribute.with {
|
||||
attributes["audio-quality"] = AccountAttribute.with {
|
||||
$0.stringValue = "1"
|
||||
}
|
||||
|
||||
attributes["can_use_superbird"] = AccountAttribute.with {
|
||||
$0.boolValue = true
|
||||
}
|
||||
|
||||
attributes["catalogue"] = AccountAttribute.with {
|
||||
$0.stringValue = "premium"
|
||||
}
|
||||
|
||||
attributes["financial-product"] = AccountAttribute.with {
|
||||
$0.stringValue = "pr:premium,tc:0"
|
||||
}
|
||||
|
||||
attributes["high-bitrate"] = AccountAttribute.with {
|
||||
$0.boolValue = true
|
||||
}
|
||||
|
||||
attributes["is-eligible-premium-unboxing"] = AccountAttribute.with {
|
||||
$0.boolValue = true
|
||||
}
|
||||
|
||||
attributes["name"] = AccountAttribute.with {
|
||||
$0.stringValue = "Spotify Premium"
|
||||
}
|
||||
|
||||
attributes["nft-disabled"] = AccountAttribute.with {
|
||||
$0.stringValue = "1"
|
||||
}
|
||||
|
||||
attributes["offline"] = AccountAttribute.with {
|
||||
$0.boolValue = true // allow downloading
|
||||
}
|
||||
|
||||
attributes["on-demand"] = AccountAttribute.with {
|
||||
$0.boolValue = true
|
||||
}
|
||||
|
||||
attributes["payments-initial-campaign"] = AccountAttribute.with {
|
||||
$0.stringValue = "default"
|
||||
}
|
||||
|
||||
attributes["player-license"] = AccountAttribute.with {
|
||||
$0.stringValue = "premium"
|
||||
}
|
||||
|
||||
attributes["player-license-v2"] = AccountAttribute.with {
|
||||
$0.stringValue = "premium"
|
||||
}
|
||||
|
||||
attributes["product-expiry"] = AccountAttribute.with {
|
||||
$0.stringValue = formatter.string(from: oneYearFromNow)
|
||||
}
|
||||
|
||||
attributes["public-toplist"] = AccountAttribute.with {
|
||||
$0.stringValue = "1"
|
||||
}
|
||||
|
||||
attributes["shuffle-eligible"] = AccountAttribute.with {
|
||||
$0.boolValue = true
|
||||
}
|
||||
|
||||
attributes["social-session"] = AccountAttribute.with {
|
||||
$0.boolValue = true
|
||||
}
|
||||
|
||||
attributes["social-session-free-tier"] = AccountAttribute.with {
|
||||
$0.boolValue = false
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
attributes["com.spotify.madprops.delivered.by.ucs"] = AccountAttribute.with {
|
||||
$0.boolValue = true
|
||||
}
|
||||
attributes["com.spotify.madprops.use.ucs.product.state"] = AccountAttribute.with {
|
||||
|
||||
attributes["streaming-rules"] = AccountAttribute.with {
|
||||
$0.stringValue = ""
|
||||
}
|
||||
|
||||
attributes["subscription-enddate"] = AccountAttribute.with {
|
||||
$0.stringValue = formatter.string(from: oneYearFromNow)
|
||||
}
|
||||
|
||||
attributes["type"] = AccountAttribute.with {
|
||||
$0.stringValue = "premium"
|
||||
}
|
||||
|
||||
attributes["unrestricted"] = AccountAttribute.with {
|
||||
$0.boolValue = true
|
||||
}
|
||||
|
||||
attributes.removeValue(forKey: "payment-state")
|
||||
attributes.removeValue(forKey: "last-premium-activation-date")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import Foundation
|
||||
|
||||
func getPremiumPlanRowData(originalPremiumPlanRow: PremiumPlanRow) throws -> Data {
|
||||
var premiumPlanRow = originalPremiumPlanRow
|
||||
|
||||
premiumPlanRow.planName = "EeveeSpotify"
|
||||
premiumPlanRow.planIdentifier = "Eevee"
|
||||
premiumPlanRow.colorCode = "#FFD2D7"
|
||||
|
||||
return try premiumPlanRow.serializedData()
|
||||
}
|
||||
|
||||
func getPlanOverviewData() throws -> Data {
|
||||
let plan = SpotifyPlan.with {
|
||||
$0.notice = SpotifyPlan.Notice.with {
|
||||
$0.message = "payment_notice".localized
|
||||
$0.status = 2 // 0 - trial, 1 - prepaid, 2 - subsription
|
||||
}
|
||||
$0.subscription = SpotifyPlan.SubscriptionInfo.with {
|
||||
$0.planVariant = 2
|
||||
$0.planName = "EeveeSpotify"
|
||||
$0.planCategory = "Eevee"
|
||||
$0.colorCode = "#FFD2D7"
|
||||
$0.features = [
|
||||
SpotifyPlan.Feature.with {
|
||||
$0.color = "#1ED760"
|
||||
$0.description_p = "ad_free_music_listening".localized
|
||||
$0.icon = SpotifyPlan.IconType.check
|
||||
},
|
||||
SpotifyPlan.Feature.with {
|
||||
$0.color = "#1ED760"
|
||||
$0.description_p = "play_songs_in_any_order".localized
|
||||
$0.icon = SpotifyPlan.IconType.check
|
||||
},
|
||||
SpotifyPlan.Feature.with {
|
||||
$0.color = "#1ED760"
|
||||
$0.description_p = "organize_listening_queue".localized
|
||||
$0.icon = SpotifyPlan.IconType.check
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
return try plan.serializedData()
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import Foundation
|
||||
|
||||
extension BootstrapMessage {
|
||||
|
||||
var ucsResponse: UcsResponse {
|
||||
get {
|
||||
self.wrapper.oneMoreWrapper.message.response
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import Foundation
|
||||
|
||||
extension UcsResponse {
|
||||
|
||||
var assignedValues: [AssignedValue] {
|
||||
get {
|
||||
self.resolve.configuration.assignedValues
|
||||
|
||||
132
Sources/EeveeSpotify/Premium/Models/PremiumPlanRow.pb.swift
Normal file
132
Sources/EeveeSpotify/Premium/Models/PremiumPlanRow.pb.swift
Normal file
@@ -0,0 +1,132 @@
|
||||
// DO NOT EDIT.
|
||||
// swift-format-ignore-file
|
||||
// swiftlint:disable all
|
||||
//
|
||||
// Generated by the Swift generator plugin for the protocol buffer compiler.
|
||||
// Source: pam.proto
|
||||
//
|
||||
// For information on using the generated types, please see the documentation:
|
||||
// https://github.com/apple/swift-protobuf/
|
||||
|
||||
import SwiftProtobuf
|
||||
|
||||
// If the compiler emits an error on this type, it is because this file
|
||||
// was generated by a version of the `protoc` Swift plug-in that is
|
||||
// incompatible with the version of SwiftProtobuf to which you are linking.
|
||||
// Please ensure that you are building against the same version of the API
|
||||
// that was used to generate this file.
|
||||
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
|
||||
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
|
||||
typealias Version = _2
|
||||
}
|
||||
|
||||
/// Message emitted by pam-view-service
|
||||
/// GET https://spclient.wg.spotify.com/pam-view-service/v1/GetPremiumPlanRow
|
||||
struct PremiumPlanRow: Sendable {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var planName: String = String()
|
||||
var colorCode: String = String()
|
||||
var planTypeID: Int32 = 0
|
||||
var billingLabel: String = String()
|
||||
var actionText: String = String()
|
||||
var flag: Int32 = 0
|
||||
var availabilityMessage: String = String()
|
||||
var durationText: String = String()
|
||||
var planCategory: Int32 = 0
|
||||
var planIdentifier: String = String()
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
}
|
||||
|
||||
// MARK: - Code below here is support for the SwiftProtobuf runtime.
|
||||
|
||||
extension PremiumPlanRow: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = "PremiumPlanRow"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
3: .standard(proto: "plan_name"),
|
||||
4: .standard(proto: "color_code"),
|
||||
6: .standard(proto: "plan_type_id"),
|
||||
8: .standard(proto: "billing_label"),
|
||||
9: .standard(proto: "action_text"),
|
||||
10: .same(proto: "flag"),
|
||||
12: .standard(proto: "availability_message"),
|
||||
14: .standard(proto: "duration_text"),
|
||||
16: .standard(proto: "plan_category"),
|
||||
18: .standard(proto: "plan_identifier"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 3: try { try decoder.decodeSingularStringField(value: &self.planName) }()
|
||||
case 4: try { try decoder.decodeSingularStringField(value: &self.colorCode) }()
|
||||
case 6: try { try decoder.decodeSingularInt32Field(value: &self.planTypeID) }()
|
||||
case 8: try { try decoder.decodeSingularStringField(value: &self.billingLabel) }()
|
||||
case 9: try { try decoder.decodeSingularStringField(value: &self.actionText) }()
|
||||
case 10: try { try decoder.decodeSingularInt32Field(value: &self.flag) }()
|
||||
case 12: try { try decoder.decodeSingularStringField(value: &self.availabilityMessage) }()
|
||||
case 14: try { try decoder.decodeSingularStringField(value: &self.durationText) }()
|
||||
case 16: try { try decoder.decodeSingularInt32Field(value: &self.planCategory) }()
|
||||
case 18: try { try decoder.decodeSingularStringField(value: &self.planIdentifier) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if !self.planName.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.planName, fieldNumber: 3)
|
||||
}
|
||||
if !self.colorCode.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.colorCode, fieldNumber: 4)
|
||||
}
|
||||
if self.planTypeID != 0 {
|
||||
try visitor.visitSingularInt32Field(value: self.planTypeID, fieldNumber: 6)
|
||||
}
|
||||
if !self.billingLabel.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.billingLabel, fieldNumber: 8)
|
||||
}
|
||||
if !self.actionText.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.actionText, fieldNumber: 9)
|
||||
}
|
||||
if self.flag != 0 {
|
||||
try visitor.visitSingularInt32Field(value: self.flag, fieldNumber: 10)
|
||||
}
|
||||
if !self.availabilityMessage.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.availabilityMessage, fieldNumber: 12)
|
||||
}
|
||||
if !self.durationText.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.durationText, fieldNumber: 14)
|
||||
}
|
||||
if self.planCategory != 0 {
|
||||
try visitor.visitSingularInt32Field(value: self.planCategory, fieldNumber: 16)
|
||||
}
|
||||
if !self.planIdentifier.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.planIdentifier, fieldNumber: 18)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: PremiumPlanRow, rhs: PremiumPlanRow) -> Bool {
|
||||
if lhs.planName != rhs.planName {return false}
|
||||
if lhs.colorCode != rhs.colorCode {return false}
|
||||
if lhs.planTypeID != rhs.planTypeID {return false}
|
||||
if lhs.billingLabel != rhs.billingLabel {return false}
|
||||
if lhs.actionText != rhs.actionText {return false}
|
||||
if lhs.flag != rhs.flag {return false}
|
||||
if lhs.availabilityMessage != rhs.availabilityMessage {return false}
|
||||
if lhs.durationText != rhs.durationText {return false}
|
||||
if lhs.planCategory != rhs.planCategory {return false}
|
||||
if lhs.planIdentifier != rhs.planIdentifier {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
567
Sources/EeveeSpotify/Premium/Models/SpotifyPlan.pb.swift
Normal file
567
Sources/EeveeSpotify/Premium/Models/SpotifyPlan.pb.swift
Normal file
@@ -0,0 +1,567 @@
|
||||
// DO NOT EDIT.
|
||||
// swift-format-ignore-file
|
||||
// swiftlint:disable all
|
||||
//
|
||||
// Generated by the Swift generator plugin for the protocol buffer compiler.
|
||||
// Source: SpotifyPlan.proto
|
||||
//
|
||||
// For information on using the generated types, please see the documentation:
|
||||
// https://github.com/apple/swift-protobuf/
|
||||
|
||||
import SwiftProtobuf
|
||||
|
||||
// If the compiler emits an error on this type, it is because this file
|
||||
// was generated by a version of the `protoc` Swift plug-in that is
|
||||
// incompatible with the version of SwiftProtobuf to which you are linking.
|
||||
// Please ensure that you are building against the same version of the API
|
||||
// that was used to generate this file.
|
||||
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
|
||||
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
|
||||
typealias Version = _2
|
||||
}
|
||||
|
||||
struct SpotifyPlan: Sendable {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var subscription: SpotifyPlan.SubscriptionInfo {
|
||||
get {return _subscription ?? SpotifyPlan.SubscriptionInfo()}
|
||||
set {_subscription = newValue}
|
||||
}
|
||||
/// Returns true if `subscription` has been explicitly set.
|
||||
var hasSubscription: Bool {return self._subscription != nil}
|
||||
/// Clears the value of `subscription`. Subsequent reads from it will return its default value.
|
||||
mutating func clearSubscription() {self._subscription = nil}
|
||||
|
||||
var notice: SpotifyPlan.Notice {
|
||||
get {return _notice ?? SpotifyPlan.Notice()}
|
||||
set {_notice = newValue}
|
||||
}
|
||||
/// Returns true if `notice` has been explicitly set.
|
||||
var hasNotice: Bool {return self._notice != nil}
|
||||
/// Clears the value of `notice`. Subsequent reads from it will return its default value.
|
||||
mutating func clearNotice() {self._notice = nil}
|
||||
|
||||
var actions: [SpotifyPlan.Action] = []
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
enum IconType: SwiftProtobuf.Enum, Swift.CaseIterable {
|
||||
typealias RawValue = Int
|
||||
case unspecifiedIcon // = 0
|
||||
case check // = 1
|
||||
case chevron // = 2
|
||||
case ads // = 3
|
||||
case offline // = 4
|
||||
case arrow // = 5
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
self = .unspecifiedIcon
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .unspecifiedIcon
|
||||
case 1: self = .check
|
||||
case 2: self = .chevron
|
||||
case 3: self = .ads
|
||||
case 4: self = .offline
|
||||
case 5: self = .arrow
|
||||
default: self = .UNRECOGNIZED(rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .unspecifiedIcon: return 0
|
||||
case .check: return 1
|
||||
case .chevron: return 2
|
||||
case .ads: return 3
|
||||
case .offline: return 4
|
||||
case .arrow: return 5
|
||||
case .UNRECOGNIZED(let i): return i
|
||||
}
|
||||
}
|
||||
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static let allCases: [SpotifyPlan.IconType] = [
|
||||
.unspecifiedIcon,
|
||||
.check,
|
||||
.chevron,
|
||||
.ads,
|
||||
.offline,
|
||||
.arrow,
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
struct SubscriptionInfo: Sendable {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var planType: Int32 = 0
|
||||
|
||||
var planVariant: Int32 = 0
|
||||
|
||||
var planName: String = String()
|
||||
|
||||
var planCategory: String = String()
|
||||
|
||||
var colorCode: String = String()
|
||||
|
||||
var backgroundImageURL: String = String()
|
||||
|
||||
var features: [SpotifyPlan.Feature] = []
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
}
|
||||
|
||||
struct Feature: Sendable {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var icon: SpotifyPlan.IconType = .unspecifiedIcon
|
||||
|
||||
var description_p: String = String()
|
||||
|
||||
var color: String = String()
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
}
|
||||
|
||||
struct Notice: Sendable {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var message: String = String()
|
||||
|
||||
var timestamp: Int64 = 0
|
||||
|
||||
var status: Int32 = 0
|
||||
|
||||
var settings: SpotifyPlan.Settings {
|
||||
get {return _settings ?? SpotifyPlan.Settings()}
|
||||
set {_settings = newValue}
|
||||
}
|
||||
/// Returns true if `settings` has been explicitly set.
|
||||
var hasSettings: Bool {return self._settings != nil}
|
||||
/// Clears the value of `settings`. Subsequent reads from it will return its default value.
|
||||
mutating func clearSettings() {self._settings = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _settings: SpotifyPlan.Settings? = nil
|
||||
}
|
||||
|
||||
struct Settings: Sendable {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var autoRenew: Int32 = 0
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
}
|
||||
|
||||
struct Action: Sendable {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var actionID: Int32 = 0
|
||||
|
||||
var details: SpotifyPlan.ActionDetails {
|
||||
get {return _details ?? SpotifyPlan.ActionDetails()}
|
||||
set {_details = newValue}
|
||||
}
|
||||
/// Returns true if `details` has been explicitly set.
|
||||
var hasDetails: Bool {return self._details != nil}
|
||||
/// Clears the value of `details`. Subsequent reads from it will return its default value.
|
||||
mutating func clearDetails() {self._details = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _details: SpotifyPlan.ActionDetails? = nil
|
||||
}
|
||||
|
||||
struct ActionDetails: Sendable {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var title: String = String()
|
||||
|
||||
var subtitle: String = String()
|
||||
|
||||
var url: String = String()
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
}
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _subscription: SpotifyPlan.SubscriptionInfo? = nil
|
||||
fileprivate var _notice: SpotifyPlan.Notice? = nil
|
||||
}
|
||||
|
||||
// MARK: - Code below here is support for the SwiftProtobuf runtime.
|
||||
|
||||
extension SpotifyPlan: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = "SpotifyPlan"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "subscription"),
|
||||
2: .same(proto: "notice"),
|
||||
3: .same(proto: "actions"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularMessageField(value: &self._subscription) }()
|
||||
case 2: try { try decoder.decodeSingularMessageField(value: &self._notice) }()
|
||||
case 3: try { try decoder.decodeRepeatedMessageField(value: &self.actions) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._subscription {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._notice {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
if !self.actions.isEmpty {
|
||||
try visitor.visitRepeatedMessageField(value: self.actions, fieldNumber: 3)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: SpotifyPlan, rhs: SpotifyPlan) -> Bool {
|
||||
if lhs._subscription != rhs._subscription {return false}
|
||||
if lhs._notice != rhs._notice {return false}
|
||||
if lhs.actions != rhs.actions {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension SpotifyPlan.IconType: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "UNSPECIFIED_ICON"),
|
||||
1: .same(proto: "CHECK"),
|
||||
2: .same(proto: "CHEVRON"),
|
||||
3: .same(proto: "ADS"),
|
||||
4: .same(proto: "OFFLINE"),
|
||||
5: .same(proto: "ARROW"),
|
||||
]
|
||||
}
|
||||
|
||||
extension SpotifyPlan.SubscriptionInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = SpotifyPlan.protoMessageName + ".SubscriptionInfo"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "plan_type"),
|
||||
2: .standard(proto: "plan_variant"),
|
||||
3: .standard(proto: "plan_name"),
|
||||
4: .standard(proto: "plan_category"),
|
||||
5: .standard(proto: "color_code"),
|
||||
19: .standard(proto: "background_image_url"),
|
||||
20: .same(proto: "features"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularInt32Field(value: &self.planType) }()
|
||||
case 2: try { try decoder.decodeSingularInt32Field(value: &self.planVariant) }()
|
||||
case 3: try { try decoder.decodeSingularStringField(value: &self.planName) }()
|
||||
case 4: try { try decoder.decodeSingularStringField(value: &self.planCategory) }()
|
||||
case 5: try { try decoder.decodeSingularStringField(value: &self.colorCode) }()
|
||||
case 19: try { try decoder.decodeSingularStringField(value: &self.backgroundImageURL) }()
|
||||
case 20: try { try decoder.decodeRepeatedMessageField(value: &self.features) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if self.planType != 0 {
|
||||
try visitor.visitSingularInt32Field(value: self.planType, fieldNumber: 1)
|
||||
}
|
||||
if self.planVariant != 0 {
|
||||
try visitor.visitSingularInt32Field(value: self.planVariant, fieldNumber: 2)
|
||||
}
|
||||
if !self.planName.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.planName, fieldNumber: 3)
|
||||
}
|
||||
if !self.planCategory.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.planCategory, fieldNumber: 4)
|
||||
}
|
||||
if !self.colorCode.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.colorCode, fieldNumber: 5)
|
||||
}
|
||||
if !self.backgroundImageURL.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.backgroundImageURL, fieldNumber: 19)
|
||||
}
|
||||
if !self.features.isEmpty {
|
||||
try visitor.visitRepeatedMessageField(value: self.features, fieldNumber: 20)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: SpotifyPlan.SubscriptionInfo, rhs: SpotifyPlan.SubscriptionInfo) -> Bool {
|
||||
if lhs.planType != rhs.planType {return false}
|
||||
if lhs.planVariant != rhs.planVariant {return false}
|
||||
if lhs.planName != rhs.planName {return false}
|
||||
if lhs.planCategory != rhs.planCategory {return false}
|
||||
if lhs.colorCode != rhs.colorCode {return false}
|
||||
if lhs.backgroundImageURL != rhs.backgroundImageURL {return false}
|
||||
if lhs.features != rhs.features {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension SpotifyPlan.Feature: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = SpotifyPlan.protoMessageName + ".Feature"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "icon"),
|
||||
2: .same(proto: "description"),
|
||||
4: .same(proto: "color"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularEnumField(value: &self.icon) }()
|
||||
case 2: try { try decoder.decodeSingularStringField(value: &self.description_p) }()
|
||||
case 4: try { try decoder.decodeSingularStringField(value: &self.color) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if self.icon != .unspecifiedIcon {
|
||||
try visitor.visitSingularEnumField(value: self.icon, fieldNumber: 1)
|
||||
}
|
||||
if !self.description_p.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.description_p, fieldNumber: 2)
|
||||
}
|
||||
if !self.color.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.color, fieldNumber: 4)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: SpotifyPlan.Feature, rhs: SpotifyPlan.Feature) -> Bool {
|
||||
if lhs.icon != rhs.icon {return false}
|
||||
if lhs.description_p != rhs.description_p {return false}
|
||||
if lhs.color != rhs.color {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension SpotifyPlan.Notice: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = SpotifyPlan.protoMessageName + ".Notice"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "message"),
|
||||
4: .same(proto: "timestamp"),
|
||||
7: .same(proto: "status"),
|
||||
8: .same(proto: "settings"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularStringField(value: &self.message) }()
|
||||
case 4: try { try decoder.decodeSingularInt64Field(value: &self.timestamp) }()
|
||||
case 7: try { try decoder.decodeSingularInt32Field(value: &self.status) }()
|
||||
case 8: try { try decoder.decodeSingularMessageField(value: &self._settings) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
if !self.message.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.message, fieldNumber: 1)
|
||||
}
|
||||
if self.timestamp != 0 {
|
||||
try visitor.visitSingularInt64Field(value: self.timestamp, fieldNumber: 4)
|
||||
}
|
||||
if self.status != 0 {
|
||||
try visitor.visitSingularInt32Field(value: self.status, fieldNumber: 7)
|
||||
}
|
||||
try { if let v = self._settings {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 8)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: SpotifyPlan.Notice, rhs: SpotifyPlan.Notice) -> Bool {
|
||||
if lhs.message != rhs.message {return false}
|
||||
if lhs.timestamp != rhs.timestamp {return false}
|
||||
if lhs.status != rhs.status {return false}
|
||||
if lhs._settings != rhs._settings {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension SpotifyPlan.Settings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = SpotifyPlan.protoMessageName + ".Settings"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
2: .standard(proto: "auto_renew"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 2: try { try decoder.decodeSingularInt32Field(value: &self.autoRenew) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if self.autoRenew != 0 {
|
||||
try visitor.visitSingularInt32Field(value: self.autoRenew, fieldNumber: 2)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: SpotifyPlan.Settings, rhs: SpotifyPlan.Settings) -> Bool {
|
||||
if lhs.autoRenew != rhs.autoRenew {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension SpotifyPlan.Action: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = SpotifyPlan.protoMessageName + ".Action"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "action_id"),
|
||||
2: .same(proto: "details"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularInt32Field(value: &self.actionID) }()
|
||||
case 2: try { try decoder.decodeSingularMessageField(value: &self._details) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
if self.actionID != 0 {
|
||||
try visitor.visitSingularInt32Field(value: self.actionID, fieldNumber: 1)
|
||||
}
|
||||
try { if let v = self._details {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: SpotifyPlan.Action, rhs: SpotifyPlan.Action) -> Bool {
|
||||
if lhs.actionID != rhs.actionID {return false}
|
||||
if lhs._details != rhs._details {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension SpotifyPlan.ActionDetails: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = SpotifyPlan.protoMessageName + ".ActionDetails"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "title"),
|
||||
2: .same(proto: "subtitle"),
|
||||
3: .same(proto: "url"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularStringField(value: &self.title) }()
|
||||
case 2: try { try decoder.decodeSingularStringField(value: &self.subtitle) }()
|
||||
case 3: try { try decoder.decodeSingularStringField(value: &self.url) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if !self.title.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.title, fieldNumber: 1)
|
||||
}
|
||||
if !self.subtitle.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.subtitle, fieldNumber: 2)
|
||||
}
|
||||
if !self.url.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.url, fieldNumber: 3)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: SpotifyPlan.ActionDetails, rhs: SpotifyPlan.ActionDetails) -> Bool {
|
||||
if lhs.title != rhs.title {return false}
|
||||
if lhs.subtitle != rhs.subtitle {return false}
|
||||
if lhs.url != rhs.url {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,14 @@ extension URL {
|
||||
var isLyrics: Bool {
|
||||
self.path.contains("color-lyrics/v2")
|
||||
}
|
||||
|
||||
var isPlanOverview: Bool {
|
||||
self.path.contains("GetPlanOverview")
|
||||
}
|
||||
|
||||
var isPremiumPlanRow: Bool {
|
||||
self.path.contains("v1/GetPremiumPlanRow")
|
||||
}
|
||||
|
||||
var isOpenSpotifySafariExtension: Bool {
|
||||
self.host == "eevee"
|
||||
|
||||
@@ -11,7 +11,7 @@ func exitApplication() {
|
||||
struct PremiumPatchingGroup: HookGroup { }
|
||||
|
||||
struct EeveeSpotify: Tweak {
|
||||
static let version = "6.0.2"
|
||||
static let version = "6.1"
|
||||
|
||||
static var hookTarget: VersionHookTarget {
|
||||
let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
|
||||
|
||||
2
control
2
control
@@ -1,6 +1,6 @@
|
||||
Package: com.eevee.spotify
|
||||
Name: EeveeSpotify
|
||||
Version: 6.0.2
|
||||
Version: 6.1
|
||||
Architecture: iphoneos-arm
|
||||
Description: A tweak to get Spotify Premium for free, just like Spotilife
|
||||
Maintainer: Eevee
|
||||
|
||||
@@ -131,3 +131,11 @@ request_anonymous_token = "Request Anonymous Token";
|
||||
request_anonymous_token_description = "Tap “Request Anonymous Token” to request a token from Musixmatch without authorization.";
|
||||
|
||||
lrclib_api = "Server Address";
|
||||
|
||||
// Snapshot of your benefits, should match official spotify loc
|
||||
|
||||
ad_free_music_listening = "Ad-free music listening";
|
||||
play_songs_in_any_order = "Play songs in any order";
|
||||
organize_listening_queue = "Organize listening queue";
|
||||
|
||||
payment_notice = "EeveeSpotify applies patches to unlock certain Premium features. It's free.";
|
||||
|
||||
Binary file not shown.
@@ -129,3 +129,11 @@ request_anonymous_token = "Запросить анонимный токен";
|
||||
request_anonymous_token_description = "Нажмите Запросить анонимный токен, чтобы запросить токен у Musixmatch без авторизации.";
|
||||
|
||||
lrclib_api = "Адрес сервера";
|
||||
|
||||
// Snapshot of your benefits, should match official spotify loc
|
||||
|
||||
ad_free_music_listening = "Музыка без рекламы";
|
||||
play_songs_in_any_order = "Треки в любом порядке";
|
||||
organize_listening_queue = "Добавление треков в очередь";
|
||||
|
||||
payment_notice = "EeveeSpotify применяет патчи, которые активируют некоторые возможности Premium. Это бесплатно.";
|
||||
|
||||
Reference in New Issue
Block a user