mirror of
https://silica.codes/BedrockReverse/PremiumPacksInstaller.git
synced 2025-04-23 05:05:58 +12:00
Upload v1.0
This commit is contained in:
parent
02a911de75
commit
b3a80a479a
46 changed files with 76594 additions and 0 deletions
65
PremiumPackInstaller/PlayFab/Config.cs
Normal file
65
PremiumPackInstaller/PlayFab/Config.cs
Normal file
|
@ -0,0 +1,65 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace PlayFab
|
||||
{
|
||||
internal class Config
|
||||
{
|
||||
public static string DataFolder = Path.Combine(Environment.GetEnvironmentVariable("APPDATA"), "PremiumPackInstaller");
|
||||
public static string ConfigFile = Path.Combine(DataFolder, "playfab.conf");
|
||||
|
||||
private static void initConfig()
|
||||
{
|
||||
Directory.CreateDirectory(DataFolder);
|
||||
File.WriteAllText(ConfigFile, "");
|
||||
}
|
||||
|
||||
private static void replaceConfValue(string key, string newval)
|
||||
{
|
||||
if (!File.Exists(ConfigFile))
|
||||
initConfig();
|
||||
|
||||
string[] keyValuePairs = File.ReadAllLines(ConfigFile);
|
||||
for (int i = 0; i < keyValuePairs.Length; i++)
|
||||
{
|
||||
string[] kvp = keyValuePairs[i].Split(':');
|
||||
if (kvp[0] == key)
|
||||
keyValuePairs[i] = key + ":" + newval;
|
||||
}
|
||||
|
||||
File.WriteAllLines(ConfigFile, keyValuePairs);
|
||||
}
|
||||
|
||||
public static string GetConfValue(string key)
|
||||
{
|
||||
if (!File.Exists(ConfigFile))
|
||||
initConfig();
|
||||
|
||||
string[] keyValuePairs = File.ReadAllLines(ConfigFile);
|
||||
foreach (string keyValuePair in keyValuePairs)
|
||||
{
|
||||
string[] kvp = keyValuePair.Split(':');
|
||||
if (kvp[0] == key)
|
||||
return String.Join(":", kvp.Skip(1).ToArray());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
public static void WriteConfValue(string key, string value)
|
||||
{
|
||||
if (!File.Exists(ConfigFile))
|
||||
initConfig();
|
||||
string curConfValue = GetConfValue(key);
|
||||
|
||||
if (curConfValue == value)
|
||||
return;
|
||||
|
||||
if (curConfValue != null)
|
||||
replaceConfValue(key, value);
|
||||
else
|
||||
File.AppendAllLines(ConfigFile, new string[] { key + ":" + value });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
18
PremiumPackInstaller/PlayFab/McClient.cs
Normal file
18
PremiumPackInstaller/PlayFab/McClient.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
using System.Net;
|
||||
using System;
|
||||
namespace PlayFab
|
||||
{
|
||||
class McClient : WebClient
|
||||
{
|
||||
protected override WebRequest GetWebRequest(Uri address)
|
||||
{
|
||||
HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
|
||||
if (request == null)
|
||||
return null;
|
||||
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
|
||||
return request;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
234
PremiumPackInstaller/PlayFab/PlayFab.cs
Normal file
234
PremiumPackInstaller/PlayFab/PlayFab.cs
Normal file
|
@ -0,0 +1,234 @@
|
|||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Dynamic;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace PlayFab
|
||||
{
|
||||
|
||||
public class PlayFab
|
||||
{
|
||||
|
||||
public static string PLAYFAB_VERSION = "XPlatCppSdk-3.6.190304";
|
||||
public static string CPP_REST_VERSION = "cpprestsdk/2.9.0";
|
||||
|
||||
public static string TITLE_ID = "20CA2";
|
||||
public static string TITLE_SECRET = "S8RS53ZEIGMYTYG856U3U19AORWXQXF41J7FT3X9YCWAC7I35X";
|
||||
public static byte[] PUBLIC_KEY = null;
|
||||
|
||||
|
||||
public static string ENTITY_TOKEN = null;
|
||||
public static string ENTITY_ID = null;
|
||||
public static string ENTITY_TYPE = null;
|
||||
|
||||
|
||||
|
||||
public static dynamic GetProductInformation(string uuid)
|
||||
{
|
||||
dynamic dyn = new ExpandoObject();
|
||||
dyn.ItemId = uuid;
|
||||
dyn.ETag = "";
|
||||
|
||||
return POST(dyn, "/Catalog/GetPublishedItem");
|
||||
}
|
||||
public static dynamic Search(string query, string filter = "", int skip = 0, string orderBy= "creationDate DESC")
|
||||
{
|
||||
dynamic dyn = new ExpandoObject();
|
||||
dyn.count = true;
|
||||
dyn.filter = filter;
|
||||
dyn.search = query;
|
||||
dyn.orderBy = orderBy;
|
||||
dyn.top = 300;
|
||||
dyn.skip = skip;
|
||||
|
||||
return POST(dyn, "/Catalog/Search");
|
||||
}
|
||||
|
||||
public static dynamic POST(dynamic data, string url, string clientsecret = null, bool incSDK = false)
|
||||
{
|
||||
McClient wc = new McClient();
|
||||
string body = JsonConvert.SerializeObject(data, (incSDK ? Formatting.Indented : Formatting.None));
|
||||
|
||||
// Pretend to be minecraft ...
|
||||
|
||||
wc.Headers.Set("Accept", "application/json");
|
||||
wc.Headers.Set("Accept-Language", "en-US");
|
||||
wc.Headers.Set("Accept-Encoding", "gzip, deflate, br");
|
||||
wc.Headers.Set("User-Agent", CPP_REST_VERSION);
|
||||
wc.Headers.Set("x-playfabsdk", PLAYFAB_VERSION);
|
||||
wc.Headers.Set("x-reporterrorassuccess", "true");
|
||||
wc.Headers.Set("content-type", "application/json; charset=utf-8");
|
||||
|
||||
if (clientsecret != null)
|
||||
{
|
||||
|
||||
string signature;
|
||||
string timestamp = DateTime.UtcNow.ToString("O");
|
||||
|
||||
using (SHA256 hash = SHA256.Create())
|
||||
{
|
||||
string msg = body + "." + timestamp + "." + clientsecret;
|
||||
byte[] bytesToHash = Encoding.UTF8.GetBytes(msg);
|
||||
signature = Convert.ToBase64String(hash.ComputeHash(bytesToHash));
|
||||
}
|
||||
|
||||
wc.Headers.Set("x-playfab-signature", signature);
|
||||
wc.Headers.Set("x-playfab-timestamp", timestamp);
|
||||
}
|
||||
if (ENTITY_TOKEN != null)
|
||||
wc.Headers.Set("x-entitytoken", ENTITY_TOKEN);
|
||||
string response = wc.UploadString(GetPlayfabApiUrl() + url + (incSDK ? SdkMsg() : ""), body);
|
||||
dynamic resp = JsonConvert.DeserializeObject(response);
|
||||
wc.Dispose();
|
||||
|
||||
return resp.data;
|
||||
|
||||
}
|
||||
public static string RefreshEntityTokenBullshit()
|
||||
{
|
||||
dynamic dyn = new ExpandoObject();
|
||||
dyn.Entity = new ExpandoObject();
|
||||
dyn.Entity.Id = ENTITY_ID;
|
||||
dyn.Entity.Type = ENTITY_TYPE;
|
||||
|
||||
dynamic resp = POST(dyn, "/Authentication/GetEntityToken", null, true);
|
||||
ENTITY_TOKEN = resp.EntityToken.ToString();
|
||||
return ENTITY_TOKEN;
|
||||
}
|
||||
public static string SdkMsg()
|
||||
{
|
||||
return "?sdk=" + PLAYFAB_VERSION;
|
||||
}
|
||||
public static string GenerateClientSecret()
|
||||
{
|
||||
Random r = new Random(Guid.NewGuid().GetHashCode());
|
||||
byte[] clientSecret = new byte[0x20];
|
||||
r.NextBytes(clientSecret);
|
||||
return Convert.ToBase64String(clientSecret);
|
||||
}
|
||||
public static string GenerateCustomId()
|
||||
{
|
||||
Random r = new Random(Guid.NewGuid().GetHashCode());
|
||||
byte[] customId = new byte[0x10];
|
||||
r.NextBytes(customId);
|
||||
return "MCPF" + BitConverter.ToString(customId).Replace("-", "").ToUpper();
|
||||
}
|
||||
|
||||
public static string GetPlayfabApiUrl()
|
||||
{
|
||||
return "https://" + TITLE_ID + ".playfabapi.com";
|
||||
}
|
||||
|
||||
// How 2 find TitleSharedSecret:
|
||||
// 1- delete all mc data
|
||||
// 2- open fiddler
|
||||
// 3- open minecraft
|
||||
// 4- check for https://20ca2.playfabapi.com/Client/GetTitlePublicKey...
|
||||
public static void GetPublicKeyAndMicrosoftTakesABigL()
|
||||
{
|
||||
dynamic dyn = new ExpandoObject();
|
||||
dyn.TitleId = TITLE_ID;
|
||||
dyn.TitleSharedSecret = TITLE_SECRET;
|
||||
|
||||
dynamic resp = POST(dyn, "/Client/GetTitlePublicKey", null, true);
|
||||
PUBLIC_KEY = Convert.FromBase64String(resp.RSAPublicKey.ToString());
|
||||
}
|
||||
|
||||
public static string EncryptCustomIdLoginToken(string customId, string clientSecret)
|
||||
{
|
||||
dynamic dyn = new ExpandoObject();
|
||||
dyn.CustomId = customId;
|
||||
dyn.PlayerSecret = clientSecret;
|
||||
|
||||
|
||||
return EncryptRequest(JsonConvert.SerializeObject(dyn));
|
||||
}
|
||||
|
||||
public static string LoginWithCustomId(bool newUser = true, string customId = null, string clientSecret = null)
|
||||
{
|
||||
dynamic dyn = new ExpandoObject();
|
||||
|
||||
if (newUser)
|
||||
dyn.CreateAccount = true;
|
||||
else
|
||||
dyn.CreateAccount = null;
|
||||
dyn.CustomId = customId;
|
||||
|
||||
if (clientSecret == null)
|
||||
clientSecret = GenerateClientSecret();
|
||||
|
||||
if (customId == null)
|
||||
customId = GenerateCustomId();
|
||||
|
||||
if (newUser)
|
||||
dyn.EncryptedRequest = EncryptCustomIdLoginToken(customId, clientSecret);
|
||||
else
|
||||
dyn.EncryptedRequest = null;
|
||||
|
||||
dyn.InfoRequestParameters = new ExpandoObject();
|
||||
dyn.InfoRequestParameters.GetCharacterInventories = false;
|
||||
dyn.InfoRequestParameters.GetCharacterList = false;
|
||||
dyn.InfoRequestParameters.GetPlayerProfile = true;
|
||||
dyn.InfoRequestParameters.GetPlayerStatistics = false;
|
||||
dyn.InfoRequestParameters.GetTitleData = false;
|
||||
dyn.InfoRequestParameters.GetUserAccountInfo = true;
|
||||
dyn.InfoRequestParameters.GetUserData = false;
|
||||
dyn.InfoRequestParameters.GetUserInventory = false;
|
||||
dyn.InfoRequestParameters.GetUserReadOnlyData = false;
|
||||
dyn.InfoRequestParameters.PlayerStatisticNames = null;
|
||||
dyn.InfoRequestParameters.ProfileConstraints = null;
|
||||
dyn.InfoRequestParameters.TitleDataKeys = null;
|
||||
dyn.InfoRequestParameters.UserDataKeys = null;
|
||||
dyn.InfoRequestParameters.UserReadOnlyDataKeys = null;
|
||||
|
||||
dyn.PlayerSecret = null;
|
||||
dyn.TitleId = TITLE_ID;
|
||||
|
||||
|
||||
dynamic resp = POST(dyn, "/Client/LoginWithCustomID", newUser ? null : clientSecret, true);
|
||||
|
||||
Config.WriteConfValue("CustomId", customId);
|
||||
Config.WriteConfValue("ClientSecret", clientSecret);
|
||||
|
||||
ENTITY_TOKEN = resp.EntityToken.EntityToken.ToString();
|
||||
ENTITY_ID = resp.PlayFabId.ToString();
|
||||
ENTITY_TYPE = "master_player_account";
|
||||
|
||||
return ENTITY_TOKEN;
|
||||
}
|
||||
|
||||
public static string EncryptRequest(string plaintext)
|
||||
{
|
||||
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
|
||||
{
|
||||
rsa.ImportCspBlob(PUBLIC_KEY);
|
||||
byte[] bytesToEncrypt = Encoding.UTF8.GetBytes(plaintext);
|
||||
byte[] encryptedBytes = rsa.Encrypt(bytesToEncrypt, false);
|
||||
return Convert.ToBase64String(encryptedBytes);
|
||||
}
|
||||
}
|
||||
|
||||
public static string PullEntityTokenOutOfMyAss()
|
||||
{
|
||||
|
||||
if (Config.GetConfValue("CustomId") == null && Config.GetConfValue("ClientSecret") == null)
|
||||
{
|
||||
GetPublicKeyAndMicrosoftTakesABigL();
|
||||
LoginWithCustomId();
|
||||
return RefreshEntityTokenBullshit();
|
||||
}
|
||||
else
|
||||
{
|
||||
string customId = Config.GetConfValue("CustomId");
|
||||
string clientSecret = Config.GetConfValue("ClientSecret");
|
||||
|
||||
LoginWithCustomId(false, customId, clientSecret);
|
||||
return RefreshEntityTokenBullshit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue