mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-05 15:25:34 +00:00
457 lines
13 KiB
Elixir
457 lines
13 KiB
Elixir
defmodule WandererApp.EveDataService do
|
|
@moduledoc """
|
|
Service for loading data from the EVE DB dumps & JSON files
|
|
"""
|
|
|
|
require Logger
|
|
|
|
alias WandererApp.Utils.JSONUtil
|
|
|
|
@eve_db_dump_url "https://www.fuzzwork.co.uk/dump/latest"
|
|
|
|
@dump_file_names [
|
|
"invGroups.csv",
|
|
"invTypes.csv",
|
|
"mapConstellations.csv",
|
|
"mapRegions.csv",
|
|
"mapLocationWormholeClasses.csv",
|
|
"mapSolarSystems.csv",
|
|
"mapSolarSystemJumps.csv"
|
|
]
|
|
|
|
def update_eve_data() do
|
|
download_files()
|
|
|
|
Logger.info("Downloading files finished!")
|
|
|
|
get_db_data()
|
|
|> Ash.bulk_create(WandererApp.Api.MapSolarSystem, :create)
|
|
|
|
Logger.info("MapSolarSystem updated!")
|
|
|
|
get_ship_types_data()
|
|
|> Ash.bulk_create(WandererApp.Api.ShipTypeInfo, :create)
|
|
|
|
Logger.info("ShipTypeInfo updated!")
|
|
|
|
get_solar_system_jumps_data()
|
|
|> Ash.bulk_create(WandererApp.Api.MapSolarSystemJumps, :create)
|
|
|
|
Logger.info("MapSolarSystemJumps updated!")
|
|
end
|
|
|
|
def download_files() do
|
|
tasks =
|
|
@dump_file_names
|
|
|> Enum.map(fn file_name ->
|
|
Task.async(fn ->
|
|
download_file(file_name)
|
|
end)
|
|
end)
|
|
|
|
Task.await_many(tasks, :timer.minutes(1))
|
|
end
|
|
|
|
def download_file(file_name) do
|
|
url = "#{@eve_db_dump_url}/#{file_name}"
|
|
Logger.info("Downloading file from #{url}")
|
|
|
|
download_path = Path.join([:code.priv_dir(:wanderer_app), "repo", "data", file_name])
|
|
|
|
Req.get!(url, raw: true, into: File.stream!(download_path, [:write])).body
|
|
|> Stream.run()
|
|
|
|
Logger.info("File downloaded successfully to #{download_path}")
|
|
|
|
:ok
|
|
end
|
|
|
|
def load_wormhole_types() do
|
|
JSONUtil.read_json("#{:code.priv_dir(:wanderer_app)}/repo/data/wormholes.json")
|
|
|> JSONUtil.map_json(fn row ->
|
|
%{
|
|
id: row["typeID"],
|
|
name: row["name"],
|
|
src: row["src"],
|
|
dest: row["dest"],
|
|
total_mass: row["total_mass"],
|
|
lifetime: row["lifetime"],
|
|
max_mass_per_jump: row["max_mass_per_jump"],
|
|
static: row["static"],
|
|
mass_regen: row["mass_regen"],
|
|
sibling_groups: row["sibling_groups"]
|
|
}
|
|
end)
|
|
end
|
|
|
|
def load_wormhole_classes() do
|
|
JSONUtil.read_json("#{:code.priv_dir(:wanderer_app)}/repo/data/wormholeClasses.json")
|
|
|> JSONUtil.map_json(fn row ->
|
|
%{
|
|
id: row["id"],
|
|
short_name: row["shortName"],
|
|
title: row["title"],
|
|
effect_power: row |> Map.get("effectPower", 0),
|
|
wormhole_class_id: row["wormholeClassID"]
|
|
}
|
|
end)
|
|
end
|
|
|
|
def load_wormhole_systems() do
|
|
JSONUtil.read_json("#{:code.priv_dir(:wanderer_app)}/repo/data/wormholeSystems.json")
|
|
|> JSONUtil.map_json(fn row ->
|
|
%{
|
|
solar_system_id: row["solarSystemID"],
|
|
wanderers: row["wanderers"],
|
|
statics: row["statics"],
|
|
system_name: row["systemName"],
|
|
effect_name: row["effectName"]
|
|
}
|
|
end)
|
|
end
|
|
|
|
def load_effects() do
|
|
JSONUtil.read_json("#{:code.priv_dir(:wanderer_app)}/repo/data/effects.json")
|
|
|> JSONUtil.map_json(fn row ->
|
|
%{
|
|
id: row["name"] |> Slug.slugify(),
|
|
name: row["name"],
|
|
modifiers:
|
|
row["modifiers"]
|
|
|> Enum.map(fn m ->
|
|
%{
|
|
name: m["name"],
|
|
positive: m["positive"],
|
|
power: m["power"]
|
|
}
|
|
end)
|
|
}
|
|
end)
|
|
end
|
|
|
|
def load_triglavian_systems() do
|
|
JSONUtil.read_json("#{:code.priv_dir(:wanderer_app)}/repo/data/triglavianSystems.json")
|
|
|> JSONUtil.map_json(fn row ->
|
|
%{
|
|
solar_system_id: row["solarSystemID"],
|
|
solar_system_name: row["solarSystemName"],
|
|
effect_name: row["effectName"],
|
|
effect_power: row["effectPower"],
|
|
invasion_status: row["invasionStatus"]
|
|
}
|
|
end)
|
|
end
|
|
|
|
def load_wormhole_classes_info() do
|
|
{:ok, data} =
|
|
JSONUtil.read_json("#{:code.priv_dir(:wanderer_app)}/repo/data/wormholeClassesInfo.json")
|
|
|
|
%{
|
|
names: data["names"],
|
|
classes: data["classes"]
|
|
}
|
|
end
|
|
|
|
def load_shattered_constellations() do
|
|
{:ok, data} =
|
|
JSONUtil.read_json(
|
|
"#{:code.priv_dir(:wanderer_app)}/repo/data/shatteredConstellations.json"
|
|
)
|
|
|
|
data
|
|
end
|
|
|
|
def load_map_constellations() do
|
|
WandererApp.Utils.CSVUtil.csv_row_to_table_record(
|
|
"#{:code.priv_dir(:wanderer_app)}/repo/data/mapConstellations.csv",
|
|
fn row ->
|
|
%{
|
|
constellation_id: row["constellationID"] |> Integer.parse() |> elem(0),
|
|
constellation_name: row["constellationName"]
|
|
}
|
|
end
|
|
)
|
|
end
|
|
|
|
def load_map_regions() do
|
|
WandererApp.Utils.CSVUtil.csv_row_to_table_record(
|
|
"#{:code.priv_dir(:wanderer_app)}/repo/data/mapRegions.csv",
|
|
fn row ->
|
|
%{
|
|
region_id: row["regionID"] |> Integer.parse() |> elem(0),
|
|
region_name: row["regionName"]
|
|
}
|
|
end
|
|
)
|
|
end
|
|
|
|
def load_map_location_wormhole_classes() do
|
|
WandererApp.Utils.CSVUtil.csv_row_to_table_record(
|
|
"#{:code.priv_dir(:wanderer_app)}/repo/data/mapLocationWormholeClasses.csv",
|
|
fn row ->
|
|
%{
|
|
location_id: row["locationID"],
|
|
wormhole_class_id: row["wormholeClassID"]
|
|
}
|
|
end
|
|
)
|
|
end
|
|
|
|
def load_inv_groups() do
|
|
WandererApp.Utils.CSVUtil.csv_row_to_table_record(
|
|
"#{:code.priv_dir(:wanderer_app)}/repo/data/invGroups.csv",
|
|
fn row ->
|
|
%{
|
|
group_id: row["groupID"] |> Integer.parse() |> elem(0),
|
|
group_name: row["groupName"],
|
|
category_id: row["categoryID"] |> Integer.parse() |> elem(0)
|
|
}
|
|
end
|
|
)
|
|
end
|
|
|
|
def get_db_data() do
|
|
map_constellations = load_map_constellations()
|
|
map_regions = load_map_regions()
|
|
map_location_wormhole_classes = load_map_location_wormhole_classes()
|
|
wormhole_classes = load_wormhole_classes()
|
|
wormhole_systems = load_wormhole_systems()
|
|
|
|
triglavian_systems = load_triglavian_systems()
|
|
wormhole_classes_info = load_wormhole_classes_info()
|
|
shattered_constellations = load_shattered_constellations()
|
|
|
|
WandererApp.Utils.CSVUtil.csv_row_to_table_record(
|
|
"#{:code.priv_dir(:wanderer_app)}/repo/data/mapSolarSystems.csv",
|
|
fn row ->
|
|
solar_system_id = row["solarSystemID"] |> Integer.parse() |> elem(0)
|
|
region_id = row["regionID"] |> Integer.parse() |> elem(0)
|
|
constellation_id = row["constellationID"] |> Integer.parse() |> elem(0)
|
|
|
|
{:ok, wormhole_class_id} =
|
|
get_wormhole_class_id(
|
|
map_location_wormhole_classes,
|
|
region_id,
|
|
constellation_id,
|
|
solar_system_id
|
|
)
|
|
|
|
{:ok, constellation_name} =
|
|
get_constellation_name(map_constellations, constellation_id)
|
|
|
|
{:ok, region_name} = get_region_name(map_regions, region_id)
|
|
|
|
{:ok, wormhole_class} = get_wormhole_class(wormhole_classes, wormhole_class_id)
|
|
|
|
{:ok, security} = get_security(row["security"])
|
|
|
|
{:ok, class_title} =
|
|
get_class_title(
|
|
wormhole_classes_info,
|
|
wormhole_class_id,
|
|
security,
|
|
wormhole_class
|
|
)
|
|
|
|
is_shattered =
|
|
case Map.get(shattered_constellations, constellation_id |> Integer.to_string()) do
|
|
nil -> false
|
|
_ -> true
|
|
end
|
|
|
|
%{
|
|
effect_power: 0,
|
|
effect_name: "",
|
|
statics: [],
|
|
wandering: [],
|
|
triglavian_invasion_status: "Normal",
|
|
constellation_id: constellation_id,
|
|
region_id: region_id,
|
|
solar_system_id: solar_system_id,
|
|
solar_system_name: row["solarSystemName"],
|
|
solar_system_name_lc: row["solarSystemName"] |> String.downcase(),
|
|
sun_type_id: get_sun_type_id(row["sunTypeID"]),
|
|
constellation_name: constellation_name,
|
|
region_name: region_name,
|
|
security: security,
|
|
system_class: wormhole_class_id,
|
|
class_title: class_title,
|
|
type_description: wormhole_class.title,
|
|
is_shattered: is_shattered
|
|
}
|
|
|> get_wormhole_data(wormhole_systems, solar_system_id, wormhole_class)
|
|
|> get_triglavian_data(triglavian_systems, solar_system_id)
|
|
end
|
|
)
|
|
end
|
|
|
|
def get_ship_types_data() do
|
|
inv_groups = load_inv_groups()
|
|
|
|
ship_type_groups =
|
|
inv_groups
|
|
|> Enum.filter(fn g -> g.category_id == 6 end)
|
|
|> Enum.map(fn g -> g.group_id end)
|
|
|
|
WandererApp.Utils.CSVUtil.csv_row_to_table_record(
|
|
"#{:code.priv_dir(:wanderer_app)}/repo/data/invTypes.csv",
|
|
fn row ->
|
|
group_id = row["groupID"] |> Integer.parse() |> elem(0)
|
|
|
|
inv_group =
|
|
case Enum.find(inv_groups, fn group ->
|
|
group.group_id == group_id
|
|
end) do
|
|
nil -> %{}
|
|
group -> group
|
|
end
|
|
|
|
%{
|
|
type_id: row["typeID"] |> Integer.parse() |> elem(0),
|
|
group_id: group_id,
|
|
name: row["typeName"],
|
|
mass: row["mass"],
|
|
volume: row["volume"],
|
|
capacity: row["capacity"],
|
|
group_name: inv_group.group_name
|
|
}
|
|
end
|
|
)
|
|
|> Enum.filter(fn t -> t.group_id in ship_type_groups end)
|
|
end
|
|
|
|
def get_solar_system_jumps_data() do
|
|
WandererApp.Utils.CSVUtil.csv_row_to_table_record(
|
|
"#{:code.priv_dir(:wanderer_app)}/repo/data/mapSolarSystemJumps.csv",
|
|
fn row ->
|
|
%{
|
|
from_solar_system_id: row["fromSolarSystemID"] |> Integer.parse() |> elem(0),
|
|
to_solar_system_id: row["toSolarSystemID"] |> Integer.parse() |> elem(0)
|
|
}
|
|
end
|
|
)
|
|
end
|
|
|
|
defp get_sun_type_id(sun_type_id) do
|
|
case sun_type_id do
|
|
"None" -> 0
|
|
_ -> sun_type_id |> Integer.parse() |> elem(0)
|
|
end
|
|
end
|
|
|
|
defp get_wormhole_data(default_data, wormhole_systems, solar_system_id, wormhole_class) do
|
|
case Enum.find(wormhole_systems, fn system -> system.solar_system_id == solar_system_id end) do
|
|
nil ->
|
|
default_data
|
|
|
|
wormhole_data ->
|
|
%{
|
|
default_data
|
|
| effect_power: wormhole_class.effect_power,
|
|
effect_name: wormhole_data.effect_name,
|
|
statics: wormhole_data.statics,
|
|
wandering: wormhole_data.wanderers
|
|
}
|
|
end
|
|
end
|
|
|
|
defp get_triglavian_data(default_data, triglavian_systems, solar_system_id) do
|
|
case Enum.find(triglavian_systems, fn system -> system.solar_system_id == solar_system_id end) do
|
|
nil ->
|
|
default_data
|
|
|
|
triglavian_data ->
|
|
%{
|
|
default_data
|
|
| triglavian_invasion_status: triglavian_data.invasion_status,
|
|
effect_name: triglavian_data.effect_name,
|
|
effect_power: triglavian_data.effect_power
|
|
}
|
|
end
|
|
end
|
|
|
|
defp get_security(security) do
|
|
case security do
|
|
nil -> {:ok, ""}
|
|
_ -> {:ok, String.to_float(security) |> get_true_security() |> Float.to_string(decimals: 1)}
|
|
end
|
|
end
|
|
|
|
defp get_true_security(security) when is_float(security) and security > 0.0 and security < 0.05, do: security |> Float.ceil(1)
|
|
|
|
defp get_true_security(security) when is_float(security), do: security |> Float.floor(1)
|
|
|
|
defp get_class_title(wormhole_classes_info, wormhole_class_id, security, wormhole_class) do
|
|
case wormhole_class_id in [
|
|
wormhole_classes_info.names["hs"],
|
|
wormhole_classes_info.names["ls"],
|
|
wormhole_classes_info.names["ns"]
|
|
] do
|
|
true ->
|
|
{:ok, security}
|
|
|
|
_ ->
|
|
{:ok, wormhole_class.short_name}
|
|
end
|
|
end
|
|
|
|
defp get_constellation_name(constellations, constellation_id) do
|
|
case Enum.find(constellations, fn constellation ->
|
|
constellation.constellation_id == constellation_id
|
|
end) do
|
|
nil -> {:ok, ""}
|
|
constellation -> {:ok, constellation.constellation_name}
|
|
end
|
|
end
|
|
|
|
defp get_region_name(regions, region_id) do
|
|
case Enum.find(regions, fn region -> region.region_id == region_id end) do
|
|
nil -> {:ok, ""}
|
|
region -> {:ok, region.region_name}
|
|
end
|
|
end
|
|
|
|
defp get_wormhole_class(wormhole_classes, wormhole_class_id) do
|
|
{:ok,
|
|
Enum.find(wormhole_classes, fn wormhole_class ->
|
|
wormhole_class.wormhole_class_id == wormhole_class_id
|
|
end)}
|
|
end
|
|
|
|
defp get_wormhole_class_id(_systems, _region_id, _constellation_id, 30_100_000),
|
|
do: {:ok, 10_100}
|
|
|
|
defp get_wormhole_class_id(systems, region_id, constellation_id, solar_system_id) do
|
|
with region <-
|
|
Enum.find(systems, fn system ->
|
|
system.location_id |> Integer.parse() |> elem(0) == region_id
|
|
end),
|
|
constellation <-
|
|
Enum.find(systems, fn system ->
|
|
system.location_id |> Integer.parse() |> elem(0) == constellation_id
|
|
end),
|
|
solar_system <-
|
|
Enum.find(systems, fn system ->
|
|
system.location_id |> Integer.parse() |> elem(0) == solar_system_id
|
|
end),
|
|
wormhole_class_id <- get_wormhole_class_id(region, constellation, solar_system) do
|
|
{:ok, wormhole_class_id}
|
|
else
|
|
_ -> {:ok, -1}
|
|
end
|
|
end
|
|
|
|
defp get_wormhole_class_id(_region, _constellation, solar_system)
|
|
when not is_nil(solar_system),
|
|
do: solar_system.wormhole_class_id |> Integer.parse() |> elem(0)
|
|
|
|
defp get_wormhole_class_id(_region, constellation, _solar_system)
|
|
when not is_nil(constellation),
|
|
do: constellation.wormhole_class_id |> Integer.parse() |> elem(0)
|
|
|
|
defp get_wormhole_class_id(region, _constellation, _solar_system) when not is_nil(region),
|
|
do: region.wormhole_class_id |> Integer.parse() |> elem(0)
|
|
|
|
defp get_wormhole_class_id(_region, _constellation, _solar_system), do: -1
|
|
end
|