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