From 429c5c7e46e852817b95441c19f3fefe1a070cef Mon Sep 17 00:00:00 2001 From: AlphaBs Date: Thu, 11 Feb 2021 23:36:33 +0900 Subject: [PATCH] add documents --- README.md | 55 ++++++++++++++ docs/MojangAPI.md | 146 +++++++++++++++++++++++++++++++++++++ docs/MojangAuth.md | 119 ++++++++++++++++++++++++++++++ docs/SecurityQuestion.md | 100 +++++++++++++++++++++++++ docs/XboxAuthentication.md | 1 + 5 files changed, 421 insertions(+) create mode 100644 README.md create mode 100644 docs/MojangAPI.md create mode 100644 docs/MojangAuth.md create mode 100644 docs/SecurityQuestion.md create mode 100644 docs/XboxAuthentication.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..77741bf --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# Mojang API + +![Discord](https://img.shields.io/discord/795952027443527690?label=discord&logo=discord&style=for-the-badge) + +.NET Library for [Mojang API](https://wiki.vg/Mojang_API), [Mojang Authentication](https://wiki.vg/Authentication) and [Microsoft Xbox Authentication](https://wiki.vg/Microsoft_Authentication_Scheme) + +- Asynchronous API +- Getting Player Data +- Changing Player Name or Skin +- Mojang Authentication +- Microsoft Authentication +- Security Question-Answer +- Statistics + +Support: + +- .NET Framework 4.6.2 +- .NET Core 3.1 +- .NET 5.0 + +## Install + +Use Nuget package [MojangAPI](https://nuget.org) or download dll from [release](https://github.com). + +## Dependencies + +- Newtonsoft.Json +- System.Net.Http + +## Usage + +Include these namespaces : + +```csharp +using MojangAPI; +using MojangAPI.Model; +``` + +Sample program: [MojangAPISample](./MojangAPISample) + +### [MojangAPI](./docs/MojangAPI.md) + +Getting player profile, Changing name or skin, Statistics, Blocked Server, Checking Game Ownership + +### [Authentication](./docs/MojangAuth.md) + +Mojang Yggdrasil authentication. + +### [XboxAuthentication](./docs/XboxAuthentication.md) + +Microsoft Xbox Authentication + +### [SecurityQuestion](./docs/SecurityQuestion.md) + +Security question-answer flow \ No newline at end of file diff --git a/docs/MojangAPI.md b/docs/MojangAPI.md new file mode 100644 index 0000000..415a721 --- /dev/null +++ b/docs/MojangAPI.md @@ -0,0 +1,146 @@ +## Mojang + +Most methods return `MojangAPIResponse` or class inherited from `MojangAPIResponse`. +You can check whether the request was successful or failed to check `IsSuccess` property in `MojangAPIResponse`. +If `IsSuccess` is false, `Error` and `ErrorMessage` property tell you why the request failed. + +Example: +```csharp +HttpClient httpClient = new HttpClient(); +Mojang mojang = new Mojang(httpClient); + +MojangAPIResponse response = await mojang.something(); +if (response.isSuccess) +{ + Console.WriteLine("Success!"); +} +else +{ + Console.WriteLine(response.Error); + Console.WriteLine(response.ErrorMessage); +} +``` + +#### GetUUID + +```csharp +PlayerUUID uuid = await mojang.GetUUID("username"); + +// uuid.UUID +// uuid.IsLegacy +// uuid.IsDemo +``` + +#### GetUUIDs +```csharp +PlayerUUID[] uuids = await mojang.GetUUIDs(new string[] { "user1", "user2" }); + +if (uuids == null) + Console.WriteLine("Failed to request"); +else +{ + foreach (PlayerUUID uuid in uuids) + { + Console.WriteLine(uuid.UUID); + } +} +``` + +*note: this method return null if the request was failed* + +#### GetNameHistories +```csharp +NameHistoryResponse response = await mojang.GetNameHistories("uuid"); + +if (response.IsSuccess) +{ + foreach (NameHistory item in response.Histories) + { + // item.Name + // item.ChangedToAt + // item.ChangedTime + } +} +else +{ + Console.WriteLine(response.Error); + Console.WriteLine(response.ErrorMessage); +} +``` + +#### GetProfileUsingUUID + +```csharp +PlayerProfile profile = await mojang.GetProfileUsingUUID("uuid"); + +// profile.UUID +// profile.Name +// profile.Skin +// profile.IsLegacy +``` + +#### GetProfileUsingAccessToken + +```csharp +PlayerProfile profile = await mojang.GetProfileUsingAccessToken("accessToken"); +``` + +#### ChangeName + +```csharp +PlayerProfile profile = await mojang.ChangeName("accessToken", "newName"); +``` + +#### ChangeSkin + +```csharp +MojangAPIResponse response = await mojang.ChangeSkin("uuid", "accessToken", SkinType.Steve, "skinUrl"); +``` + +#### UploadSkin + +```csharp +MojangAPIResponse response = await mojang.UploadSkin("accessToken", SkinType.Steve, "skin_png_file_path"); +``` +```csharp +Stream stream; // create stream for uploading skin +MojangAPIResponse response = await mojang.UploadSkin("accessToken", SkinType.Steve, stream, "file_name"); +``` + +#### ResetSkin + +```csharp +MojangAPIResponse response = await mojang.ResetSkin("uuid", "accessToken"); +``` + +#### GetBlockedServer + +```csharp +string[] servers = await mojang.GetBlockedServer(); +``` + +#### GetStatistics + +```csharp +Statistics stats = await mojang.GetStatistics( + StatisticOption.ItemSoldMinecraft, + StatisticOption.ItemSoldCobalt +); + +// stats.Total +// stats.Last24h +// stats.SaleVelocityPerSeconds +``` + +#### CheckGameOwnership + +```csharp +bool result = await mojang.CheckGameOwnership("accessToken"); + +if (result) + Console.WriteLine("You have Minecraft JE"); +else + Console.WriteLine("You don't have Minecraft JE"); +``` + +*note: this method works only accessToken from Microsoft login* \ No newline at end of file diff --git a/docs/MojangAuth.md b/docs/MojangAuth.md new file mode 100644 index 0000000..2fc7d91 --- /dev/null +++ b/docs/MojangAuth.md @@ -0,0 +1,119 @@ +## MojangAuth + +Most methods return `MojangAuthResponse` or class inherited from `MojangAuthResponse`. +You can check whether the request was successful or failed to check `IsSuccess` property in `MojangAuthResponse`. +`Session` property is the result of authenticate. It contains `Username`, `AccessToken`, and `UUID` +If `IsSuccess` is false, `Result`, `Error`, and `ErrorMessage` property tell you why the request failed. + +`MojangAuth` has its own session caching manager. You don't have to type mojang email and password everytime when you login. Login once using your mojang email and password, and `MojangAuth` will save your session information into json file(not contain your raw password, it contains only tokens). Next time when you login just call `TryAutoLogin`. it authenticate you using cached session without typing mojang email and password. + +Example: + +```csharp +HttpClient httpClient = new HttpClient(); +MojangAuth auth = new MojangAuth(httpClient); + +MojangAuthResponse res; + +res = await auth.TryAutoLogin(); // login using cached session +if (!res.IsSuccess) // failed to login using cached session +{ + Console.WriteLine(res.Result.ToString()); + + // it will save your login information into json file + res = await auth.Authenticate("mojang email", "password"); +} + +Console.WriteLine(res.ToString()); + +Session session = res.Session; +// session.Username +// session.UUID +// session.AccessToken +``` + +### Constructor + +#### public MojangAuth(HttpClient client) + +Same as `new MojangAuth(client, new SessionFileCacheManager("mojang_auth.json"))` + +#### public MojangAuth(HttpClient httpClient, ICacheManager\ _cacheManager) + +Initialize a new instance of the `MojangAuth` class with the specified cache manager. +If `_cacheManager` is null, `MojangAuth` does not cache session. +If you want to change cache file path, create a instance of `SessionFileCacheManager` with file path. +Example: +```csharp +MojangAuth auth = new MojangAuth(client, new SessionFileCacheManager("session_file_path.json")); +``` + +### Methods + +#### Authenticate + +```csharp +// using cached client token or create new client token if it was null. +MojangAuthResponse res = await auth.Authenticate("mojang email", "password"); + +// using the specified client token +MojangAuthResponse res = await auth.Authenticate("mojang email", "password", "clientToken"); + +if (res.IsSuccess) +{ + // res.Session +} +else +{ + // res.Result + // res.Error + // res.ErrorMessage +} +``` + +#### TryAutoLogin + +```csharp +// call Validate() and Refersh() using cached session. +MojangAuthResponse res = await auth.TryAutoLogin(); +``` + +#### Refresh + +```csharp +// using cached session +MojangAuthResponse res = await auth.Refresh(); +``` +```csharp +// using the specified session +MojangAuthResponse res = await auth.Refresh(session); +``` + +#### Validate + +```csharp +// using cached session +MojangAuthResponse res = await auth.Validate(); +``` +```csharp +// using the specified session +MojangAuthResponse res = await auth.Validate(session); +``` + +#### Signout + +```csharp +MojangAuthResponse res = await auth.Signout("mojang email", "password"); +``` + +#### Invalidate + +```csharp +// using cached session +MojangAuthResponse res = await auth.Invalidate(); +``` +```csharp +// using the specified session +MojangAuthResponse res = await auth.Invalidate("accessToken", "clientToken"); +``` +*note: 'clientToken' can be null* \ No newline at end of file diff --git a/docs/SecurityQuestion.md b/docs/SecurityQuestion.md new file mode 100644 index 0000000..d3c92da --- /dev/null +++ b/docs/SecurityQuestion.md @@ -0,0 +1,100 @@ +## SecurityQuestion + +`using MojangAPI.SecurityQuestion;` + +This is required to get the skin change endpoint to work in case the services do not trust your IP yet. + +Most methods return `MojangAPIResponse` or class inherited from `MojangAPIResponse`. +You can check whether the request was successful or failed to check `IsSuccess` property in `MojangAPIResponse`. +If `IsSuccess` is false, `Error` and `ErrorMessage` property tell you why the request failed. + +Example: +```csharp +HttpClient httpClient = new HttpClient(); +QuestionFlow questionFlow = new QuestionFlow(httpClient); + +MojangAPIResponse trusted = await questionFlow.CheckTrusted("accessToken"); + +if (trusted.IsSuccess) +{ + Console.WriteLine("Your IP was trusted"); +} +else +{ + QuestionFlowResponse res = await questionFlow.GetQuestionList("accessToken"); + if (!res.IsSuccess) + throw new Exception("failed to get questions"); + + QuestionList questions = res.Questions; + for (int i = 0; i < questions.Count; i++) + { + Question question = questions[i]; + Console.WriteLine($"Q{i + 1}. [{question.QuestionId}] {question.QuestionMessage}"); + Console.Write("Answer? : "); + + var answer = Console.ReadLine(); + question.Answer = answer; + Console.WriteLine(); + } + + MojangAPIResponse answerResponse = await questionFlow.SendAnswers(questions, session.AccessToken); + + if (answerResponse.IsSuccess) + { + Console.WriteLine("Success"); + } + else + { + Console.WriteLine("Failed"); + // answerResponse.Error + // answerResponse.ErrorMessage + } +} +``` + +### Methods (QuestionFlow class) + +#### CheckTrusted + +Check if security questions are needed. + +```csharp +MojangAPIResponse response = await questionFlow.CheckTrusted("accessToken"); +if (response.IsSuccess) +{ + // trusted +} +else +{ + // security questions are needed +} +``` + +#### GetQuestionList + +```csharp +QuestionFlowResponse res = await questionFlow.GetQuestionList("accessToken"); +if (res.IsSuccess) +{ + QuestionList questionList = res.Questions; + foreach (Question q in questionList) + { + // q.QuestionId + // q.QuestionMessage + // q.AnswerId + // q.Answer + } +} +else +{ + // res.Error + // res.ErrorMessage +} +``` + +#### SendAnswers + +```csharp +QuestionList list; // you can get this from GetQuestionsList method, like 'questionList' variable above. +MojangAPIResponse res = await questionFlow.SendAnswers(list, "accessToken"); +``` \ No newline at end of file diff --git a/docs/XboxAuthentication.md b/docs/XboxAuthentication.md new file mode 100644 index 0000000..bb190f6 --- /dev/null +++ b/docs/XboxAuthentication.md @@ -0,0 +1 @@ +writing \ No newline at end of file