diff --git a/Lib_MCPlayerStats.csproj b/Lib_MCPlayerStats.csproj
new file mode 100644
index 0000000..1e968a6
--- /dev/null
+++ b/Lib_MCPlayerStats.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/Lib_MCPlayerStats.sln b/Lib_MCPlayerStats.sln
new file mode 100644
index 0000000..683633e
--- /dev/null
+++ b/Lib_MCPlayerStats.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33205.214
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lib_MCPlayerStats", "Lib_MCPlayerStats.csproj", "{D09C0088-FF5D-42AA-A790-8415AB21E11A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D09C0088-FF5D-42AA-A790-8415AB21E11A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D09C0088-FF5D-42AA-A790-8415AB21E11A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D09C0088-FF5D-42AA-A790-8415AB21E11A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D09C0088-FF5D-42AA-A790-8415AB21E11A}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {5DCEC488-14AC-4868-A2F5-048BB8B934D8}
+ EndGlobalSection
+EndGlobal
diff --git a/MojangApi.cs b/MojangApi.cs
new file mode 100644
index 0000000..905861b
--- /dev/null
+++ b/MojangApi.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lib_MCPlayerStats
+{
+ internal class MojangApi
+ {
+ public string? id;
+ public string? name;
+ public Cape? properties;
+ }
+
+ internal class Cape
+ {
+ public string? name;
+ public string? value;
+ public string? signature;
+ }
+
+
+}
diff --git a/Player_Stats.cs b/Player_Stats.cs
new file mode 100644
index 0000000..5296d79
--- /dev/null
+++ b/Player_Stats.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lib_MCPlayerStats
+{
+ public class Player_Stats
+ {
+ public SortedList? picked_up;
+
+
+ public SortedList? mined;
+
+
+ public SortedList? crafted;
+
+
+ public SortedList? broken;
+
+
+ public SortedList? killed;
+
+
+ public SortedList? dropped;
+
+
+ public SortedList? custom;
+
+
+ public SortedList? used;
+
+
+ public SortedList? killed_by;
+
+ public string? Username;
+
+ }
+}
diff --git a/PlayersStats.cs b/PlayersStats.cs
new file mode 100644
index 0000000..6edc0b0
--- /dev/null
+++ b/PlayersStats.cs
@@ -0,0 +1,103 @@
+using Newtonsoft.Json;
+using System.Text.Json.Serialization;
+
+namespace Lib_MCPlayerStats
+{
+ public class PlayersStats
+ {
+
+
+
+ ///
+ /// Load player Stats from file
+ ///
+ /// File path
+ ///
+ public static Task LoadPlayerAsync(string file)
+ {
+ Player_Stats player = new();
+
+ if (!File.Exists(file))
+ {
+ player.Username = "File not Exist";
+ return Task.FromResult(player); //If Deserialized object is null return empty stats object with ErrorMessage in Username
+ }
+
+ Stats_Internal? loaded = JsonConvert.DeserializeObject(File.ReadAllText(file)); //Desearialize Stats file to internal object
+
+ if (loaded == null)
+ {
+ player.Username = "Deserialized object is null";
+ return Task.FromResult(player); //If Deserialized object is null return empty stats object with ErrorMessage in Username
+ }
+
+ player.Username = GetNameByUUID(file.Split(@"/").Last().Replace("-", "").Replace(".json", ""));
+
+ //Move data from loaded stats to object with username
+ player.picked_up = loaded.stats.picked_up;
+ player.mined = loaded.stats.mined;
+ player.crafted = loaded.stats.crafted;
+ player.broken = loaded.stats.broken;
+ player.killed = loaded.stats.killed;
+ player.dropped = loaded.stats.dropped;
+ player.custom = loaded.stats.custom;
+ player.used = loaded.stats.used;
+ player.killed_by = loaded.stats.killed_by;
+
+ return Task.FromResult(player); //Return object with player Stats
+ }
+
+ ///
+ /// Load all player stats from files in folder
+ ///
+ /// Folder path
+ ///
+ public static async Task> LoadPlayersAsync(string folder)
+ {
+ List stats = new();
+
+ foreach (string file in Directory.GetFiles(folder))
+ {
+ if (file.EndsWith(".json"))
+ {
+ stats.Add(await LoadPlayerAsync(file));
+ }
+ }
+
+ return stats;
+ }
+
+
+ ///
+ /// Get Username from UUID by Mojang Api
+ ///
+ ///
+ ///
+ private static string GetNameByUUID(string UUID)
+ {
+ HttpClient client = new();
+ MojangApi? data = null;
+
+ HttpResponseMessage response = client.GetAsync($"https://sessionserver.mojang.com/session/minecraft/profile/{UUID}").Result;
+
+ if (response.IsSuccessStatusCode)
+ {
+ #pragma warning disable CS8604
+ data = JsonConvert.DeserializeObject(response.Content.ToString());
+ #pragma warning restore CS8604
+ }
+
+ if (data == null)
+ return UUID;
+
+ #pragma warning disable CS8603
+ return data.name;
+ #pragma warning restore CS8603
+
+
+ }
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/Stats_Internal.cs b/Stats_Internal.cs
new file mode 100644
index 0000000..aeef864
--- /dev/null
+++ b/Stats_Internal.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lib_MCPlayerStats
+{
+ internal class Stats_Internal
+ {
+#pragma warning disable CS8618 // Pole, které nemůže být null, musí při ukončování konstruktoru obsahovat hodnotu, která není null. Zvažte možnost deklarovat ho jako pole s možnou hodnotou null.
+ public Stats stats;
+#pragma warning restore CS8618 // Pole, které nemůže být null, musí při ukončování konstruktoru obsahovat hodnotu, která není null. Zvažte možnost deklarovat ho jako pole s možnou hodnotou null.
+
+ public int DataVersion;
+ }
+
+ internal class Stats
+ {
+
+ public SortedList? picked_up;
+
+
+ public SortedList? mined;
+
+
+ public SortedList? crafted;
+
+
+ public SortedList? broken;
+
+
+ public SortedList? killed;
+
+
+ public SortedList? dropped;
+
+
+ public SortedList? custom;
+
+
+ public SortedList? used;
+
+
+ public SortedList? killed_by;
+ }
+
+
+}