diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f608001
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+UnlinkPSN/obj/*
+UnlinkPSN/bin/*
+
+*.user
+
+bin/*
+obj/*
\ No newline at end of file
diff --git a/UnlinkPSN.sln b/UnlinkPSN.sln
new file mode 100644
index 0000000..d3a0dbb
--- /dev/null
+++ b/UnlinkPSN.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.3.32611.2
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnlinkPSN", "UnlinkPSN\UnlinkPSN.csproj", "{2CF49BCB-46F5-4BD9-A40A-530FA62E57A4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2CF49BCB-46F5-4BD9-A40A-530FA62E57A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2CF49BCB-46F5-4BD9-A40A-530FA62E57A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2CF49BCB-46F5-4BD9-A40A-530FA62E57A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2CF49BCB-46F5-4BD9-A40A-530FA62E57A4}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {8CFF5A67-53C5-402C-9561-50B1CA442AC6}
+ EndGlobalSection
+EndGlobal
diff --git a/UnlinkPSN/Program.cs b/UnlinkPSN/Program.cs
new file mode 100644
index 0000000..cee4992
--- /dev/null
+++ b/UnlinkPSN/Program.cs
@@ -0,0 +1,17 @@
+namespace UnlinkPSN
+{
+ internal static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ // To customize application configuration such as set high DPI settings or default font,
+ // see https://aka.ms/applicationconfiguration.
+ ApplicationConfiguration.Initialize();
+ Application.Run(new UnlinkForm());
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnlinkPSN/Properties/PublishProfiles/Win64.pubxml b/UnlinkPSN/Properties/PublishProfiles/Win64.pubxml
new file mode 100644
index 0000000..c22f8c8
--- /dev/null
+++ b/UnlinkPSN/Properties/PublishProfiles/Win64.pubxml
@@ -0,0 +1,18 @@
+
+
+
+
+ Release
+ Any CPU
+ bin\Release\net7.0-windows\publish\Win64
+ FileSystem
+ <_TargetId>Folder
+ net7.0-windows
+ win-x64
+ true
+ true
+ true
+
+
\ No newline at end of file
diff --git a/UnlinkPSN/UnlinkForm.Designer.cs b/UnlinkPSN/UnlinkForm.Designer.cs
new file mode 100644
index 0000000..7cdf4b2
--- /dev/null
+++ b/UnlinkPSN/UnlinkForm.Designer.cs
@@ -0,0 +1,69 @@
+namespace UnlinkPSN
+{
+ partial class UnlinkForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UnlinkForm));
+ this.xbxAuth = new Microsoft.Web.WebView2.WinForms.WebView2();
+ ((System.ComponentModel.ISupportInitialize)(this.xbxAuth)).BeginInit();
+ this.SuspendLayout();
+ //
+ // xbxAuth
+ //
+ this.xbxAuth.AllowExternalDrop = true;
+ this.xbxAuth.CreationProperties = null;
+ this.xbxAuth.DefaultBackgroundColor = System.Drawing.Color.White;
+ this.xbxAuth.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.xbxAuth.Location = new System.Drawing.Point(0, 0);
+ this.xbxAuth.Name = "xbxAuth";
+ this.xbxAuth.Size = new System.Drawing.Size(524, 621);
+ this.xbxAuth.TabIndex = 0;
+ this.xbxAuth.ZoomFactor = 1D;
+ this.xbxAuth.CoreWebView2InitializationCompleted += new System.EventHandler(this.xbxAuth_CoreWebView2InitializationCompleted);
+ this.xbxAuth.SourceChanged += new System.EventHandler(this.xbxAuth_SourceChanged);
+ //
+ // UnlinkForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(524, 621);
+ this.Controls.Add(this.xbxAuth);
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.Name = "UnlinkForm";
+ this.Text = "Login to Microsoft ...";
+ this.Load += new System.EventHandler(this.UnlinkForm_Load);
+ ((System.ComponentModel.ISupportInitialize)(this.xbxAuth)).EndInit();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private Microsoft.Web.WebView2.WinForms.WebView2 xbxAuth;
+ }
+}
\ No newline at end of file
diff --git a/UnlinkPSN/UnlinkForm.cs b/UnlinkPSN/UnlinkForm.cs
new file mode 100644
index 0000000..0eb1ba8
--- /dev/null
+++ b/UnlinkPSN/UnlinkForm.cs
@@ -0,0 +1,163 @@
+using Microsoft.Web.WebView2.Core;
+using Newtonsoft.Json;
+using System.Dynamic;
+using System.Net;
+using XboxWebApi.Authentication;
+using XboxWebApi.Authentication.Model;
+
+namespace UnlinkPSN
+{
+ public partial class UnlinkForm : Form
+ {
+ public UnlinkForm()
+ {
+ InitializeComponent();
+ }
+
+ private void UnlinkForm_Load(object sender, EventArgs e)
+ {
+ string requestUrl = AuthenticationService.GetWindowsLiveAuthenticationUrl();
+ xbxAuth.Source = new Uri(requestUrl);
+ }
+
+ private string gamerTag = "";
+
+ private void UnlinkPsnAccount(string sessionTicket)
+ {
+ dynamic request = new ExpandoObject();
+ string requestStr = JsonConvert.SerializeObject(request);
+
+ WebClient wc = new WebClient();
+ wc.Headers.Add("User-Agent", "cpprestsdk/2.9.0");
+ wc.Headers.Add("Content-Type", "application/json; charset=utf-8");
+ wc.Headers.Add("x-playfabsdk", "XPlatCppSdk-3.6.190304");
+ wc.Headers.Add("X-Authorization", sessionTicket);
+ wc.UploadString("https://20ca2.playfabapi.com/Client/UnlinkPSNAccount?sdk=XPlatCppSdk-3.6.190304", requestStr);
+
+ }
+ private dynamic LoginWithXbox(string xbxToken)
+ {
+ dynamic request = new ExpandoObject();
+ request.CreateAccount = null;
+ request.CustomId = null;
+
+ request.EncryptedRequest = null;
+
+ request.InfoRequestParameters = new ExpandoObject();
+ request.InfoRequestParameters.GetCharacterInventories = false;
+ request.InfoRequestParameters.GetCharacterList = false;
+ request.InfoRequestParameters.GetPlayerProfile = true;
+ request.InfoRequestParameters.GetPlayerStatistics = false;
+ request.InfoRequestParameters.GetTitleData = false;
+ request.InfoRequestParameters.GetUserAccountInfo = true;
+ request.InfoRequestParameters.GetUserData = false;
+ request.InfoRequestParameters.GetUserInventory = false;
+ request.InfoRequestParameters.GetUserReadOnlyData = false;
+ request.InfoRequestParameters.PlayerStatisticNames = null;
+ request.InfoRequestParameters.ProfileConstraints = null;
+ request.InfoRequestParameters.TitleDataKeys = null;
+ request.InfoRequestParameters.UserDataKeys = null;
+ request.InfoRequestParameters.UserReadOnlyDataKeys = null;
+
+ request.PlayerSecret = null;
+ request.TitleId = "20CA2";
+ request.XboxToken = xbxToken;
+
+ string requestStr = JsonConvert.SerializeObject(request, Formatting.Indented);
+
+ WebClient wc = new WebClient();
+ wc.Headers.Add("User-Agent", "cpprestsdk/2.9.0");
+ wc.Headers.Add("Content-Type", "application/json; charset=utf-8");
+ wc.Headers.Add("x-playfabsdk", "XPlatCppSdk-3.6.190304");
+ wc.Headers.Add("x-reporterrorassuccess", "true");
+
+
+ string responseStr = wc.UploadString("https://20ca2.playfabapi.com/Client/LoginWithXbox?sdk=XPlatCppSdk-3.6.190304", requestStr);
+ return JsonConvert.DeserializeObject(responseStr);
+ }
+
+ private async Task XboxAuth(string newUrl)
+ {
+ WindowsLiveResponse response = AuthenticationService.ParseWindowsLiveResponse(newUrl);
+ AuthenticationService authenticator = new AuthenticationService(response);
+ bool authenticateSuccess = await authenticator.AuthenticateAsync();
+ if (authenticateSuccess)
+ {
+ gamerTag = authenticator.UserInformation.Gamertag;
+ // Get playfab xtoken
+ string userToken = authenticator.UserToken.Jwt;
+
+ dynamic altRelayingPartyRequest = new ExpandoObject();
+ altRelayingPartyRequest.RelyingParty = "https://b980a380.minecraft.playfabapi.com/";
+ altRelayingPartyRequest.TokenType = "JWT";
+ altRelayingPartyRequest.Properties = new ExpandoObject();
+ altRelayingPartyRequest.Properties.SandboxId = "RETAIL";
+ altRelayingPartyRequest.Properties.UserTokens = new String[] { userToken };
+
+ string altRelayingPartyRequestStr = JsonConvert.SerializeObject(altRelayingPartyRequest);
+
+ WebClient wc = new WebClient();
+ wc.Headers.Add("x-xbl-contract-version", "1");
+ wc.Headers.Add("Content-Type", "application/json; charset=utf-8");
+ dynamic jsonResponse = JsonConvert.DeserializeObject(wc.UploadString("https://xsts.auth.xboxlive.com/xsts/authorize", altRelayingPartyRequestStr));
+ string xtoken = jsonResponse.Token;
+
+ // Playfab LoginWithXbox token!
+ return "XBL3.0 x=" + authenticator.UserInformation.Userhash + ";" + xtoken;
+ }
+ return null;
+ }
+ private async Task UnlinkPsnByMSAccount(string newUrl)
+ {
+ string xtoken = await XboxAuth(newUrl);
+ if(xtoken != null)
+ {
+ dynamic loginResponse = LoginWithXbox(xtoken);
+ if (loginResponse.data != null)
+ {
+ // Playfab tokens
+ string sessionTicket = loginResponse.data.SessionTicket;
+
+ if(loginResponse.data.InfoResultPayload.AccountInfo.PsnInfo == null)
+ {
+ MessageBox.Show("No PSN Account is Linked.", "No Linked Account ...", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ Environment.Exit(0);
+ }
+ else
+ {
+ long accountId = loginResponse.data.InfoResultPayload.AccountInfo.PsnInfo.PsnAccountId;
+ string accountName = loginResponse.data.InfoResultPayload.AccountInfo.PsnInfo.PsnOnlineId;
+
+ if(MessageBox.Show("Do you want to unlink the PSN Account: \n"+accountName+" (0x"+accountId.ToString("X")+")\nfrom the Minecraft Bedrock Account "+ gamerTag+"?", "Unlink?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
+ {
+ UnlinkPsnAccount(sessionTicket);
+ MessageBox.Show("Account Unlinked!", "Unlink Success.", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ Environment.Exit(0);
+ }
+ else
+ {
+ Environment.Exit(0);
+ }
+ }
+ }
+ }
+
+ MessageBox.Show("Something went wrong!\n\nAnd just like microsoft im not going to tell you what it was.,", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ Environment.Exit(0);
+ }
+ private void xbxAuth_SourceChanged(object sender, CoreWebView2SourceChangedEventArgs e)
+ {
+ string newUrl = xbxAuth.Source.ToString();
+ if (newUrl.StartsWith("https://login.live.com/oauth20_desktop.srf"))
+ {
+ this.Hide();
+ _ = UnlinkPsnByMSAccount(newUrl);
+ }
+ }
+
+ private void xbxAuth_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
+ {
+ xbxAuth.CoreWebView2.CookieManager.DeleteAllCookies();
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnlinkPSN/UnlinkForm.resx b/UnlinkPSN/UnlinkForm.resx
new file mode 100644
index 0000000..180dc4f
--- /dev/null
+++ b/UnlinkPSN/UnlinkForm.resx
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+
+ AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAMMOAADDDgAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4/oQA8R5UCHjSqIxgtr2IYLbCfGS60zhcr
+ tesaLrbzHDC39BovtukZLrTNFyyznhcrrGEmK0dCPz8+nSwsLKgbGxs9FhYWBBUVFQAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACw3ogA2Pp0CGi2qLhgtsI4YLLbYFSi7+hIk
+ vf8OHr7/DBq//woYv/8LGb//CxrA/xAgvv8dLqj/ND15+Dc5QO9JSUn+QUFB/yoqKug1NTWXTExMNRAQ
+ EAQhISEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL6+XAAVJqwAIjGkFBgtsH8VKbfkESK9/wgV
+ vv8DD7//AQ3A/wENwP8AC8D/AAvB/wAKwP8KFKn/MjiI/zg6Tf9GRUT/QUFB/0NDQ/8xMTH/NDQ0/zEx
+ Mf8uLi7pNDQ0lysrKzMMDAwEGxsbAAAAAAAAAAAAAAAAAAAAAAA2RaIABiC1ACA0qi4UKLK3Dh+6/AYU
+ vf8CDsD/AQvC/wELxP8CCcf/AgjJ/wMHy/8HDbX/GB1x/ywtQf86Ojj/Pz89/0RERP9OTk7/R0dH/zU1
+ Nf8zMzP/LCws/ycnJ/81NTX/NDQ06SgoKJg5OTknNTU1AAAAAAAAAAAAQEabAAAVuAAWKqs3EiW1zwkZ
+ uv8BDb3/AQvC/wEKxv8BCMr/AgbM/wIEz/8DAtL/BALY/x4dnf9LSkj/RUVE/zk5Of9KSkr/WFhY/1JS
+ Uv9dXV3/QkJC/y8vL/82Njb/Ozs7/zw8PP8pKSn/MjIy/z4+Pn49PT0AAAAAAF50sgAUJ60AHjGrLhAj
+ tdIGFLz/AQy+/wEKw/8BCMj/AQXL/wEEz/8BA9H/AgLT/wIB1P8BANj/Hh2c/0JCQf8/Pz//TU1N/z8/
+ P/9NTU3/Tk5O/0FBQf9CQkL/NTU1/ysrK/8tLS3/ODg4/z8/P/88PDz/QEBAgT09PQAAAAAAIDKqACU3
+ qRYRJLO6BRS7/wEMwf8BCcb/AQbL/wEDz/8CAdP/AwHX/wQB2f8GAdv/BwDc/wYA3/8bF5n/RERD/zY2
+ Nv89PT3/PT09/0xMTP9KSUr/Ly8v/y8vL/83Nzf/Ozs7/zQ0NP89PT3/Pj4+/zk5Of8lJSWBLi4uADZJ
+ qgDq+WQBEyiwgAcXuf4BC8H/AQfI/wEEzv8CAtP/BAHY/wYB3P8IAeD/CQDh/woA4/8LAeT/CgDm/yUe
+ pf9OTk3/QEBA/09PT/84ODj/SEhI/01NTf88PDz/Nzc3/zU1Nf8wMDD/MTEx/zAwMP86Ojr/RUVF/0RE
+ RIFMTEwAEySrABcoqi8JGrfjAg3A/wEHyP8BA8//AwHU/wcB2/8JAeD/CwHk/w0B5/8OAen/DwHr/w8B
+ 7P8NAO3/Lyau/1NTUv9CQkL/RkZG/zs7O/85OTn/QkJC/z8/P/8tLS3/Li4u/yYmJv8uLi7/LS0t/z8/
+ P/84ODj/Ojo6gTU1NQDy/HUBDh6wjQIOvP8BBsb/AQLO/wQB1f8IAd3/CwHj/wwA6P8NAOz/DwDu/xEA
+ 8P8RAPH/NSTx/4N49/+Ff67/TU1N/zg4OP81NTX/U1NT/09PT/81NTX/QEBA/0pKSv85OTn/MzMz/zs7
+ O/8yMjL/OTk5/ysrK/8fIjSZYKX/AR8yrCQIF7fZAAnC/wEEzP8EAdT/CAHc/wwB4/8fEen/RDXv/2hb
+ 8/9+cfX/fXD1/1tL8/+HfPX//////6ysrP9ERET/Pz8//0xMTP9TU1P/VlZW/0tLS/9FRUX/XV1d/1RU
+ VP9ISEj/TU1N/0FBQf80NDT/MDAv/yAoYdoZLrwkEyavZAMPvPkBBcj/AwLS/wgB2/8NAeP/Vkrs/8W+
+ 9//t6fv/yMD4/7Ck9v/Wz/r/zsb4/5uQ9v//////q6ur/zk5Of9CQkL/YmJi/01NTf9FRUX/Xl5e/1ZW
+ Vv9ra2v/XV1d/25ubv9YWFj/PT09/y8vL/8wLy3/HSZv+hMms2UPI7OkAgzA/wIDzP8GAdf/CwHh/xMC
+ 6P+ajvP////+//7+/v/At/j/bVzz/0w48f9RPPL/j4L3//////+4uLn/PT08/0REQ/9SUlL/RkZG/05O
+ Tv9cXFz/TU1N/11dXf9WVlb/Y2Nj/1hYWP9HR0f/S0tI/zs7O/8XInn/DB+yowsctdMBCcT/AwLQ/wgB
+ 3P8PAOb/FQDu/zEa8v+DdPb/z8j6//f0/f/7+f7/3Nb7/46A9f+Th/f///////b29P+inr3/W1Z8/1JS
+ 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
+ AAPgAAAH8AAAD/gAAB/8AAA//gAAf/+AAf8=
+
+
+
\ No newline at end of file
diff --git a/UnlinkPSN/UnlinkPSN.csproj b/UnlinkPSN/UnlinkPSN.csproj
new file mode 100644
index 0000000..b1b514c
--- /dev/null
+++ b/UnlinkPSN/UnlinkPSN.csproj
@@ -0,0 +1,30 @@
+
+
+
+ False
+ Static
+ explicit
+ False
+ low
+
+
+
+ WinExe
+ net7.0-windows
+ enable
+ true
+ enable
+ unlink.ico
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UnlinkPSN/unlink.ico b/UnlinkPSN/unlink.ico
new file mode 100644
index 0000000..e949361
Binary files /dev/null and b/UnlinkPSN/unlink.ico differ