mirror of
https://github.com/amineo/t2_server_query_elixir.git
synced 2026-02-13 11:43:38 +00:00
Compare commits
7 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84e923852b | ||
|
|
0c88b68068 | ||
|
|
7392039071 | ||
|
|
a500fea095 | ||
|
|
0c785ccb39 | ||
|
|
916e738ca0 | ||
|
|
9740fc8438 |
8 changed files with 67 additions and 20 deletions
2
.github/workflows/elixir.yml
vendored
2
.github/workflows/elixir.yml
vendored
|
|
@ -29,5 +29,7 @@ jobs:
|
||||||
run: mix deps.get
|
run: mix deps.get
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: mix test
|
run: mix test
|
||||||
|
- name: Static Code Analysis - Dialyzer
|
||||||
|
run: mix dialyzer
|
||||||
- name: Static Code Analysis - Credo
|
- name: Static Code Analysis - Credo
|
||||||
run: mix credo
|
run: mix credo
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ The package can be installed by adding `t2_server_query` to your list of depende
|
||||||
```elixir
|
```elixir
|
||||||
def deps do
|
def deps do
|
||||||
[
|
[
|
||||||
{:t2_server_query, "~> 0.1.2"}
|
{:t2_server_query, "~> 0.1.3"}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ defmodule T2ServerQuery do
|
||||||
## Installation
|
## Installation
|
||||||
def deps do
|
def deps do
|
||||||
[
|
[
|
||||||
{:t2_server_query, "~> 0.1.2"}
|
{:t2_server_query, "~> 0.1.3"}
|
||||||
]
|
]
|
||||||
end
|
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
|
def query(server_ip, port \\ 28_000, timeout \\ 3_500) do
|
||||||
Logger.info "query: #{server_ip}"
|
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}])
|
{:ok, socket} = :gen_udp.open(0, [:binary, {:active, false}])
|
||||||
|
|
||||||
# Convert a string ip from "127.0.0.1" into {127, 0, 0, 1}
|
# 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)
|
PacketParser.init(hex_info_packet, hex_status_packet)
|
||||||
end
|
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
|
defp handle_udp_response({:ok, {_ip, port, packet}}, _server_ip, port) do
|
||||||
packet
|
packet
|
||||||
|> Base.encode16
|
|> Base.encode16
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,9 @@ defmodule T2ServerQuery.PacketParser do
|
||||||
|
|
||||||
Refer to `T2ServerQuery.QueryResult` for what a typical struct would look like.
|
Refer to `T2ServerQuery.QueryResult` for what a typical struct would look like.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
alias T2ServerQuery.QueryResult
|
alias T2ServerQuery.QueryResult
|
||||||
|
|
||||||
@doc """
|
@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`
|
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
|
def init({:error, host}, _) do
|
||||||
results = %QueryResult{}
|
results = %QueryResult{}
|
||||||
|
|
||||||
|
|
@ -65,6 +66,7 @@ defmodule T2ServerQuery.PacketParser do
|
||||||
}
|
}
|
||||||
end
|
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
|
def init(info_packet, status_packet) when is_binary(info_packet) and is_binary(status_packet) do
|
||||||
|
|
||||||
info_results = info_packet
|
info_results = info_packet
|
||||||
|
|
@ -81,6 +83,7 @@ defmodule T2ServerQuery.PacketParser do
|
||||||
pack_results({:ok, status_results, info_results})
|
pack_results({:ok, status_results, info_results})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec pack_results({:ok, map(), map()}) :: {:ok, QueryResult.t()}
|
||||||
defp pack_results({:ok, status_results, info_results}) do
|
defp pack_results({:ok, status_results, info_results}) do
|
||||||
results = %QueryResult{}
|
results = %QueryResult{}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 [
|
defstruct [
|
||||||
server_status: :offline,
|
server_status: :offline,
|
||||||
server_name: "",
|
server_name: "",
|
||||||
|
|
|
||||||
8
mix.exs
8
mix.exs
|
|
@ -4,7 +4,7 @@ defmodule T2ServerQuery.MixProject do
|
||||||
def project do
|
def project do
|
||||||
[
|
[
|
||||||
app: :t2_server_query,
|
app: :t2_server_query,
|
||||||
version: "0.1.1",
|
version: "0.1.3",
|
||||||
elixir: "~> 1.12",
|
elixir: "~> 1.12",
|
||||||
start_permanent: Mix.env() == :prod,
|
start_permanent: Mix.env() == :prod,
|
||||||
deps: deps(),
|
deps: deps(),
|
||||||
|
|
@ -32,8 +32,10 @@ defmodule T2ServerQuery.MixProject do
|
||||||
# Run "mix help deps" to learn about dependencies.
|
# Run "mix help deps" to learn about dependencies.
|
||||||
defp deps do
|
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
|
end
|
||||||
|
|
||||||
|
|
|
||||||
6
mix.lock
6
mix.lock
|
|
@ -1,10 +1,12 @@
|
||||||
%{
|
%{
|
||||||
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
|
"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"},
|
"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"},
|
"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"},
|
"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": {: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_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"},
|
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
|
||||||
|
|
|
||||||
|
|
@ -21,30 +21,35 @@ defmodule T2ServerQueryTest do
|
||||||
test "Live test a number of Tribes 2 servers" do
|
test "Live test a number of Tribes 2 servers" do
|
||||||
tasks = [
|
tasks = [
|
||||||
Task.async(T2ServerQuery, :query, ["35.239.88.241", 28_000]),
|
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)
|
Task.yield_many(tasks)
|
||||||
|> Enum.map(fn {_task, result} ->
|
|> Enum.each(fn {_task, result} ->
|
||||||
test_server_status(result)
|
case result do
|
||||||
|
{:ok, _ } -> assert true
|
||||||
|
{:error, _} -> assert false
|
||||||
|
_ -> assert false
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp test_server_status({:ok, _}) do
|
|
||||||
assert true
|
test "Invalid IP" do
|
||||||
end
|
{:error, result} = T2ServerQuery.query("fake.ip")
|
||||||
defp test_server_status({:error, _}) do
|
|> T2ServerQuery.log
|
||||||
assert false
|
|
||||||
end
|
assert result.server_status == :offline
|
||||||
defp test_server_status(nil) do
|
assert result.server_name == "fake.ip - Invalid IP"
|
||||||
assert false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#qry_test = T2ServerQuery.query("127.0.0.1")
|
#qry_test = T2ServerQuery.query("127.0.0.1")
|
||||||
#IO.inspect qry_test
|
#IO.inspect qry_test
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue