Fix - Localization bug in widevine licence request
Fix - Subsciption check for third party subscriptions
This commit is contained in:
parent
9814fefcf6
commit
cd4ceea38a
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -112,7 +113,16 @@ public class CrAuth{
|
||||||
if (responseSubs.IsOk){
|
if (responseSubs.IsOk){
|
||||||
var subsc = Helpers.Deserialize<Subscription>(responseSubs.ResponseContent, crunInstance.SettingsJsonSerializerSettings);
|
var subsc = Helpers.Deserialize<Subscription>(responseSubs.ResponseContent, crunInstance.SettingsJsonSerializerSettings);
|
||||||
crunInstance.Profile.Subscription = subsc;
|
crunInstance.Profile.Subscription = subsc;
|
||||||
|
if ( subsc.SubscriptionProducts is{ Count: 0 } && subsc.ThirdPartySubscriptionProducts is{ Count: > 0 }){
|
||||||
|
var thirdPartySub = subsc.ThirdPartySubscriptionProducts.First();
|
||||||
|
var remaining = thirdPartySub.ExpirationDate - DateTime.UtcNow;
|
||||||
|
crunInstance.Profile.HasPremium = remaining > TimeSpan.Zero;
|
||||||
|
crunInstance.Profile.Subscription.IsActive = remaining > TimeSpan.Zero;
|
||||||
|
crunInstance.Profile.Subscription.NextRenewalDate = thirdPartySub.ExpirationDate;
|
||||||
|
} else{
|
||||||
crunInstance.Profile.HasPremium = subsc.IsActive;
|
crunInstance.Profile.HasPremium = subsc.IsActive;
|
||||||
|
}
|
||||||
|
|
||||||
} else{
|
} else{
|
||||||
crunInstance.Profile.HasPremium = false;
|
crunInstance.Profile.HasPremium = false;
|
||||||
Console.Error.WriteLine("Failed to check premium subscription status");
|
Console.Error.WriteLine("Failed to check premium subscription status");
|
||||||
|
|
|
@ -1030,8 +1030,7 @@ public class Crunchyroll{
|
||||||
var assetId = assetIdRegexMatch.Success ? assetIdRegexMatch.Groups[1].Value : null;
|
var assetId = assetIdRegexMatch.Success ? assetIdRegexMatch.Groups[1].Value : null;
|
||||||
var sessionId = Helpers.GenerateSessionId();
|
var sessionId = Helpers.GenerateSessionId();
|
||||||
|
|
||||||
//TODO change back from error
|
Console.WriteLine("Decryption Needed, attempting to decrypt");
|
||||||
Console.Error.WriteLine("Decryption Needed, attempting to decrypt");
|
|
||||||
|
|
||||||
if (!_widevine.canDecrypt){
|
if (!_widevine.canDecrypt){
|
||||||
dlFailed = true;
|
dlFailed = true;
|
||||||
|
@ -1071,17 +1070,11 @@ public class Crunchyroll{
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO change back from error
|
|
||||||
Console.Error.WriteLine("Request to DRM Authentication successful");
|
|
||||||
DrmAuthData authData = Helpers.Deserialize<DrmAuthData>(decRequestResponse.ResponseContent, SettingsJsonSerializerSettings) ?? new DrmAuthData();
|
DrmAuthData authData = Helpers.Deserialize<DrmAuthData>(decRequestResponse.ResponseContent, SettingsJsonSerializerSettings) ?? new DrmAuthData();
|
||||||
|
|
||||||
//TODO change back from error
|
|
||||||
Console.Error.WriteLine("Deserialized Authentication successful");
|
|
||||||
Dictionary<string, string> authDataDict = new Dictionary<string, string>
|
Dictionary<string, string> authDataDict = new Dictionary<string, string>
|
||||||
{ { "dt-custom-data", authData.CustomData ?? string.Empty },{ "x-dt-auth-token", authData.Token ?? string.Empty } };
|
{ { "dt-custom-data", authData.CustomData ?? string.Empty },{ "x-dt-auth-token", authData.Token ?? string.Empty } };
|
||||||
|
|
||||||
//TODO change back from error
|
|
||||||
Console.Error.WriteLine("Requesting encryption keys");
|
|
||||||
var encryptionKeys = await _widevine.getKeys(chosenVideoSegments.pssh, "https://lic.drmtoday.com/license-proxy-widevine/cenc/", authDataDict);
|
var encryptionKeys = await _widevine.getKeys(chosenVideoSegments.pssh, "https://lic.drmtoday.com/license-proxy-widevine/cenc/", authDataDict);
|
||||||
|
|
||||||
if (encryptionKeys.Count == 0){
|
if (encryptionKeys.Count == 0){
|
||||||
|
@ -1095,22 +1088,23 @@ public class Crunchyroll{
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO change back from error
|
|
||||||
Console.Error.WriteLine("Requested encryption keys successful");
|
|
||||||
|
|
||||||
if (Path.Exists(CfgManager.PathMP4Decrypt)){
|
if (Path.Exists(CfgManager.PathMP4Decrypt)){
|
||||||
//TODO change back from error
|
|
||||||
Console.Error.WriteLine("Building command");
|
|
||||||
var keyId = BitConverter.ToString(encryptionKeys[0].KeyID).Replace("-", "").ToLower();
|
var keyId = BitConverter.ToString(encryptionKeys[0].KeyID).Replace("-", "").ToLower();
|
||||||
var key = BitConverter.ToString(encryptionKeys[0].Bytes).Replace("-", "").ToLower();
|
var key = BitConverter.ToString(encryptionKeys[0].Bytes).Replace("-", "").ToLower();
|
||||||
var commandBase = $"--show-progress --key {keyId}:{key}";
|
var commandBase = $"--show-progress --key {keyId}:{key}";
|
||||||
var commandVideo = commandBase + $" \"{tempTsFile}.video.enc.m4s\" \"{tempTsFile}.video.m4s\"";
|
var commandVideo = commandBase + $" \"{tempTsFile}.video.enc.m4s\" \"{tempTsFile}.video.m4s\"";
|
||||||
var commandAudio = commandBase + $" \"{tempTsFile}.audio.enc.m4s\" \"{tempTsFile}.audio.m4s\"";
|
var commandAudio = commandBase + $" \"{tempTsFile}.audio.enc.m4s\" \"{tempTsFile}.audio.m4s\"";
|
||||||
//TODO change back from error
|
|
||||||
Console.Error.WriteLine("Built command");
|
|
||||||
if (videoDownloaded){
|
if (videoDownloaded){
|
||||||
//TODO change back from error
|
Console.WriteLine("Started decrypting video");
|
||||||
Console.Error.WriteLine("Started decrypting video");
|
data.DownloadProgress = new DownloadProgress(){
|
||||||
|
IsDownloading = true,
|
||||||
|
Percent = 100,
|
||||||
|
Time = 0,
|
||||||
|
DownloadSpeed = 0,
|
||||||
|
Doing = "Decrypting video"
|
||||||
|
};
|
||||||
|
Queue.Refresh();
|
||||||
var decryptVideo = await Helpers.ExecuteCommandAsync("mp4decrypt", CfgManager.PathMP4Decrypt, commandVideo);
|
var decryptVideo = await Helpers.ExecuteCommandAsync("mp4decrypt", CfgManager.PathMP4Decrypt, commandVideo);
|
||||||
|
|
||||||
if (!decryptVideo.IsOk){
|
if (!decryptVideo.IsOk){
|
||||||
|
@ -1156,13 +1150,19 @@ public class Crunchyroll{
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else{
|
} else{
|
||||||
//TODO change back from error
|
Console.WriteLine("No Video downloaded");
|
||||||
Console.Error.WriteLine("No Video downloaded");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audioDownloaded){
|
if (audioDownloaded){
|
||||||
//TODO change back from error
|
Console.WriteLine("Started decrypting audio");
|
||||||
Console.Error.WriteLine("Started decrypting audio");
|
data.DownloadProgress = new DownloadProgress(){
|
||||||
|
IsDownloading = true,
|
||||||
|
Percent = 100,
|
||||||
|
Time = 0,
|
||||||
|
DownloadSpeed = 0,
|
||||||
|
Doing = "Decrypting audio"
|
||||||
|
};
|
||||||
|
Queue.Refresh();
|
||||||
var decryptAudio = await Helpers.ExecuteCommandAsync("mp4decrypt", CfgManager.PathMP4Decrypt, commandAudio);
|
var decryptAudio = await Helpers.ExecuteCommandAsync("mp4decrypt", CfgManager.PathMP4Decrypt, commandAudio);
|
||||||
|
|
||||||
if (!decryptAudio.IsOk){
|
if (!decryptAudio.IsOk){
|
||||||
|
@ -1207,8 +1207,7 @@ public class Crunchyroll{
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else{
|
} else{
|
||||||
//TODO change back from error
|
Console.WriteLine("No Audio downloaded");
|
||||||
Console.Error.WriteLine("No Audio downloaded");
|
|
||||||
}
|
}
|
||||||
} else{
|
} else{
|
||||||
Console.Error.WriteLine("mp4decrypt not found, files need decryption. Decryption Keys: ");
|
Console.Error.WriteLine("mp4decrypt not found, files need decryption. Decryption Keys: ");
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class Session{
|
||||||
Type = LicenseRequest.RequestType.New,
|
Type = LicenseRequest.RequestType.New,
|
||||||
KeyControlNonce = 1093602366,
|
KeyControlNonce = 1093602366,
|
||||||
ProtocolVersion = ProtocolVersion.Current,
|
ProtocolVersion = ProtocolVersion.Current,
|
||||||
RequestTime = uint.Parse((DateTime.Now - DateTime.UnixEpoch).TotalSeconds.ToString().Split(",")[0]),
|
RequestTime = uint.Parse((DateTime.Now - DateTime.UnixEpoch).TotalSeconds.ToString(System.Globalization.CultureInfo.InvariantCulture).Split('.')[0]),
|
||||||
ContentId = new LicenseRequest.ContentIdentification{
|
ContentId = new LicenseRequest.ContentIdentification{
|
||||||
CencId = new LicenseRequest.ContentIdentification.Cenc{
|
CencId = new LicenseRequest.ContentIdentification.Cenc{
|
||||||
LicenseType = LicenseType.Default,
|
LicenseType = LicenseType.Default,
|
||||||
|
@ -104,7 +104,7 @@ public class Session{
|
||||||
Type = LicenseRequestRaw.RequestType.New,
|
Type = LicenseRequestRaw.RequestType.New,
|
||||||
KeyControlNonce = 1093602366,
|
KeyControlNonce = 1093602366,
|
||||||
ProtocolVersion = ProtocolVersion.Current,
|
ProtocolVersion = ProtocolVersion.Current,
|
||||||
RequestTime = uint.Parse((DateTime.Now - DateTime.UnixEpoch).TotalSeconds.ToString().Split(",")[0]),
|
RequestTime = uint.Parse((DateTime.Now - DateTime.UnixEpoch).TotalSeconds.ToString(System.Globalization.CultureInfo.InvariantCulture).Split('.')[0]),
|
||||||
ContentId = new LicenseRequestRaw.ContentIdentification{
|
ContentId = new LicenseRequestRaw.ContentIdentification{
|
||||||
CencId = new LicenseRequestRaw.ContentIdentification.Cenc{
|
CencId = new LicenseRequestRaw.ContentIdentification.Cenc{
|
||||||
LicenseType = LicenseType.Default,
|
LicenseType = LicenseType.Default,
|
||||||
|
|
|
@ -75,6 +75,7 @@ public class Widevine{
|
||||||
public async Task<List<ContentKey>> getKeys(string? pssh, string licenseServer, Dictionary<string, string> authData){
|
public async Task<List<ContentKey>> getKeys(string? pssh, string licenseServer, Dictionary<string, string> authData){
|
||||||
if (pssh == null || !canDecrypt) return new List<ContentKey>();
|
if (pssh == null || !canDecrypt) return new List<ContentKey>();
|
||||||
|
|
||||||
|
try{
|
||||||
byte[] psshBuffer = Convert.FromBase64String(pssh);
|
byte[] psshBuffer = Convert.FromBase64String(pssh);
|
||||||
|
|
||||||
Session ses = new Session(new ContentDecryptionModule{ identifierBlob = identifierBlob, privateKey = privateKey }, psshBuffer);
|
Session ses = new Session(new ContentDecryptionModule{ identifierBlob = identifierBlob, privateKey = privateKey }, psshBuffer);
|
||||||
|
@ -99,6 +100,10 @@ public class Widevine{
|
||||||
ses.ProvideLicense(Convert.FromBase64String(resp.license));
|
ses.ProvideLicense(Convert.FromBase64String(resp.license));
|
||||||
|
|
||||||
return ses.ContentKeys;
|
return ses.ContentKeys;
|
||||||
|
} catch (Exception e){
|
||||||
|
Console.Error.WriteLine(e);
|
||||||
|
return new List<ContentKey>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,12 @@ public class Subscription{
|
||||||
public bool TaxIncluded{ get; set; }
|
public bool TaxIncluded{ get; set; }
|
||||||
[JsonProperty("subscription_products")]
|
[JsonProperty("subscription_products")]
|
||||||
public List<SubscriptionProduct>? SubscriptionProducts{ get; set; }
|
public List<SubscriptionProduct>? SubscriptionProducts{ get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("third_party_subscription_products")]
|
||||||
|
public List<ThirdPartySubscriptionProduct>? ThirdPartySubscriptionProducts{ get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("nonrecurring_subscription_products")]
|
||||||
|
public List<SubscriptionProduct>? NonrecurringSubscriptionProducts{ get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SubscriptionProduct{
|
public class SubscriptionProduct{
|
||||||
|
@ -55,3 +61,24 @@ public class SubscriptionProduct{
|
||||||
[JsonProperty("active_free_trial")]
|
[JsonProperty("active_free_trial")]
|
||||||
public bool ActiveFreeTrial{ get; set; }
|
public bool ActiveFreeTrial{ get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ThirdPartySubscriptionProduct{
|
||||||
|
[JsonProperty("effective_date")]
|
||||||
|
public DateTime EffectiveDate{ get; set; }
|
||||||
|
public string? Source{ get; set; }
|
||||||
|
[JsonProperty("source_reference")]
|
||||||
|
public string? SourceReference{ get; set; }
|
||||||
|
public string? Sku{ get; set; }
|
||||||
|
public string? Tier{ get; set; }
|
||||||
|
[JsonProperty("active_free_trial")]
|
||||||
|
public bool ActiveFreeTrial{ get; set; }
|
||||||
|
[JsonProperty("in_grace")]
|
||||||
|
public bool InGrace{ get; set; }
|
||||||
|
[JsonProperty("on_hold")]
|
||||||
|
public bool OnHold{ get; set; }
|
||||||
|
[JsonProperty("auto_renew")]
|
||||||
|
public bool AutoRenew{ get; set; }
|
||||||
|
[JsonProperty("expiration_date")]
|
||||||
|
public DateTime ExpirationDate{ get; set; }
|
||||||
|
|
||||||
|
}
|
|
@ -53,10 +53,14 @@ public partial class AccountPageViewModel : ViewModelBase{
|
||||||
if (Crunchyroll.Instance.Profile.Subscription != null && Crunchyroll.Instance.Profile.Subscription?.SubscriptionProducts != null){
|
if (Crunchyroll.Instance.Profile.Subscription != null && Crunchyroll.Instance.Profile.Subscription?.SubscriptionProducts != null){
|
||||||
if (Crunchyroll.Instance.Profile.Subscription?.SubscriptionProducts.Count >= 1){
|
if (Crunchyroll.Instance.Profile.Subscription?.SubscriptionProducts.Count >= 1){
|
||||||
var sub = Crunchyroll.Instance.Profile.Subscription?.SubscriptionProducts.First();
|
var sub = Crunchyroll.Instance.Profile.Subscription?.SubscriptionProducts.First();
|
||||||
|
|
||||||
if (sub != null){
|
if (sub != null){
|
||||||
IsCancelled = sub.IsCancelled;
|
IsCancelled = sub.IsCancelled;
|
||||||
}
|
}
|
||||||
|
}else if (Crunchyroll.Instance.Profile.Subscription?.ThirdPartySubscriptionProducts.Count >= 1){
|
||||||
|
var sub = Crunchyroll.Instance.Profile.Subscription?.ThirdPartySubscriptionProducts.First();
|
||||||
|
if (sub != null){
|
||||||
|
IsCancelled = !sub.AutoRenew;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Crunchyroll.Instance.Profile.Subscription?.NextRenewalDate != null){
|
if (Crunchyroll.Instance.Profile.Subscription?.NextRenewalDate != null){
|
||||||
|
|
Loading…
Reference in New Issue