Compare commits

...

7 commits

Author SHA1 Message Date
Anthony Mineo
84e923852b v0.1.3 2022-04-13 17:53:56 -04:00
Anthony Mineo
0c88b68068 ci: run dialyzer 2022-04-13 17:53:00 -04:00
Anthony Mineo
7392039071 refactor(spec): add type specs 2022-04-13 17:48:55 -04:00
Anthony Mineo
a500fea095 refactor(spec): add type specs 2022-04-13 17:37:18 -04:00
Anthony Mineo
0c785ccb39 chore: Update credo; Add dialyxir 2022-04-13 15:07:33 -04:00
Anthony Mineo
916e738ca0 feat(query): IPv4 validation handler 2022-04-13 14:52:16 -04:00
Anthony Mineo
9740fc8438 v0.1.2 2021-10-13 13:15:07 -04:00
8 changed files with 67 additions and 20 deletions

View file

@ -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

View file

@ -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
```

View file

@ -9,7 +9,7 @@ defmodule T2ServerQuery do
## Installation
def deps do
[
{:t2_server_query, "~> 0.1.2"}
{:t2_server_query, "~> 0.1.3"}
]
end
@ -70,9 +70,17 @@ defmodule T2ServerQuery do
}}
"""
@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
true -> handle_query(server_ip, port, timeout)
false -> PacketParser.init({:error, "#{server_ip} - Invalid IP" }, nil)
end
end
@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}])
# Convert a string ip from "127.0.0.1" into {127, 0, 0, 1}
@ -98,7 +106,17 @@ 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
false -> false
true -> true
end
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

View file

@ -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.t()}
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.t()}
defp pack_results({:ok, status_results, info_results}) do
results = %QueryResult{}

View file

@ -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: "",

View file

@ -4,7 +4,7 @@ defmodule T2ServerQuery.MixProject do
def project do
[
app: :t2_server_query,
version: "0.1.1",
version: "0.1.3",
elixir: "~> 1.12",
start_permanent: Mix.env() == :prod,
deps: deps(),
@ -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

View file

@ -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"},

View file

@ -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