From 9740fc8438ec8f14d7d91d741975732d67c0185a Mon Sep 17 00:00:00 2001 From: Anthony Mineo Date: Wed, 13 Oct 2021 13:15:07 -0400 Subject: [PATCH 1/7] v0.1.2 --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index bf59382..4b75b0b 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule T2ServerQuery.MixProject do def project do [ app: :t2_server_query, - version: "0.1.1", + version: "0.1.2", elixir: "~> 1.12", start_permanent: Mix.env() == :prod, deps: deps(), From 916e738ca00496406b8ff57ef0298d2c00976561 Mon Sep 17 00:00:00 2001 From: Anthony Mineo Date: Wed, 13 Apr 2022 14:52:16 -0400 Subject: [PATCH 2/7] feat(query): IPv4 validation handler --- lib/t2_server_query.ex | 17 +++++++++++++++++ test/t2_server_query_test.exs | 29 +++++++++++++++++------------ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/lib/t2_server_query.ex b/lib/t2_server_query.ex index 19e1621..51e9e39 100644 --- a/lib/t2_server_query.ex +++ b/lib/t2_server_query.ex @@ -72,6 +72,14 @@ defmodule T2ServerQuery do """ def query(server_ip, port \\ 28_000, timeout \\ 3_500) do Logger.info "query: #{server_ip}" + case is_valid_ip?(server_ip) do + true -> handle_query(server_ip, port, timeout) + false -> PacketParser.init({:error, "#{server_ip} - Invalid IP" }, nil) + end + end + + + defp handle_query(server_ip, port, timeout) do {:ok, socket} = :gen_udp.open(0, [:binary, {:active, false}]) @@ -99,6 +107,15 @@ defmodule T2ServerQuery do end + defp is_valid_ip?(nil), do: false + defp is_valid_ip?(server_ip) do + case Regex.match?(~r/^([1-2]?[0-9]{1,2}\.){3}([1-2]?[0-9]{1,2})$/, server_ip) do + false -> false + true -> true + end + end + + defp handle_udp_response({:ok, {_ip, port, packet}}, _server_ip, port) do packet |> Base.encode16 diff --git a/test/t2_server_query_test.exs b/test/t2_server_query_test.exs index 2926ce6..66a8880 100644 --- a/test/t2_server_query_test.exs +++ b/test/t2_server_query_test.exs @@ -21,30 +21,35 @@ defmodule T2ServerQueryTest do test "Live test a number of Tribes 2 servers" do tasks = [ Task.async(T2ServerQuery, :query, ["35.239.88.241", 28_000]), - Task.async(T2ServerQuery, :query, ["67.222.138.13"]) + Task.async(T2ServerQuery, :query, ["148.170.171.67"]) ] Task.yield_many(tasks) - |> Enum.map(fn {_task, result} -> - test_server_status(result) + |> Enum.each(fn {_task, result} -> + case result do + {:ok, _ } -> assert true + {:error, _} -> assert false + _ -> assert false + end end) - end - defp test_server_status({:ok, _}) do - assert true - end - defp test_server_status({:error, _}) do - assert false - end - defp test_server_status(nil) do - assert false + + test "Invalid IP" do + {:error, result} = T2ServerQuery.query("fake.ip") + |> T2ServerQuery.log + + assert result.server_status == :offline + assert result.server_name == "fake.ip - Invalid IP" end + end + + #qry_test = T2ServerQuery.query("127.0.0.1") #IO.inspect qry_test From 0c785ccb39ca94aeb1c31c7e9f8aa83d8c0c23a8 Mon Sep 17 00:00:00 2001 From: Anthony Mineo Date: Wed, 13 Apr 2022 15:07:33 -0400 Subject: [PATCH 3/7] chore: Update credo; Add dialyxir --- mix.exs | 6 ++++-- mix.lock | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/mix.exs b/mix.exs index 4b75b0b..9a8af8b 100644 --- a/mix.exs +++ b/mix.exs @@ -32,8 +32,10 @@ defmodule T2ServerQuery.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:credo, "~> 1.5", only: :dev, runtime: false}, - {:ex_doc, "~> 0.24", only: :dev, runtime: false} + {:ex_doc, "~> 0.24", only: :dev, runtime: false}, + # Code quality, style and linting + {:dialyxir, "~> 1.1", only: [:dev], runtime: false}, + {:credo, "~> 1.6", only: [:dev, :test], runtime: false} ] end diff --git a/mix.lock b/mix.lock index 3681bd1..17f51e6 100644 --- a/mix.lock +++ b/mix.lock @@ -1,10 +1,12 @@ %{ "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"}, - "credo": {:hex, :credo, "1.5.6", "e04cc0fdc236fefbb578e0c04bd01a471081616e741d386909e527ac146016c6", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "4b52a3e558bd64e30de62a648518a5ea2b6e3e5d2b164ef5296244753fc7eb17"}, + "credo": {:hex, :credo, "1.6.4", "ddd474afb6e8c240313f3a7b0d025cc3213f0d171879429bf8535d7021d9ad78", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "c28f910b61e1ff829bffa056ef7293a8db50e87f2c57a9b5c3f57eee124536b7"}, + "dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"}, "earmark_parser": {:hex, :earmark_parser, "1.4.16", "607709303e1d4e3e02f1444df0c821529af1c03b8578dfc81bb9cf64553d02b9", [:mix], [], "hexpm", "69fcf696168f5a274dd012e3e305027010658b2d1630cef68421d6baaeaccead"}, + "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, "ex_doc": {:hex, :ex_doc, "0.25.3", "3edf6a0d70a39d2eafde030b8895501b1c93692effcbd21347296c18e47618ce", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "9ebebc2169ec732a38e9e779fd0418c9189b3ca93f4a676c961be6c1527913f5"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, - "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"}, + "jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"}, "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, "makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"}, "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, From a500fea095e3672aff69e2d7e9338338765f70d0 Mon Sep 17 00:00:00 2001 From: Anthony Mineo Date: Wed, 13 Apr 2022 17:37:18 -0400 Subject: [PATCH 4/7] refactor(spec): add type specs --- lib/t2_server_query.ex | 7 ++++--- lib/t2_server_query/packet_parser.ex | 5 ++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/t2_server_query.ex b/lib/t2_server_query.ex index 51e9e39..c729a79 100644 --- a/lib/t2_server_query.ex +++ b/lib/t2_server_query.ex @@ -70,6 +70,7 @@ defmodule T2ServerQuery do }} """ + @spec query(String.t(), integer(), integer()) :: {atom(), %T2ServerQuery.QueryResult{}} def query(server_ip, port \\ 28_000, timeout \\ 3_500) do Logger.info "query: #{server_ip}" case is_valid_ip?(server_ip) do @@ -78,9 +79,8 @@ defmodule T2ServerQuery do end end - + @spec handle_query(String.t(), integer(), integer()) :: {atom(), %T2ServerQuery.QueryResult{}} defp handle_query(server_ip, port, timeout) do - {:ok, socket} = :gen_udp.open(0, [:binary, {:active, false}]) # Convert a string ip from "127.0.0.1" into {127, 0, 0, 1} @@ -106,7 +106,7 @@ defmodule T2ServerQuery do PacketParser.init(hex_info_packet, hex_status_packet) end - + @spec is_valid_ip?(any()) :: boolean() defp is_valid_ip?(nil), do: false defp is_valid_ip?(server_ip) do case Regex.match?(~r/^([1-2]?[0-9]{1,2}\.){3}([1-2]?[0-9]{1,2})$/, server_ip) do @@ -116,6 +116,7 @@ defmodule T2ServerQuery do end + @spec handle_udp_response(tuple(), String.t(), integer()) :: tuple() | String.t() defp handle_udp_response({:ok, {_ip, port, packet}}, _server_ip, port) do packet |> Base.encode16 diff --git a/lib/t2_server_query/packet_parser.ex b/lib/t2_server_query/packet_parser.ex index 37a0cf0..4519389 100644 --- a/lib/t2_server_query/packet_parser.ex +++ b/lib/t2_server_query/packet_parser.ex @@ -43,9 +43,9 @@ defmodule T2ServerQuery.PacketParser do Refer to `T2ServerQuery.QueryResult` for what a typical struct would look like. - """ + alias T2ServerQuery.QueryResult @doc """ @@ -53,6 +53,7 @@ defmodule T2ServerQuery.PacketParser do Normally you wouldn't need to run this function manually since it's called in a pipeline from the main `T2ServerQuery.query` """ + @spec init({:error, String.t()}, any()) :: {:error, map()} def init({:error, host}, _) do results = %QueryResult{} @@ -65,6 +66,7 @@ defmodule T2ServerQuery.PacketParser do } end + @spec init(binary(), binary()) :: {:ok, %QueryResult{}} def init(info_packet, status_packet) when is_binary(info_packet) and is_binary(status_packet) do info_results = info_packet @@ -81,6 +83,7 @@ defmodule T2ServerQuery.PacketParser do pack_results({:ok, status_results, info_results}) end + @spec pack_results({:ok, map(), map()}) :: {:ok, %QueryResult{}} defp pack_results({:ok, status_results, info_results}) do results = %QueryResult{} From 73920390713f44e7462fdbadf7daf526f3b15cc5 Mon Sep 17 00:00:00 2001 From: Anthony Mineo Date: Wed, 13 Apr 2022 17:48:55 -0400 Subject: [PATCH 5/7] refactor(spec): add type specs --- lib/t2_server_query.ex | 4 ++-- lib/t2_server_query/packet_parser.ex | 4 ++-- lib/t2_server_query/query_result.ex | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/t2_server_query.ex b/lib/t2_server_query.ex index c729a79..77d0da3 100644 --- a/lib/t2_server_query.ex +++ b/lib/t2_server_query.ex @@ -70,7 +70,7 @@ defmodule T2ServerQuery do }} """ - @spec query(String.t(), integer(), integer()) :: {atom(), %T2ServerQuery.QueryResult{}} + @spec query(String.t(), integer(), integer()) :: {atom(), T2ServerQuery.QueryResult.t()} def query(server_ip, port \\ 28_000, timeout \\ 3_500) do Logger.info "query: #{server_ip}" case is_valid_ip?(server_ip) do @@ -79,7 +79,7 @@ defmodule T2ServerQuery do end end - @spec handle_query(String.t(), integer(), integer()) :: {atom(), %T2ServerQuery.QueryResult{}} + @spec handle_query(String.t(), integer(), integer()) :: {atom(), T2ServerQuery.QueryResult.t()} defp handle_query(server_ip, port, timeout) do {:ok, socket} = :gen_udp.open(0, [:binary, {:active, false}]) diff --git a/lib/t2_server_query/packet_parser.ex b/lib/t2_server_query/packet_parser.ex index 4519389..d4bb592 100644 --- a/lib/t2_server_query/packet_parser.ex +++ b/lib/t2_server_query/packet_parser.ex @@ -66,7 +66,7 @@ defmodule T2ServerQuery.PacketParser do } end - @spec init(binary(), binary()) :: {:ok, %QueryResult{}} + @spec init(binary(), binary()) :: {:ok, QueryResult.t()} def init(info_packet, status_packet) when is_binary(info_packet) and is_binary(status_packet) do info_results = info_packet @@ -83,7 +83,7 @@ defmodule T2ServerQuery.PacketParser do pack_results({:ok, status_results, info_results}) end - @spec pack_results({:ok, map(), map()}) :: {:ok, %QueryResult{}} + @spec pack_results({:ok, map(), map()}) :: {:ok, QueryResult.t()} defp pack_results({:ok, status_results, info_results}) do results = %QueryResult{} diff --git a/lib/t2_server_query/query_result.ex b/lib/t2_server_query/query_result.ex index e61dc2c..a7c680b 100644 --- a/lib/t2_server_query/query_result.ex +++ b/lib/t2_server_query/query_result.ex @@ -48,6 +48,21 @@ defmodule T2ServerQuery.QueryResult do } """ + @type t() :: %__MODULE__{ + server_status: atom(), + server_name: String.t(), + game_type: String.t(), + mission_type: String.t(), + map_name: String.t(), + player_count: integer(), + max_player_count: integer(), + bot_count: integer(), + server_description: String.t(), + team_count: integer(), + teams: list(), + players: list() + } + defstruct [ server_status: :offline, server_name: "", From 0c88b6806883145c34525c347209add53399e3fd Mon Sep 17 00:00:00 2001 From: Anthony Mineo Date: Wed, 13 Apr 2022 17:53:00 -0400 Subject: [PATCH 6/7] ci: run dialyzer --- .github/workflows/elixir.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index c4c6951..53724cf 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -29,5 +29,7 @@ jobs: run: mix deps.get - name: Run tests run: mix test + - name: Static Code Analysis - Dialyzer + run: mix dialyzer - name: Static Code Analysis - Credo run: mix credo From 84e923852b57d0225a8859fb39265b88048a27eb Mon Sep 17 00:00:00 2001 From: Anthony Mineo Date: Wed, 13 Apr 2022 17:53:56 -0400 Subject: [PATCH 7/7] v0.1.3 --- README.md | 2 +- lib/t2_server_query.ex | 2 +- mix.exs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7536e45..a3154ed 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ The package can be installed by adding `t2_server_query` to your list of depende ```elixir def deps do [ - {:t2_server_query, "~> 0.1.2"} + {:t2_server_query, "~> 0.1.3"} ] end ``` diff --git a/lib/t2_server_query.ex b/lib/t2_server_query.ex index 77d0da3..227a2a4 100644 --- a/lib/t2_server_query.ex +++ b/lib/t2_server_query.ex @@ -9,7 +9,7 @@ defmodule T2ServerQuery do ## Installation def deps do [ - {:t2_server_query, "~> 0.1.2"} + {:t2_server_query, "~> 0.1.3"} ] end diff --git a/mix.exs b/mix.exs index 9a8af8b..b222f9f 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule T2ServerQuery.MixProject do def project do [ app: :t2_server_query, - version: "0.1.2", + version: "0.1.3", elixir: "~> 1.12", start_permanent: Mix.env() == :prod, deps: deps(),