From 03c0103212338b76ce9cdc2dd56f459c789d24c1 Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 12 Apr 2024 14:09:14 +0200 Subject: [PATCH] Add advertisement options --- lib/compression/domain.ml | 38 ++++++++++++++---------- lib/models/stub/advertisement.ml | 6 ++-- lib/models/stub/advertisement_options.ml | 20 +++++++++++++ tests/unit/res/findAdvertisements.json | 4 +-- 4 files changed, 47 insertions(+), 21 deletions(-) create mode 100644 lib/models/stub/advertisement_options.ml diff --git a/lib/compression/domain.ml b/lib/compression/domain.ml index b635adf..db3e7bf 100644 --- a/lib/compression/domain.ml +++ b/lib/compression/domain.ml @@ -1,30 +1,36 @@ -let decompress_base64_str ?(buffer_size_factor = 12) base64_str = +open Bigarray + +let decode_base64_exn 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 + let compressed_ba = Array1.create char c_layout compressed_len in for i = 0 to compressed_len - 1 do - Bigarray.Array1.set compressed_ba i compressed_data.[i] + Array1.set compressed_ba i compressed_data.[i] done; + compressed_ba, compressed_len +;; + +let decompress_base64_str ?(buffer_size_factor = 12) base64_str = + let compressed_ba, compressed_len = decode_base64_exn base64_str in let inflate_state = Zlib.create_inflate () in - inflate_state.Zlib.in_buf <- compressed_ba; - inflate_state.Zlib.in_len <- compressed_len; + inflate_state.in_buf <- compressed_ba; + inflate_state.in_len <- compressed_len; let output_len = compressed_len * buffer_size_factor in - let output_ba = Bigarray.Array1.create Bigarray.char Bigarray.c_layout output_len in - inflate_state.Zlib.out_buf <- output_ba; - inflate_state.Zlib.out_len <- output_len; - let status = Zlib.flate inflate_state Zlib.Finish in + let output_ba = Array1.create char c_layout output_len in + inflate_state.out_buf <- output_ba; + inflate_state.out_len <- output_len; + let status = Zlib.flate inflate_state Finish in match status with - | Zlib.Ok | Zlib.Stream_end -> - let result_len = output_len - inflate_state.Zlib.out_len in - let result = String.init result_len (fun i -> Bigarray.Array1.get output_ba i) in - Some result - | Zlib.Need_dict -> + | Ok | Stream_end -> + let result_len = output_len - inflate_state.out_len in + Some (String.init result_len (fun i -> Array1.get output_ba i)) + | Need_dict -> Printf.eprintf "Decompression error: Need dictionary\n"; None - | Zlib.Buf_error -> + | Buf_error -> Printf.eprintf "Decompression error: Buffer error\n"; None - | Zlib.Data_error msg -> + | Data_error msg -> Printf.eprintf "Decompression error: Data error (%s)\n" msg; None ;; diff --git a/lib/models/stub/advertisement.ml b/lib/models/stub/advertisement.ml index 1334384..e656a09 100644 --- a/lib/models/stub/advertisement.ml +++ b/lib/models/stub/advertisement.ml @@ -8,7 +8,7 @@ type t = ; description : string ; visible : int ; mapname : string - ; options : string + ; options : Advertisement_options.t option ; passwordprotected : int ; maxplayers : int ; slotinfo : Slot_info.t option @@ -34,7 +34,7 @@ let to_json a = ; "description", `String a.description ; "visible", `Int a.visible ; "mapname", `String a.mapname - ; "options", `String a.options + ; "options", `String "" (* TODO: Compress the list again *) ; "passwordprotected", `Int a.passwordprotected ; "maxplayers", `Int a.maxplayers ; "slotinfo", `String "" (* TODO: Compress the dict into a b64 zlib string again *) @@ -60,7 +60,7 @@ let from_json json = ; description = Yojson.Basic.Util.(json |> member "description" |> to_string) ; visible = Yojson.Basic.Util.(json |> member "visible" |> to_int) ; mapname = Yojson.Basic.Util.(json |> member "mapname" |> to_string) - ; options = Yojson.Basic.Util.(json |> member "options" |> to_string) + ; options = Yojson.Basic.Util.(json |> member "options" |> to_string |> Advertisement_options.from_zlib_b64_str) ; 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) diff --git a/lib/models/stub/advertisement_options.ml b/lib/models/stub/advertisement_options.ml new file mode 100644 index 0000000..704a762 --- /dev/null +++ b/lib/models/stub/advertisement_options.ml @@ -0,0 +1,20 @@ +type t = string list + +let from_zlib_b64_str compressed_input = + match Compression.Domain.decompress_base64_str compressed_input with + | None -> + Printf.printf "Decompression failed: Input may be corrupted or invalid.\n"; + None + | Some input -> + (try + let no_quotes = String.concat "" (String.split_on_char '"' input) in + match Base64.decode no_quotes with + | Ok decoded_data -> Some (String.split_on_char ':' decoded_data) + | Error _ -> + Printf.printf "Base64 decoding failed: Data may be corrupted or improperly encoded.\n"; + None + with + | ex -> + Printf.printf "Unexpected error: %s\n" (Printexc.to_string ex); + None) +;; diff --git a/tests/unit/res/findAdvertisements.json b/tests/unit/res/findAdvertisements.json index 0db23f6..d92cd05 100644 --- a/tests/unit/res/findAdvertisements.json +++ b/tests/unit/res/findAdvertisements.json @@ -14,7 +14,7 @@ "description": "Test match 1", "visible": 1, "mapname": "test map", - "options": "options-string-1", + "options": "eNpFUs1ugzAMfpc+ARSItGOq0C0HJ0oXNtFj6YQWttJDJyhPPydOACmSJdufvx9277zh+O3Bjg8w4OtJO1n7QjnJLn3oV+DGBXjoz/q3DH0tOvZlDO2LcTr4SjSVdjz2B9wPO5l2zSVgWskaezXXt7FoPucHiDPrbid3+jmWKvuoz0v2wqeAw4C45citgInuKHH/ozvDfuOxzlYq6AizpXL36mACVqldndNey9TSisBlWTnvN83Nqmnb7xk4MxGvAW/1wQfUjK8vNDfkkcej+Ux/Z3Osl1DT7QJ5xDs9U/GOtmPk1qH39ZG41QwsDzWgZ8qSp2CBgQlaZyXQF95SbZGLa+JMy6IHM2osCbv2HkjClh57ApEwvaYw//SaiLectWujP/KJ/hAXB0w5/ko4yMXKPM5jxjLN50kHOPQ7eguuYzHHArmXhz7MIq9mivcX9Dzm2+X6NlC+tsb/KPbXzIZizWxpU2a5smnfzKmvLU/7hVowU8IvE76yXdJfaL9PuU1bbv2cctNCJm8rLe7V7h916PiS", "passwordprotected": 0, "maxplayers": 8, "slotinfo": "eNrtk1FvmzAQx/dZ/EwqDKFTI+2FBqdkgwQHm8G0BxcchdiQDFiXdNp3L3baalHVhypSpUp5urv/nXynn/yHlvHjL9g2m2UpuV8vNxdlAUa2fWU7QwO0HevKTe2PwQgaoOOsUqlpgCXLnxp91bCcP6e1+MbvuHyuAtblq3i/1RMD9UxZ8TlvUMMqHiz0XNlizoq93qJ2/m61XPGOjVnHwAj4YupigtyIoGGUFCp6+HvhEq1hd2Hq3gx7AsYCN4FwLhcxnREBlX5NkdjTmmaJt/2TrtF1DmV6O9mtmbWDiSiS0Avrfs7FCDkxxDgkzq/UlnOKKFJ6RLMbWq1KQqh6zw1K/wv4Z7xEN4BH2Ab/cYNH3FTnCdwhP4mc+To55M5js3zrtdaHutb+UNcO3+la63UPSR29JEYz6pn3ET3UEen0/+49NO094LH76YyL3lNyGmofSJwFMoMJXX3NJ/4uqsMsmeza1Oragm5v6BqPM+1FjDm5IqT3IKtC5Sn6uDvBMNukEh18Fftvpuec6Z1A7/JM7wR6n8/0juj9/PQAqnuYZg==", @@ -47,7 +47,7 @@ "description": "Test match 2", "visible": 1, "mapname": "test map 2", - "options": "options-string-2", + "options": "eNpFUs1ugzAMfpc+ARSItGOq0C0HJ0oXNtFj6YQWttJDJyhPPydOACmSJdufvx9277zh+O3Bjg8w4OtJO1n7QjnJLn3oV+DGBXjoz/q3DH0tOvZlDO2LcTr4SjSVdjz2B9wPO5l2zSVgWskaezXXt7FoPucHiDPrbid3+jmWKvuoz0v2wqeAw4C45citgInuKHH/ozvDfuOxzlYq6AizpXL36mACVqldndNey9TSisBlWTnvN83Nqmnb7xk4MxGvAW/1wQfUjK8vNDfkkcej+Ux/Z3Osl1DT7QJ5xDs9U/GOtmPk1qH39ZG41QwsDzWgZ8qSp2CBgQlaZyXQF95SbZGLa+JMy6IHM2osCbv2HkjClh57ApEwvaYw//SaiLectWujP/KJ/hAXB0w5/ko4yMXKPM5jxjLN50kHOPQ7eguuYzHHArmXhz7MIq9mivcX9Dzm2+X6NlC+tsb/KPbXzIZizWxpU2a5smnfzKmvLU/7hVowU8IvE76yXdJfaL9PuU1bbv2cctNCJm8rLe7V7h916PiS", "passwordprotected": 0, "maxplayers": 8, "slotinfo": "eNrtk1FvmzAQx/dZ/EwqDKFTI+2FBqdkgwQHm8G0BxcchdiQDFiXdNp3L3baalHVhypSpUp5urv/nXynn/yHlvHjL9g2m2UpuV8vNxdlAUa2fWU7QwO0HevKTe2PwQgaoOOsUqlpgCXLnxp91bCcP6e1+MbvuHyuAtblq3i/1RMD9UxZ8TlvUMMqHiz0XNlizoq93qJ2/m61XPGOjVnHwAj4YupigtyIoGGUFCp6+HvhEq1hd2Hq3gx7AsYCN4FwLhcxnREBlX5NkdjTmmaJt/2TrtF1DmV6O9mtmbWDiSiS0Avrfs7FCDkxxDgkzq/UlnOKKFJ6RLMbWq1KQqh6zw1K/wv4Z7xEN4BH2Ab/cYNH3FTnCdwhP4mc+To55M5js3zrtdaHutb+UNcO3+la63UPSR29JEYz6pn3ET3UEen0/+49NO094LH76YyL3lNyGmofSJwFMoMJXX3NJ/4uqsMsmeza1Oragm5v6BqPM+1FjDm5IqT3IKtC5Sn6uDvBMNukEh18Fftvpuec6Z1A7/JM7wR6n8/0juj9/PQAqnuYZg==",