From e53262a68a890b98b4da35c52a69349ba6086a95 Mon Sep 17 00:00:00 2001 From: Tim203 Date: Mon, 26 Aug 2024 15:16:01 +0200 Subject: [PATCH] Store skins to better understand what goes wrong --- lib/global_api/application.ex | 2 +- lib/global_api/schema/skin_storage.ex | 9 ++++ lib/global_api/skins/skin_storage.ex | 46 +++++++++++++++++++++ lib/global_api_web/web_socket/web_socket.ex | 8 ++++ mix.exs | 1 + mix.lock | 1 + 6 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 lib/global_api/schema/skin_storage.ex create mode 100644 lib/global_api/skins/skin_storage.ex diff --git a/lib/global_api/application.ex b/lib/global_api/application.ex index 17c314e..d12e8bd 100644 --- a/lib/global_api/application.ex +++ b/lib/global_api/application.ex @@ -9,7 +9,7 @@ defmodule GlobalApi.Application do def start(_type, _args) do children = [ GlobalApi.PromEx, - {GlobalApi.DatabaseQueue, [pool_size: 7]}, + {GlobalApi.DatabaseQueue, [pool_size: 14]}, GlobalApi.SocketManager, GlobalApi.SkinPreQueue, GlobalApi.SkinPreUploader, diff --git a/lib/global_api/schema/skin_storage.ex b/lib/global_api/schema/skin_storage.ex new file mode 100644 index 0000000..e1094f8 --- /dev/null +++ b/lib/global_api/schema/skin_storage.ex @@ -0,0 +1,9 @@ +defmodule GlobalApi.Schema.SkinStorage do + use Ecto.Schema + + schema "skin_storage" do + field :hash, :binary + field :skin, :string + field :code, :integer + end +end diff --git a/lib/global_api/skins/skin_storage.ex b/lib/global_api/skins/skin_storage.ex new file mode 100644 index 0000000..18cef96 --- /dev/null +++ b/lib/global_api/skins/skin_storage.ex @@ -0,0 +1,46 @@ +defmodule GlobalApi.Skins.SkinStorage do + alias GlobalApi.DatabaseQueue + alias GlobalApi.Repo + alias GlobalApi.Schema.SkinStorage, as: Schema + + def store(client_data, convert_code) do + # Keep: SkinImageHeight, SkinImageWidth, SkinResourcePatch, SkinGeometryDataEngineVersion, SkinGeometryData, SkinData, SkinAnimationData, + # PremiumSkin, PersonaSkin, CapeOnClassicSkin, CapeImageWidth, CapeImageHeight, CapeData, ArmSize, AnimatedImageData. + # The other keys will only result in storing duplicate data + final_data = + client_data + |> Jason.decode!() + |> Map.drop([ + :CapeId, + :ClientRandomId, + :CurrentInputMode, + :DefaultInputMode, + :DeviceId, + :DeviceModel, + :DeviceOS, + :GameVersion, + :GuiScale, + :IsEditorMode, + :LanguageCode, + :PersonaPieces, + :PieceTintColors, + :PlatformOfflineId, + :PlatformOnlineId, + :PlayFabId, + :SelfSignedId, + :ServerAddress, + :SkinColor, + :SkinId, + :ThirdPartyName, + :ThirdPartyNameOnly, + :UIProfile + ]) + |> Jason.encode!() + + identifier = Blake2.hash2b(final_data, 32) + + DatabaseQueue.async_fn_call(fn -> + Repo.insert(%Schema{hash: identifier, skin: final_data, code: convert_code}, on_conflict: :nothing) + end) + end +end diff --git a/lib/global_api_web/web_socket/web_socket.ex b/lib/global_api_web/web_socket/web_socket.ex index 19e175a..f1392c3 100644 --- a/lib/global_api_web/web_socket/web_socket.ex +++ b/lib/global_api_web/web_socket/web_socket.ex @@ -106,6 +106,10 @@ defmodule GlobalApiWeb.WebSocket do end end + def store(client_data, convert_code) do + GlobalApi.Skins.SkinStorage.store(client_data) + end + def websocket_handle({:json, %{"chain_data" => chain_data, "client_data" => client_data}}, state) when is_list(chain_data) and is_binary(client_data) do try do @@ -114,24 +118,28 @@ defmodule GlobalApiWeb.WebSocket do {[{:close, @invalid_data}], state} {:invalid_size, extra_data} -> + store(client_data, 0) handle_extra_data(extra_data) send_log_message(state, @info, "received a skin with an invalid skin size") {:ok, state} {:invalid_geometry, extra_data} -> + store(client_data, 1) handle_extra_data(extra_data) send_log_message(state, @info, "received a skin with invalid geometry") {:ok, state} {:invalid_geometry, reason, extra_data} -> + store(client_data, 2) handle_extra_data(extra_data) send_log_message(state, @info, "received a skin with invalid geometry: #{reason}") {:ok, state} {is_steve, png, rgba_hash, minecraft_hash, {xuid, _, _} = extra_data} -> + store(client_data, 3) handle_extra_data(extra_data) # check for cached skin diff --git a/mix.exs b/mix.exs index 7b544e6..0408c90 100644 --- a/mix.exs +++ b/mix.exs @@ -39,6 +39,7 @@ defmodule GlobalApi.MixProject do # Type `mix help deps` for examples and options. defp deps do [ + {:blake2, "~> 1.0.4"}, {:phoenix, "~> 1.6.13"}, {:phoenix_live_reload, "~> 1.3.3", only: :dev}, {:phoenix_live_view, "~> 0.18.1"}, diff --git a/mix.lock b/mix.lock index add74bb..187b2e1 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,6 @@ %{ "artificery": {:hex, :artificery, "0.4.3", "0bc4260f988dcb9dda4b23f9fc3c6c8b99a6220a331534fdf5bf2fd0d4333b02", [:mix], [], "hexpm", "12e95333a30e20884e937abdbefa3e7f5e05609c2ba8cf37b33f000b9ffc0504"}, + "blake2": {:hex, :blake2, "1.0.4", "8263c69a191142922bc2510f1ffc0de0ae96e8c3bd5e2ad3fac7e87aed94c8b1", [:mix], [], "hexpm", "e9f4120d163ba14d86304195e50745fa18483e6ad2be94c864ae449bbdd6a189"}, "cachex": {:hex, :cachex, "3.4.0", "868b2959ea4aeb328c6b60ff66c8d5123c083466ad3c33d3d8b5f142e13101fb", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "370123b1ab4fba4d2965fb18f87fd758325709787c8c5fce35b3fe80645ccbe5"}, "castore": {:hex, :castore, "0.1.18", "deb5b9ab02400561b6f5708f3e7660fc35ca2d51bfc6a940d2f513f89c2975fc", [:mix], [], "hexpm", "61bbaf6452b782ef80b33cdb45701afbcf0a918a45ebe7e73f1130d661e66a06"}, "certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},