From 8428b5b5a387172f5b34b6c0ac0f6a3ba78b1591 Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 12 Apr 2024 13:54:03 +0200 Subject: [PATCH] Implement compression for advertisements --- lib/compression/domain.ml | 2 +- lib/dune | 2 +- lib/models/stub/advertisement.ml | 3 ++ lib/models/stub/slot.ml | 34 +++++++++++++++ lib/models/stub/slot_info.ml | 20 +++++++++ tests/unit/res/findAdvertisements.json | 4 +- tests/unit/test.ml | 58 +++++++++++--------------- 7 files changed, 86 insertions(+), 37 deletions(-) create mode 100644 lib/models/stub/slot.ml create mode 100644 lib/models/stub/slot_info.ml diff --git a/lib/compression/domain.ml b/lib/compression/domain.ml index 64c1a07..b635adf 100644 --- a/lib/compression/domain.ml +++ b/lib/compression/domain.ml @@ -1,4 +1,4 @@ -let decompress_base64 ?(buffer_size_factor = 12) base64_str = +let decompress_base64_str ?(buffer_size_factor = 12) base64_str = let compressed_data = Base64.decode_exn base64_str in let compressed_len = String.length compressed_data in let compressed_ba = Bigarray.Array1.create Bigarray.char Bigarray.c_layout compressed_len in diff --git a/lib/dune b/lib/dune index 8dd29a2..a1484fb 100644 --- a/lib/dune +++ b/lib/dune @@ -4,7 +4,7 @@ (name relic_sdk) (public_name relic-sdk) (flags :standard -safe-string) - (libraries yojson cohttp-lwt-unix bigarray base64) + (libraries yojson cohttp-lwt-unix bigarray base64 str) (foreign_stubs (language c) (names zlib_stubs) diff --git a/lib/models/stub/advertisement.ml b/lib/models/stub/advertisement.ml index e7beddb..1334384 100644 --- a/lib/models/stub/advertisement.ml +++ b/lib/models/stub/advertisement.ml @@ -11,6 +11,7 @@ type t = ; options : string ; passwordprotected : int ; maxplayers : int + ; slotinfo : Slot_info.t option ; matchtype_id : int ; matchmembers : Match_member.t list ; observernum : int @@ -36,6 +37,7 @@ let to_json a = ; "options", `String a.options ; "passwordprotected", `Int a.passwordprotected ; "maxplayers", `Int a.maxplayers + ; "slotinfo", `String "" (* TODO: Compress the dict into a b64 zlib string again *) ; "matchtype_id", `Int a.matchtype_id ; "matchmembers", `List (List.map Match_member.to_json a.matchmembers) ; "observernum", `Int a.observernum @@ -61,6 +63,7 @@ let from_json json = ; options = Yojson.Basic.Util.(json |> member "options" |> to_string) ; passwordprotected = Yojson.Basic.Util.(json |> member "passwordprotected" |> to_int) ; maxplayers = Yojson.Basic.Util.(json |> member "maxplayers" |> to_int) + ; slotinfo = Yojson.Basic.Util.(json |> member "slotinfo" |> to_string |> Slot_info.from_zlib_b64_str) ; matchtype_id = Yojson.Basic.Util.(json |> member "matchtype_id" |> to_int) ; matchmembers = Yojson.Basic.Util.(json |> member "matchmembers" |> to_list |> List.map Match_member.from_json) ; observernum = Yojson.Basic.Util.(json |> member "observernum" |> to_int) diff --git a/lib/models/stub/slot.ml b/lib/models/stub/slot.ml new file mode 100644 index 0000000..9e62484 --- /dev/null +++ b/lib/models/stub/slot.ml @@ -0,0 +1,34 @@ +type t = + { profile_id : int + ; station_id : int + ; team_id : int + ; faction_id : int + ; race_id : int + ; rank_level : int + ; rank_match_type_id : int + ; time_per_frame_ms : int + ; is_ready : bool + ; status : int + ; metadata : string + } + +let from_json json = + let open Yojson.Basic.Util in + { profile_id = json |> member "profileInfo.id" |> to_int + ; station_id = json |> member "stationID" |> to_int + ; team_id = json |> member "teamID" |> to_int + ; faction_id = json |> member "factionID" |> to_int + ; race_id = json |> member "raceID" |> to_int + ; rank_level = json |> member "rankLevel" |> to_int + ; rank_match_type_id = json |> member "rankMatchTypeID" |> to_int + ; time_per_frame_ms = json |> member "timePerFrameMS" |> to_int + ; is_ready = json |> member "isReady" |> to_bool + ; status = json |> member "status" |> to_int + ; metadata = json |> member "metaData" |> to_string + } +;; + +let to_json = + (* TODO we need to re-encode and compress *) + "" +;; diff --git a/lib/models/stub/slot_info.ml b/lib/models/stub/slot_info.ml new file mode 100644 index 0000000..5d6735d --- /dev/null +++ b/lib/models/stub/slot_info.ml @@ -0,0 +1,20 @@ +type t = + { id : int + ; slots : Slot.t list + } + +let from_zlib_b64_str compressed_input = + let open Yojson.Basic.Util in + match Compression.Domain.decompress_base64_str compressed_input with + | None -> None + | Some input -> + (try + match Str.split (Str.regexp ",") input with + | id_str :: json_array_str :: _ -> + let id = int_of_string id_str in + let json_list = Yojson.Basic.from_string json_array_str |> to_list in + Some { id; slots = List.map Slot.from_json json_list } + | _ -> None + with + | _ -> None) +;; diff --git a/tests/unit/res/findAdvertisements.json b/tests/unit/res/findAdvertisements.json index 6370ccd..0db23f6 100644 --- a/tests/unit/res/findAdvertisements.json +++ b/tests/unit/res/findAdvertisements.json @@ -17,7 +17,7 @@ "options": "options-string-1", "passwordprotected": 0, "maxplayers": 8, - "slotinfo": "slot-info-1", + "slotinfo": "eNrtk1FvmzAQx/dZ/EwqDKFTI+2FBqdkgwQHm8G0BxcchdiQDFiXdNp3L3baalHVhypSpUp5urv/nXynn/yHlvHjL9g2m2UpuV8vNxdlAUa2fWU7QwO0HevKTe2PwQgaoOOsUqlpgCXLnxp91bCcP6e1+MbvuHyuAtblq3i/1RMD9UxZ8TlvUMMqHiz0XNlizoq93qJ2/m61XPGOjVnHwAj4YupigtyIoGGUFCp6+HvhEq1hd2Hq3gx7AsYCN4FwLhcxnREBlX5NkdjTmmaJt/2TrtF1DmV6O9mtmbWDiSiS0Avrfs7FCDkxxDgkzq/UlnOKKFJ6RLMbWq1KQqh6zw1K/wv4Z7xEN4BH2Ab/cYNH3FTnCdwhP4mc+To55M5js3zrtdaHutb+UNcO3+la63UPSR29JEYz6pn3ET3UEen0/+49NO094LH76YyL3lNyGmofSJwFMoMJXX3NJ/4uqsMsmeza1Oragm5v6BqPM+1FjDm5IqT3IKtC5Sn6uDvBMNukEh18Fftvpuec6Z1A7/JM7wR6n8/0juj9/PQAqnuYZg==", "matchtype_id": 1, "matchmembers": [ { @@ -50,7 +50,7 @@ "options": "options-string-2", "passwordprotected": 0, "maxplayers": 8, - "slotinfo": "slot-info-2", + "slotinfo": "eNrtk1FvmzAQx/dZ/EwqDKFTI+2FBqdkgwQHm8G0BxcchdiQDFiXdNp3L3baalHVhypSpUp5urv/nXynn/yHlvHjL9g2m2UpuV8vNxdlAUa2fWU7QwO0HevKTe2PwQgaoOOsUqlpgCXLnxp91bCcP6e1+MbvuHyuAtblq3i/1RMD9UxZ8TlvUMMqHiz0XNlizoq93qJ2/m61XPGOjVnHwAj4YupigtyIoGGUFCp6+HvhEq1hd2Hq3gx7AsYCN4FwLhcxnREBlX5NkdjTmmaJt/2TrtF1DmV6O9mtmbWDiSiS0Avrfs7FCDkxxDgkzq/UlnOKKFJ6RLMbWq1KQqh6zw1K/wv4Z7xEN4BH2Ab/cYNH3FTnCdwhP4mc+To55M5js3zrtdaHutb+UNcO3+la63UPSR29JEYz6pn3ET3UEen0/+49NO094LH76YyL3lNyGmofSJwFMoMJXX3NJ/4uqsMsmeza1Oragm5v6BqPM+1FjDm5IqT3IKtC5Sn6uDvBMNukEh18Fftvpuec6Z1A7/JM7wR6n8/0juj9/PQAqnuYZg==", "matchtype_id": 1, "matchmembers": [ { diff --git a/tests/unit/test.ml b/tests/unit/test.ml index b45a6f2..3f86386 100644 --- a/tests/unit/test.ml +++ b/tests/unit/test.ml @@ -1,35 +1,27 @@ let () = - let x = - Relic_sdk.Compression.Domain.decompress_base64 - "eNrVkF1PwjAUhv0tvR6GMjYniTeDVWfcgLJ2gvGibl0o3QduEyHG/y6dgUiMF8YLs6uevufknCcP7GkPb2BdFolIuZsnxbmIwcCyTN0yLzVQ1awWRe6OwABqoOYsU2VXAwmLDo39r2QRP5a5vOMbnh5/HqujZbBbNxMdtUZkfMJLVLKMe7NmTlSYs3jXXFE3X6omznjNRqxmYABceWtjguwpQf1pGKvXCe6XNmkybM+6TW+MHQkDiUtPGuYsoGMiocqHFMkdzekidNav8xUaRjCdP11vV6y3haGMQ9/x8/2cjREyAoixT4znuZ5OKKJI5VO6uKHZUhBC1T7bE+4VeNe+u+vAE22dL97giTfVOYj7rP9krvuTud9S9lpBqbeCst8KSqMVlGYrKC/+ifLx7APyMc1P" - in - match x with - | Some data -> Printf.printf "Decompressed data: %s\n" data - | None -> - Printf.printf "Decompression failed.\n"; - Lwt_main.run - @@ Alcotest_lwt.run - "Relic SDK" - [ ( "api" - , [ Alcotest_lwt.test_case "/community/advertisement/findAdvertisements" `Quick (fun _ () -> - Test_cases.Api.test_get_advertisements ()) - ; Alcotest_lwt.test_case "/community/news/getNews" `Quick (fun _ () -> Test_cases.Api.test_get_news ()) - ; Alcotest_lwt.test_case "/community/achievement/getAchievements" `Quick (fun _ () -> - Test_cases.Api.test_get_achievements ()) - ; Alcotest_lwt.test_case "/community/achievement/getAvailableAchievements" `Quick (fun _ () -> - Test_cases.Api.test_get_available_achievements ()) - ; Alcotest_lwt.test_case "/community/clan/find" `Quick (fun _ () -> Test_cases.Api.test_find_clans ()) - ; Alcotest_lwt.test_case "/community/clan/getClanInfoFull" `Quick (fun _ () -> - Test_cases.Api.test_get_clan_info ()) - ; Alcotest_lwt.test_case "/community/CommunityEvent/getAvailableCommunityEvents" `Quick (fun _ () -> - Test_cases.Api.test_get_community_events ()) - ; Alcotest_lwt.test_case "/community/leaderboard/GetAvailableLeaderboards" `Quick (fun _ () -> - Test_cases.Api.test_get_leaderboards ()) - ; Alcotest_lwt.test_case "/community/leaderboard/GetAvatarStatForProfile" `Quick (fun _ () -> - Test_cases.Api.test_get_avatar_stat ()) - ; Alcotest_lwt.test_case "/community/leaderboard/getLeaderBoard2.json" `Quick (fun _ () -> - Test_cases.Api.test_get_leaderboard2 ()) - ; Alcotest_lwt.test_case "invalid json" `Quick (fun _ () -> Test_cases.Api.test_invalid ()) - ] ) - ] + Lwt_main.run + @@ Alcotest_lwt.run + "Relic SDK" + [ ( "api" + , [ Alcotest_lwt.test_case "/community/advertisement/findAdvertisements" `Quick (fun _ () -> + Test_cases.Api.test_get_advertisements ()) + ; Alcotest_lwt.test_case "/community/news/getNews" `Quick (fun _ () -> Test_cases.Api.test_get_news ()) + ; Alcotest_lwt.test_case "/community/achievement/getAchievements" `Quick (fun _ () -> + Test_cases.Api.test_get_achievements ()) + ; Alcotest_lwt.test_case "/community/achievement/getAvailableAchievements" `Quick (fun _ () -> + Test_cases.Api.test_get_available_achievements ()) + ; Alcotest_lwt.test_case "/community/clan/find" `Quick (fun _ () -> Test_cases.Api.test_find_clans ()) + ; Alcotest_lwt.test_case "/community/clan/getClanInfoFull" `Quick (fun _ () -> + Test_cases.Api.test_get_clan_info ()) + ; Alcotest_lwt.test_case "/community/CommunityEvent/getAvailableCommunityEvents" `Quick (fun _ () -> + Test_cases.Api.test_get_community_events ()) + ; Alcotest_lwt.test_case "/community/leaderboard/GetAvailableLeaderboards" `Quick (fun _ () -> + Test_cases.Api.test_get_leaderboards ()) + ; Alcotest_lwt.test_case "/community/leaderboard/GetAvatarStatForProfile" `Quick (fun _ () -> + Test_cases.Api.test_get_avatar_stat ()) + ; Alcotest_lwt.test_case "/community/leaderboard/getLeaderBoard2.json" `Quick (fun _ () -> + Test_cases.Api.test_get_leaderboard2 ()) + ; Alcotest_lwt.test_case "invalid json" `Quick (fun _ () -> Test_cases.Api.test_invalid ()) + ] ) + ] ;;