mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-09 01:06:03 +00:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e31542c5f | ||
|
|
aae6ed0cb3 | ||
|
|
bb0e06589f | ||
|
|
d65b72c4dd | ||
|
|
24a3d5b3de | ||
|
|
2814b46941 | ||
|
|
d9a82f7c9f | ||
|
|
9a8106947e | ||
|
|
e21ca79ea1 | ||
|
|
dd579caeac | ||
|
|
ddf8a4b9fb | ||
|
|
3c04f4194e | ||
|
|
1e0de841eb | ||
|
|
c9c88cf0a6 | ||
|
|
fd1e124166 | ||
|
|
aa2bee258a | ||
|
|
12d696dc07 | ||
|
|
b33772a1d6 | ||
|
|
b41f89d7de | ||
|
|
e8ca213b74 | ||
|
|
7620b8d493 | ||
|
|
23306fd9e3 | ||
|
|
a68ccdca50 | ||
|
|
771e432546 | ||
|
|
20bdbfb81a | ||
|
|
90729b436c | ||
|
|
8ea4e97bbf | ||
|
|
17e12e9263 | ||
|
|
4cb3d021f4 | ||
|
|
97cec2e127 | ||
|
|
9c4294659c |
93
CHANGELOG.md
93
CHANGELOG.md
@@ -2,6 +2,99 @@
|
||||
|
||||
<!-- changelog -->
|
||||
|
||||
## [v1.65.24](https://github.com/wanderer-industries/wanderer/compare/v1.65.23...v1.65.24) (2025-06-04)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Core: Fixed errors duration check to reduce requests amount to ESI
|
||||
|
||||
## [v1.65.23](https://github.com/wanderer-industries/wanderer/compare/v1.65.22...v1.65.23) (2025-06-04)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Core: Added back arm docker image build
|
||||
|
||||
## [v1.65.22](https://github.com/wanderer-industries/wanderer/compare/v1.65.21...v1.65.22) (2025-06-04)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Core: Fix character tracking issues
|
||||
|
||||
## [v1.65.21](https://github.com/wanderer-industries/wanderer/compare/v1.65.20...v1.65.21) (2025-06-01)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Core: Fix connection pool errors
|
||||
|
||||
## [v1.65.20](https://github.com/wanderer-industries/wanderer/compare/v1.65.19...v1.65.20) (2025-06-01)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Core: fix waypoint set timeout errors
|
||||
|
||||
## [v1.65.19](https://github.com/wanderer-industries/wanderer/compare/v1.65.18...v1.65.19) (2025-06-01)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Core: fix updating character online
|
||||
|
||||
## [v1.65.18](https://github.com/wanderer-industries/wanderer/compare/v1.65.17...v1.65.18) (2025-05-30)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Core: fix updating systems and connections
|
||||
|
||||
## [v1.65.17](https://github.com/wanderer-industries/wanderer/compare/v1.65.16...v1.65.17) (2025-05-29)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Core: fix updating systems and connections
|
||||
|
||||
* Comments: fix error loading comments
|
||||
|
||||
## [v1.65.16](https://github.com/wanderer-industries/wanderer/compare/v1.65.15...v1.65.16) (2025-05-29)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Map: Allow lock systems for members
|
||||
|
||||
## [v1.65.15](https://github.com/wanderer-industries/wanderer/compare/v1.65.14...v1.65.15) (2025-05-28)
|
||||
|
||||
|
||||
|
||||
|
||||
## [v1.65.14](https://github.com/wanderer-industries/wanderer/compare/v1.65.13...v1.65.14) (2025-05-28)
|
||||
|
||||
|
||||
|
||||
|
||||
## [v1.65.13](https://github.com/wanderer-industries/wanderer/compare/v1.65.12...v1.65.13) (2025-05-28)
|
||||
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ export const useContextMenuSystemItems = ({
|
||||
const getLabels = useLabelsMenu(systems, systemId, onSystemLabels, onCustomLabelDialog);
|
||||
const getWaypointMenu = useWaypointMenu(onWaypointSet);
|
||||
const canLockSystem = useMapCheckPermissions([UserPermission.LOCK_SYSTEM]);
|
||||
const canManageSystem = useMapCheckPermissions([UserPermission.UPDATE_SYSTEM]);
|
||||
const canDeleteSystem = useMapCheckPermissions([UserPermission.DELETE_SYSTEM]);
|
||||
const getUserRoutes = useUserRoute({ userHubs, systemId, onUserHubToggle });
|
||||
|
||||
@@ -132,11 +133,20 @@ export const useContextMenuSystemItems = ({
|
||||
);
|
||||
},
|
||||
},
|
||||
...(canLockSystem
|
||||
...(system.locked && canLockSystem
|
||||
? [
|
||||
{
|
||||
label: system.locked ? 'Unlock' : 'Lock',
|
||||
icon: system.locked ? PrimeIcons.LOCK_OPEN : PrimeIcons.LOCK,
|
||||
label: 'Unlock',
|
||||
icon: PrimeIcons.LOCK_OPEN,
|
||||
command: onLockToggle,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(!system.locked && canManageSystem
|
||||
? [
|
||||
{
|
||||
label: 'Lock',
|
||||
icon: PrimeIcons.LOCK,
|
||||
command: onLockToggle,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { MutableRefObject, useCallback, useEffect, useRef } from 'react';
|
||||
import { Command, Commands, MapHandlers } from '@/hooks/Mapper/types';
|
||||
import { MapEvent } from '@/hooks/Mapper/events';
|
||||
// import { useThrottle } from '@/hooks/Mapper/hooks';
|
||||
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
||||
import { Command, Commands, MapHandlers } from '@/hooks/Mapper/types';
|
||||
import { MutableRefObject, useCallback, useEffect, useRef } from 'react';
|
||||
|
||||
export const useCommonMapEventProcessor = () => {
|
||||
const mapRef = useRef<MapHandlers>() as MutableRefObject<MapHandlers>;
|
||||
@@ -11,13 +12,14 @@ export const useCommonMapEventProcessor = () => {
|
||||
|
||||
const refQueue = useRef<MapEvent<Command>[]>([]);
|
||||
|
||||
// const ref = useRef({})
|
||||
|
||||
const runCommand = useCallback(({ name, data }: MapEvent<Command>) => {
|
||||
switch (name) {
|
||||
case Commands.addSystems:
|
||||
case Commands.removeSystems:
|
||||
// case Commands.updateSystems:
|
||||
// case Commands.addConnections:
|
||||
// case Commands.removeConnections:
|
||||
// case Commands.updateConnection:
|
||||
refQueue.current.push({ name, data });
|
||||
return;
|
||||
}
|
||||
@@ -26,9 +28,17 @@ export const useCommonMapEventProcessor = () => {
|
||||
mapRef.current?.command(name, data);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
refQueue.current.forEach(x => mapRef.current?.command(x.name, x.data));
|
||||
const processQueue = useCallback(() => {
|
||||
const commands = [...refQueue.current];
|
||||
refQueue.current = [];
|
||||
commands.forEach(x => mapRef.current?.command(x.name, x.data));
|
||||
}, []);
|
||||
|
||||
// const throttledProcessQueue = useThrottle(processQueue, 200);
|
||||
|
||||
useEffect(() => {
|
||||
// throttledProcessQueue();
|
||||
processQueue();
|
||||
}, [systems]);
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export * from './usePageVisibility';
|
||||
export * from './useActualizeSettings';
|
||||
export * from './useClipboard';
|
||||
export * from './useHotkey';
|
||||
export * from './usePageVisibility';
|
||||
export * from './useSkipContextMenu';
|
||||
export * from './useActualizeSettings';
|
||||
export * from './useThrottle';
|
||||
|
||||
13
assets/js/hooks/Mapper/hooks/useThrottle.ts
Normal file
13
assets/js/hooks/Mapper/hooks/useThrottle.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { useCallback, useRef } from 'react';
|
||||
|
||||
export const useThrottle = (callback: any, limit: number) => {
|
||||
const lastCallRef = useRef(0);
|
||||
const throttledCallback = useCallback(() => {
|
||||
const now = Date.now();
|
||||
if (now - lastCallRef.current >= limit) {
|
||||
lastCallRef.current = now;
|
||||
callback();
|
||||
}
|
||||
}, [callback, limit]);
|
||||
return throttledCallback;
|
||||
};
|
||||
@@ -1,9 +1,6 @@
|
||||
import { MapHandlers } from '@/hooks/Mapper/types/mapHandlers.ts';
|
||||
import { RefObject, useCallback } from 'react';
|
||||
|
||||
// Force reload the page after 5 minutes of inactivity
|
||||
const FORCE_PAGE_RELOAD_TIMEOUT = 1000 * 60 * 5;
|
||||
|
||||
export const useMapperHandlers = (handlerRefs: RefObject<MapHandlers>[], hooksRef: RefObject<any>) => {
|
||||
const handleCommand = useCallback(
|
||||
async ({ type, data }) => {
|
||||
@@ -16,13 +13,7 @@ export const useMapperHandlers = (handlerRefs: RefObject<MapHandlers>[], hooksRe
|
||||
[hooksRef.current],
|
||||
);
|
||||
|
||||
const handleMapEvent = useCallback(({ type, body, timestamp }) => {
|
||||
const timeDiff = Date.now() - Date.parse(timestamp);
|
||||
// If the event is older than the timeout, force reload the page
|
||||
if (timeDiff > FORCE_PAGE_RELOAD_TIMEOUT) {
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
const handleMapEvent = useCallback(({ type, body }) => {
|
||||
handlerRefs.forEach(ref => {
|
||||
if (!ref.current) {
|
||||
return;
|
||||
|
||||
@@ -20,9 +20,9 @@ defmodule WandererApp.Application do
|
||||
pools: %{
|
||||
default: [
|
||||
# number of connections per pool
|
||||
size: 25,
|
||||
size: 50,
|
||||
# number of pools (so total 50 connections)
|
||||
count: 2
|
||||
count: 4
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -54,18 +54,26 @@ defmodule WandererApp.Character do
|
||||
end
|
||||
end
|
||||
|
||||
def get_map_character(map_id, character_id) do
|
||||
def get_map_character(map_id, character_id, opts \\ []) do
|
||||
case get_character(character_id) do
|
||||
{:ok, character} ->
|
||||
# If we are forcing the character to not be present, we merge the character state with map settings
|
||||
character_is_present =
|
||||
if opts |> Keyword.get(:not_present, false) do
|
||||
false
|
||||
else
|
||||
WandererApp.Character.TrackerManager.Impl.character_is_present(map_id, character_id)
|
||||
end
|
||||
|
||||
{:ok,
|
||||
character
|
||||
|> maybe_merge_map_character_settings(
|
||||
map_id,
|
||||
WandererApp.Character.TrackerManager.Impl.character_is_present(map_id, character_id)
|
||||
character_is_present
|
||||
)}
|
||||
|
||||
_ ->
|
||||
{:ok, nil}
|
||||
error ->
|
||||
error
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -79,8 +79,8 @@ defmodule WandererApp.Character.Tracker do
|
||||
|
||||
:ok
|
||||
|
||||
{:error, :forbidden} ->
|
||||
Logger.warning("#{__MODULE__} failed to get_character_info: forbidden")
|
||||
{:error, error} when error in [:forbidden, :error_limited, :not_found, :timeout] ->
|
||||
Logger.warning("#{__MODULE__} failed to get_character_info: #{inspect(error)}")
|
||||
|
||||
WandererApp.Cache.put(
|
||||
"character:#{character_id}:info_forbidden",
|
||||
@@ -88,7 +88,7 @@ defmodule WandererApp.Character.Tracker do
|
||||
ttl: @forbidden_ttl
|
||||
)
|
||||
|
||||
{:error, :forbidden}
|
||||
{:error, error}
|
||||
|
||||
{:error, error} ->
|
||||
Logger.error("#{__MODULE__} failed to get_character_info: #{inspect(error)}")
|
||||
@@ -121,13 +121,13 @@ defmodule WandererApp.Character.Tracker do
|
||||
character_id: character_id,
|
||||
refresh_token?: true
|
||||
) do
|
||||
{:ok, ship} ->
|
||||
{:ok, ship} when is_non_struct_map(ship) ->
|
||||
character_state |> maybe_update_ship(ship)
|
||||
|
||||
:ok
|
||||
|
||||
{:error, :forbidden} ->
|
||||
Logger.warning("#{__MODULE__} failed to update_ship: forbidden")
|
||||
{:error, error} when error in [:forbidden, :error_limited, :not_found, :timeout] ->
|
||||
Logger.warning("#{__MODULE__} failed to update_ship: #{inspect(error)}")
|
||||
|
||||
WandererApp.Cache.put(
|
||||
"character:#{character_id}:ship_forbidden",
|
||||
@@ -135,7 +135,7 @@ defmodule WandererApp.Character.Tracker do
|
||||
ttl: @forbidden_ttl
|
||||
)
|
||||
|
||||
{:error, :forbidden}
|
||||
{:error, error}
|
||||
|
||||
{:error, error} ->
|
||||
Logger.error("#{__MODULE__} failed to update_ship: #{inspect(error)}")
|
||||
@@ -147,6 +147,11 @@ defmodule WandererApp.Character.Tracker do
|
||||
)
|
||||
|
||||
{:error, error}
|
||||
|
||||
_ ->
|
||||
Logger.error("#{__MODULE__} failed to update_ship: wrong response")
|
||||
|
||||
{:error, :skipped}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -179,14 +184,14 @@ defmodule WandererApp.Character.Tracker do
|
||||
character_id: character_id,
|
||||
refresh_token?: true
|
||||
) do
|
||||
{:ok, location} ->
|
||||
{:ok, location} when is_non_struct_map(location) ->
|
||||
character_state
|
||||
|> maybe_update_location(location)
|
||||
|
||||
:ok
|
||||
|
||||
{:error, :forbidden} ->
|
||||
Logger.warning("#{__MODULE__} failed to update_location: forbidden")
|
||||
{:error, error} when error in [:forbidden, :error_limited, :not_found, :timeout] ->
|
||||
Logger.warning("#{__MODULE__} failed to update_location: #{inspect(error)}")
|
||||
|
||||
WandererApp.Cache.put(
|
||||
"character:#{character_id}:location_forbidden",
|
||||
@@ -194,7 +199,7 @@ defmodule WandererApp.Character.Tracker do
|
||||
ttl: @forbidden_ttl
|
||||
)
|
||||
|
||||
{:error, :forbidden}
|
||||
{:error, error}
|
||||
|
||||
{:error, error} ->
|
||||
Logger.error("#{__MODULE__} failed to update_location: #{inspect(error)}")
|
||||
@@ -206,6 +211,11 @@ defmodule WandererApp.Character.Tracker do
|
||||
)
|
||||
|
||||
{:error, error}
|
||||
|
||||
_ ->
|
||||
Logger.error("#{__MODULE__} failed to update_location: wrong response")
|
||||
|
||||
{:error, :skipped}
|
||||
end
|
||||
|
||||
_ ->
|
||||
@@ -247,11 +257,6 @@ defmodule WandererApp.Character.Tracker do
|
||||
WandererApp.Cache.delete("character:#{character_id}:online_error_time")
|
||||
WandererApp.Character.update_character(character_id, online)
|
||||
|
||||
if not online.online do
|
||||
WandererApp.Cache.delete("character:#{character_id}:location_started")
|
||||
WandererApp.Cache.delete("character:#{character_id}:start_solar_system_id")
|
||||
end
|
||||
|
||||
update = %{
|
||||
character_state
|
||||
| is_online: online.online,
|
||||
@@ -263,8 +268,8 @@ defmodule WandererApp.Character.Tracker do
|
||||
|
||||
:ok
|
||||
|
||||
{:error, :forbidden} ->
|
||||
Logger.warning("#{__MODULE__} failed to update_online: forbidden")
|
||||
{:error, error} when error in [:forbidden, :error_limited, :not_found, :timeout] ->
|
||||
Logger.warning("#{__MODULE__} failed to update_online: #{inspect(error)}")
|
||||
|
||||
if not WandererApp.Cache.lookup!(
|
||||
"character:#{character_id}:online_forbidden",
|
||||
@@ -316,7 +321,7 @@ defmodule WandererApp.Character.Tracker do
|
||||
:skip
|
||||
|
||||
error_time ->
|
||||
duration = DateTime.diff(DateTime.utc_now(), error_time, :second)
|
||||
duration = DateTime.diff(DateTime.utc_now(), error_time, :millisecond)
|
||||
|
||||
if duration >= @online_error_timeout do
|
||||
WandererApp.Cache.delete("character:#{character_id}:online_forbidden")
|
||||
@@ -362,8 +367,9 @@ defmodule WandererApp.Character.Tracker do
|
||||
|
||||
:ok
|
||||
|
||||
{:error, :forbidden} ->
|
||||
Logger.warning("#{__MODULE__} failed to _update_wallet: forbidden")
|
||||
{:error, error}
|
||||
when error in [:forbidden, :error_limited, :not_found, :timeout] ->
|
||||
Logger.warning("#{__MODULE__} failed to update_wallet: #{inspect(error)}")
|
||||
|
||||
WandererApp.Cache.put(
|
||||
"character:#{character_id}:wallet_forbidden",
|
||||
@@ -371,7 +377,7 @@ defmodule WandererApp.Character.Tracker do
|
||||
ttl: @forbidden_ttl
|
||||
)
|
||||
|
||||
{:error, :forbidden}
|
||||
{:error, error}
|
||||
|
||||
{:error, error} ->
|
||||
Logger.error("#{__MODULE__} failed to _update_wallet: #{inspect(error)}")
|
||||
@@ -475,7 +481,8 @@ defmodule WandererApp.Character.Tracker do
|
||||
} =
|
||||
state,
|
||||
ship
|
||||
) do
|
||||
)
|
||||
when is_non_struct_map(ship) do
|
||||
ship_type_id = Map.get(ship, "ship_type_id")
|
||||
ship_name = Map.get(ship, "ship_name")
|
||||
|
||||
@@ -499,6 +506,12 @@ defmodule WandererApp.Character.Tracker do
|
||||
state
|
||||
end
|
||||
|
||||
defp maybe_update_ship(
|
||||
state,
|
||||
_ship
|
||||
),
|
||||
do: state
|
||||
|
||||
defp maybe_update_location(
|
||||
%{
|
||||
character_id: character_id
|
||||
@@ -508,32 +521,12 @@ defmodule WandererApp.Character.Tracker do
|
||||
) do
|
||||
location = get_location(location)
|
||||
|
||||
if not is_location_started?(character_id) do
|
||||
WandererApp.Cache.lookup!("character:#{character_id}:start_solar_system_id", nil)
|
||||
|> case do
|
||||
nil ->
|
||||
WandererApp.Cache.put(
|
||||
"character:#{character_id}:start_solar_system_id",
|
||||
location.solar_system_id
|
||||
)
|
||||
|
||||
start_solar_system_id ->
|
||||
if location.solar_system_id != start_solar_system_id do
|
||||
WandererApp.Cache.put(
|
||||
"character:#{character_id}:location_started",
|
||||
true
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
{:ok,
|
||||
%{solar_system_id: solar_system_id, structure_id: structure_id, station_id: station_id} =
|
||||
character} =
|
||||
WandererApp.Character.get_character(character_id)
|
||||
|
||||
(not is_location_started?(character_id) ||
|
||||
is_location_updated?(location, solar_system_id, structure_id, station_id))
|
||||
is_location_updated?(location, solar_system_id, structure_id, station_id)
|
||||
|> case do
|
||||
true ->
|
||||
{:ok, _character} = WandererApp.Api.Character.update_location(character, location)
|
||||
@@ -548,12 +541,12 @@ defmodule WandererApp.Character.Tracker do
|
||||
state
|
||||
end
|
||||
|
||||
defp is_location_started?(character_id),
|
||||
do:
|
||||
WandererApp.Cache.lookup!(
|
||||
"character:#{character_id}:location_started",
|
||||
false
|
||||
)
|
||||
# defp is_location_started?(character_id),
|
||||
# do:
|
||||
# WandererApp.Cache.lookup!(
|
||||
# "character:#{character_id}:location_started",
|
||||
# false
|
||||
# )
|
||||
|
||||
defp is_location_updated?(
|
||||
%{
|
||||
@@ -692,16 +685,31 @@ defmodule WandererApp.Character.Tracker do
|
||||
defp maybe_update_active_maps(
|
||||
%{character_id: character_id, active_maps: active_maps} =
|
||||
state,
|
||||
%{map_id: map_id, track: true} = _track_settings
|
||||
%{map_id: map_id, track: true} = track_settings
|
||||
) do
|
||||
WandererApp.Cache.put(
|
||||
"character:#{character_id}:map:#{map_id}:tracking_start_time",
|
||||
DateTime.utc_now()
|
||||
)
|
||||
if not Enum.member?(active_maps, map_id) do
|
||||
WandererApp.Cache.put(
|
||||
"character:#{character_id}:map:#{map_id}:tracking_start_time",
|
||||
DateTime.utc_now()
|
||||
)
|
||||
|
||||
WandererApp.Cache.take("character:#{character_id}:last_active_time")
|
||||
WandererApp.Cache.put(
|
||||
"map:#{map_id}:character:#{character_id}:start_solar_system_id",
|
||||
track_settings |> Map.get(:solar_system_id)
|
||||
)
|
||||
|
||||
%{state | active_maps: [map_id | active_maps] |> Enum.uniq()}
|
||||
WandererApp.Cache.delete("map:#{map_id}:character:#{character_id}:solar_system_id")
|
||||
WandererApp.Cache.delete("map:#{map_id}:character:#{character_id}:station_id")
|
||||
WandererApp.Cache.delete("map:#{map_id}:character:#{character_id}:structure_id")
|
||||
|
||||
WandererApp.Cache.take("character:#{character_id}:last_active_time")
|
||||
|
||||
%{state | active_maps: [map_id | active_maps]}
|
||||
else
|
||||
WandererApp.Cache.take("character:#{character_id}:last_active_time")
|
||||
|
||||
state
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_update_active_maps(
|
||||
|
||||
@@ -77,8 +77,6 @@ defmodule WandererApp.Character.TrackerManager.Impl do
|
||||
Logger.debug(fn -> "Shutting down character tracker: #{inspect(character_id)}" end)
|
||||
|
||||
WandererApp.Cache.delete("character:#{character_id}:last_active_time")
|
||||
WandererApp.Cache.delete("character:#{character_id}:location_started")
|
||||
WandererApp.Cache.delete("character:#{character_id}:start_solar_system_id")
|
||||
WandererApp.Character.delete_character_state(character_id)
|
||||
|
||||
tracked_characters =
|
||||
@@ -189,7 +187,7 @@ defmodule WandererApp.Character.TrackerManager.Impl do
|
||||
end,
|
||||
max_concurrency: System.schedulers_online(),
|
||||
on_timeout: :kill_task,
|
||||
timeout: :timer.seconds(15)
|
||||
timeout: :timer.seconds(60)
|
||||
)
|
||||
|> Enum.map(fn result ->
|
||||
case result do
|
||||
@@ -214,6 +212,10 @@ defmodule WandererApp.Character.TrackerManager.Impl do
|
||||
|> Task.async_stream(
|
||||
fn {map_id, character_id} ->
|
||||
if not character_is_present(map_id, character_id) do
|
||||
WandererApp.Cache.delete("map:#{map_id}:character:#{character_id}:solar_system_id")
|
||||
WandererApp.Cache.delete("map:#{map_id}:character:#{character_id}:station_id")
|
||||
WandererApp.Cache.delete("map:#{map_id}:character:#{character_id}:structure_id")
|
||||
|
||||
{:ok, character_state} =
|
||||
WandererApp.Character.Tracker.update_settings(character_id, %{
|
||||
map_id: map_id,
|
||||
|
||||
@@ -49,7 +49,9 @@ defmodule WandererApp.Character.TrackerPool do
|
||||
# end)
|
||||
|
||||
tracked_ids
|
||||
|> Enum.each(fn id -> Cachex.put(@cache, id, uuid) end)
|
||||
|> Enum.each(fn id ->
|
||||
Cachex.put(@cache, id, uuid)
|
||||
end)
|
||||
|
||||
state =
|
||||
%{
|
||||
@@ -78,7 +80,6 @@ defmodule WandererApp.Character.TrackerPool do
|
||||
# Cachex.get_and_update(@cache, :tracked_characters, fn ids ->
|
||||
# {:commit, ids ++ [tracked_id]}
|
||||
# end)
|
||||
|
||||
Cachex.put(@cache, tracked_id, uuid)
|
||||
|
||||
{:noreply, %{state | characters: [tracked_id | characters]}}
|
||||
@@ -96,7 +97,7 @@ defmodule WandererApp.Character.TrackerPool do
|
||||
# Cachex.get_and_update(@cache, :tracked_characters, fn ids ->
|
||||
# {:commit, ids |> Enum.reject(fn id -> id == tracked_id end)}
|
||||
# end)
|
||||
|
||||
#
|
||||
Cachex.del(@cache, tracked_id)
|
||||
|
||||
{:noreply, %{state | characters: characters |> Enum.reject(fn id -> id == tracked_id end)}}
|
||||
@@ -155,12 +156,20 @@ defmodule WandererApp.Character.TrackerPool do
|
||||
) do
|
||||
Process.send_after(self(), :update_online, @update_online_interval)
|
||||
|
||||
characters
|
||||
|> Enum.map(fn character_id ->
|
||||
WandererApp.TaskWrapper.start_link(WandererApp.Character.Tracker, :update_online, [
|
||||
character_id
|
||||
])
|
||||
end)
|
||||
try do
|
||||
characters
|
||||
|> Enum.map(fn character_id ->
|
||||
WandererApp.TaskWrapper.start_link(WandererApp.Character.Tracker, :update_online, [
|
||||
character_id
|
||||
])
|
||||
end)
|
||||
rescue
|
||||
e ->
|
||||
Logger.error("""
|
||||
[Tracker Pool] update_online => exception: #{Exception.message(e)}
|
||||
#{Exception.format_stacktrace(__STACKTRACE__)}
|
||||
""")
|
||||
end
|
||||
|
||||
{:noreply, state}
|
||||
end
|
||||
@@ -174,14 +183,22 @@ defmodule WandererApp.Character.TrackerPool do
|
||||
) do
|
||||
Process.send_after(self(), :update_online, @update_online_interval)
|
||||
|
||||
characters
|
||||
|> Enum.each(fn character_id ->
|
||||
WandererApp.Character.update_character(character_id, %{online: false})
|
||||
try do
|
||||
characters
|
||||
|> Enum.each(fn character_id ->
|
||||
WandererApp.Character.update_character(character_id, %{online: false})
|
||||
|
||||
WandererApp.Character.update_character_state(character_id, %{
|
||||
is_online: false
|
||||
})
|
||||
end)
|
||||
WandererApp.Character.update_character_state(character_id, %{
|
||||
is_online: false
|
||||
})
|
||||
end)
|
||||
rescue
|
||||
e ->
|
||||
Logger.error("""
|
||||
[Tracker Pool] update_online => exception: #{Exception.message(e)}
|
||||
#{Exception.format_stacktrace(__STACKTRACE__)}
|
||||
""")
|
||||
end
|
||||
|
||||
{:noreply, state}
|
||||
end
|
||||
@@ -195,21 +212,33 @@ defmodule WandererApp.Character.TrackerPool do
|
||||
) do
|
||||
Process.send_after(self(), :check_online_errors, @check_online_errors_interval)
|
||||
|
||||
characters
|
||||
|> Task.async_stream(
|
||||
fn character_id ->
|
||||
WandererApp.TaskWrapper.start_link(WandererApp.Character.Tracker, :check_online_errors, [
|
||||
character_id
|
||||
])
|
||||
end,
|
||||
timeout: :timer.seconds(15),
|
||||
max_concurrency: System.schedulers_online(),
|
||||
on_timeout: :kill_task
|
||||
)
|
||||
|> Enum.each(fn
|
||||
{:ok, _result} -> :ok
|
||||
{:error, reason} -> @logger.error("Error in check_online_errors: #{inspect(reason)}")
|
||||
end)
|
||||
try do
|
||||
characters
|
||||
|> Task.async_stream(
|
||||
fn character_id ->
|
||||
WandererApp.TaskWrapper.start_link(
|
||||
WandererApp.Character.Tracker,
|
||||
:check_online_errors,
|
||||
[
|
||||
character_id
|
||||
]
|
||||
)
|
||||
end,
|
||||
timeout: :timer.seconds(15),
|
||||
max_concurrency: System.schedulers_online(),
|
||||
on_timeout: :kill_task
|
||||
)
|
||||
|> Enum.each(fn
|
||||
{:ok, _result} -> :ok
|
||||
{:error, reason} -> @logger.error("Error in check_online_errors: #{inspect(reason)}")
|
||||
end)
|
||||
rescue
|
||||
e ->
|
||||
Logger.error("""
|
||||
[Tracker Pool] check_online_errors => exception: #{Exception.message(e)}
|
||||
#{Exception.format_stacktrace(__STACKTRACE__)}
|
||||
""")
|
||||
end
|
||||
|
||||
{:noreply, state}
|
||||
end
|
||||
@@ -224,12 +253,20 @@ defmodule WandererApp.Character.TrackerPool do
|
||||
) do
|
||||
Process.send_after(self(), :update_location, @update_location_interval)
|
||||
|
||||
characters
|
||||
|> Enum.map(fn character_id ->
|
||||
WandererApp.TaskWrapper.start_link(WandererApp.Character.Tracker, :update_location, [
|
||||
character_id
|
||||
])
|
||||
end)
|
||||
try do
|
||||
characters
|
||||
|> Enum.map(fn character_id ->
|
||||
WandererApp.TaskWrapper.start_link(WandererApp.Character.Tracker, :update_location, [
|
||||
character_id
|
||||
])
|
||||
end)
|
||||
rescue
|
||||
e ->
|
||||
Logger.error("""
|
||||
[Tracker Pool] update_location => exception: #{Exception.message(e)}
|
||||
#{Exception.format_stacktrace(__STACKTRACE__)}
|
||||
""")
|
||||
end
|
||||
|
||||
{:noreply, state}
|
||||
end
|
||||
@@ -253,12 +290,20 @@ defmodule WandererApp.Character.TrackerPool do
|
||||
) do
|
||||
Process.send_after(self(), :update_ship, @update_ship_interval)
|
||||
|
||||
characters
|
||||
|> Enum.map(fn character_id ->
|
||||
WandererApp.TaskWrapper.start_link(WandererApp.Character.Tracker, :update_ship, [
|
||||
character_id
|
||||
])
|
||||
end)
|
||||
try do
|
||||
characters
|
||||
|> Enum.map(fn character_id ->
|
||||
WandererApp.TaskWrapper.start_link(WandererApp.Character.Tracker, :update_ship, [
|
||||
character_id
|
||||
])
|
||||
end)
|
||||
rescue
|
||||
e ->
|
||||
Logger.error("""
|
||||
[Tracker Pool] update_ship => exception: #{Exception.message(e)}
|
||||
#{Exception.format_stacktrace(__STACKTRACE__)}
|
||||
""")
|
||||
end
|
||||
|
||||
{:noreply, state}
|
||||
end
|
||||
@@ -282,21 +327,29 @@ defmodule WandererApp.Character.TrackerPool do
|
||||
) do
|
||||
Process.send_after(self(), :update_info, @update_info_interval)
|
||||
|
||||
characters
|
||||
|> Task.async_stream(
|
||||
fn character_id ->
|
||||
WandererApp.TaskWrapper.start_link(WandererApp.Character.Tracker, :update_info, [
|
||||
character_id
|
||||
])
|
||||
end,
|
||||
timeout: :timer.seconds(15),
|
||||
max_concurrency: System.schedulers_online(),
|
||||
on_timeout: :kill_task
|
||||
)
|
||||
|> Enum.each(fn
|
||||
{:ok, _result} -> :ok
|
||||
{:error, reason} -> @logger.error("Error in update_info: #{inspect(reason)}")
|
||||
end)
|
||||
try do
|
||||
characters
|
||||
|> Task.async_stream(
|
||||
fn character_id ->
|
||||
WandererApp.TaskWrapper.start_link(WandererApp.Character.Tracker, :update_info, [
|
||||
character_id
|
||||
])
|
||||
end,
|
||||
timeout: :timer.seconds(15),
|
||||
max_concurrency: System.schedulers_online(),
|
||||
on_timeout: :kill_task
|
||||
)
|
||||
|> Enum.each(fn
|
||||
{:ok, _result} -> :ok
|
||||
{:error, reason} -> Logger.error("Error in update_info: #{inspect(reason)}")
|
||||
end)
|
||||
rescue
|
||||
e ->
|
||||
Logger.error("""
|
||||
[Tracker Pool] update_info => exception: #{Exception.message(e)}
|
||||
#{Exception.format_stacktrace(__STACKTRACE__)}
|
||||
""")
|
||||
end
|
||||
|
||||
{:noreply, state}
|
||||
end
|
||||
@@ -320,21 +373,29 @@ defmodule WandererApp.Character.TrackerPool do
|
||||
) do
|
||||
Process.send_after(self(), :update_wallet, @update_wallet_interval)
|
||||
|
||||
characters
|
||||
|> Task.async_stream(
|
||||
fn character_id ->
|
||||
WandererApp.TaskWrapper.start_link(WandererApp.Character.Tracker, :update_wallet, [
|
||||
character_id
|
||||
])
|
||||
end,
|
||||
timeout: :timer.seconds(15),
|
||||
max_concurrency: System.schedulers_online(),
|
||||
on_timeout: :kill_task
|
||||
)
|
||||
|> Enum.each(fn
|
||||
{:ok, _result} -> :ok
|
||||
{:error, reason} -> @logger.error("Error in update_wallet: #{inspect(reason)}")
|
||||
end)
|
||||
try do
|
||||
characters
|
||||
|> Task.async_stream(
|
||||
fn character_id ->
|
||||
WandererApp.TaskWrapper.start_link(WandererApp.Character.Tracker, :update_wallet, [
|
||||
character_id
|
||||
])
|
||||
end,
|
||||
timeout: :timer.seconds(15),
|
||||
max_concurrency: System.schedulers_online(),
|
||||
on_timeout: :kill_task
|
||||
)
|
||||
|> Enum.each(fn
|
||||
{:ok, _result} -> :ok
|
||||
{:error, reason} -> Logger.error("Error in update_wallet: #{inspect(reason)}")
|
||||
end)
|
||||
rescue
|
||||
e ->
|
||||
Logger.error("""
|
||||
[Tracker Pool] update_wallet => exception: #{Exception.message(e)}
|
||||
#{Exception.format_stacktrace(__STACKTRACE__)}
|
||||
""")
|
||||
end
|
||||
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
@@ -11,6 +11,8 @@ defmodule WandererApp.Esi.ApiClient do
|
||||
@base_url "https://esi.evetech.net/latest"
|
||||
@wanderrer_user_agent "(wanderer-industries@proton.me; +https://github.com/wanderer-industries/wanderer)"
|
||||
|
||||
@req_esi Req.new(base_url: @base_url, finch: WandererApp.Finch)
|
||||
|
||||
@get_link_pairs_advanced_params [
|
||||
:include_mass_crit,
|
||||
:include_eol,
|
||||
@@ -36,7 +38,7 @@ defmodule WandererApp.Esi.ApiClient do
|
||||
|
||||
@cache_opts [cache: true]
|
||||
@retry_opts [max_retries: 0, retry_log_level: :warning]
|
||||
@timeout_opts [pool_timeout: 15_000, receive_timeout: :timer.seconds(30)]
|
||||
@timeout_opts [pool_timeout: 15_000, receive_timeout: :timer.minutes(1)]
|
||||
@api_retry_count 1
|
||||
|
||||
@logger Application.compile_env(:wanderer_app, :logger)
|
||||
@@ -47,7 +49,7 @@ defmodule WandererApp.Esi.ApiClient do
|
||||
do:
|
||||
post_esi(
|
||||
"/ui/autopilot/waypoint",
|
||||
opts
|
||||
get_auth_opts(opts)
|
||||
|> Keyword.merge(
|
||||
params: %{
|
||||
add_to_beginning: add_to_beginning,
|
||||
@@ -60,8 +62,8 @@ defmodule WandererApp.Esi.ApiClient do
|
||||
def post_characters_affiliation(character_eve_ids, _opts)
|
||||
when is_list(character_eve_ids),
|
||||
do:
|
||||
post(
|
||||
"#{@base_url}/characters/affiliation/",
|
||||
post_esi(
|
||||
"/characters/affiliation/",
|
||||
json: character_eve_ids,
|
||||
params: %{
|
||||
datasource: "tranquility"
|
||||
@@ -218,8 +220,6 @@ defmodule WandererApp.Esi.ApiClient do
|
||||
{:ok, result}
|
||||
|
||||
{:error, _error} ->
|
||||
@logger.error("Error getting custom routes for #{inspect(origin)}: #{inspect(hubs)}")
|
||||
|
||||
@logger.error(
|
||||
"Error getting custom routes for #{inspect(origin)}: #{inspect(params)}"
|
||||
)
|
||||
@@ -499,13 +499,6 @@ defmodule WandererApp.Esi.ApiClient do
|
||||
opts |> Keyword.merge(@cache_opts) |> Keyword.merge(cache_dir: System.tmp_dir!())
|
||||
end
|
||||
|
||||
defp post_esi(path, opts),
|
||||
do:
|
||||
post(
|
||||
"#{@base_url}#{path}",
|
||||
[params: opts[:params] || []] ++ (opts |> get_auth_opts())
|
||||
)
|
||||
|
||||
defp get(path, api_opts \\ [], opts \\ []) do
|
||||
case Cachex.get(:api_cache, path) do
|
||||
{:ok, cached_data} when not is_nil(cached_data) ->
|
||||
@@ -519,8 +512,9 @@ defmodule WandererApp.Esi.ApiClient do
|
||||
defp do_get_request(path, api_opts \\ [], opts \\ []) do
|
||||
try do
|
||||
case Req.get(
|
||||
"#{@base_url}#{path}",
|
||||
@req_esi,
|
||||
api_opts
|
||||
|> Keyword.merge(url: path)
|
||||
|> with_user_agent_opts()
|
||||
|> with_cache_opts()
|
||||
|> Keyword.merge(@retry_opts)
|
||||
@@ -537,11 +531,11 @@ defmodule WandererApp.Esi.ApiClient do
|
||||
{:ok, %{status: 404}} ->
|
||||
{:error, :not_found}
|
||||
|
||||
{:ok, %{status: 403} = _error} ->
|
||||
{:ok, %{status: status} = _error} when status in [401, 403] ->
|
||||
get_retry(path, api_opts, opts)
|
||||
|
||||
{:ok, %{status: 420} = _error} ->
|
||||
get_retry(path, api_opts, opts, :error_limited)
|
||||
{:error, :error_limited}
|
||||
|
||||
{:ok, %{status: status}} ->
|
||||
{:error, "Unexpected status: #{status}"}
|
||||
@@ -551,7 +545,7 @@ defmodule WandererApp.Esi.ApiClient do
|
||||
end
|
||||
rescue
|
||||
e ->
|
||||
@logger.error(Exception.message(e))
|
||||
Logger.error(Exception.message(e))
|
||||
|
||||
{:error, "Request failed"}
|
||||
end
|
||||
@@ -610,6 +604,45 @@ defmodule WandererApp.Esi.ApiClient do
|
||||
end
|
||||
end
|
||||
|
||||
defp post_esi(url, opts) do
|
||||
try do
|
||||
req_opts =
|
||||
(opts
|
||||
|> with_user_agent_opts()) ++
|
||||
[params: opts[:params] || []]
|
||||
|
||||
Req.new(
|
||||
[base_url: @base_url, finch: WandererApp.Finch] ++
|
||||
req_opts
|
||||
)
|
||||
|> Req.post(url: url)
|
||||
|> case do
|
||||
{:ok, %{status: status, body: body}} when status in [200, 201] ->
|
||||
{:ok, body}
|
||||
|
||||
{:ok, %{status: 504}} ->
|
||||
{:error, :timeout}
|
||||
|
||||
{:ok, %{status: 403}} ->
|
||||
{:error, :forbidden}
|
||||
|
||||
{:ok, %{status: 420}} ->
|
||||
{:error, :error_limited}
|
||||
|
||||
{:ok, %{status: status}} ->
|
||||
{:error, "Unexpected status: #{status}"}
|
||||
|
||||
{:error, reason} ->
|
||||
{:error, reason}
|
||||
end
|
||||
rescue
|
||||
e ->
|
||||
@logger.error(Exception.message(e))
|
||||
|
||||
{:error, "Request failed"}
|
||||
end
|
||||
end
|
||||
|
||||
defp get_retry(path, api_opts, opts, status \\ :forbidden) do
|
||||
refresh_token? = opts |> Keyword.get(:refresh_token?, false)
|
||||
retry_count = opts |> Keyword.get(:retry_count, 0)
|
||||
|
||||
@@ -96,7 +96,9 @@ defmodule WandererApp.Map do
|
||||
map_id
|
||||
|> get_map!()
|
||||
|> Map.get(:characters, [])
|
||||
|> Enum.map(fn character_id -> WandererApp.Character.get_map_character!(map_id, character_id) end)
|
||||
|> Enum.map(fn character_id ->
|
||||
WandererApp.Character.get_map_character!(map_id, character_id)
|
||||
end)
|
||||
|
||||
def list_systems(map_id),
|
||||
do: {:ok, map_id |> get_map!() |> Map.get(:systems, Map.new()) |> Map.values()}
|
||||
@@ -155,56 +157,61 @@ defmodule WandererApp.Map do
|
||||
|
||||
case not (characters |> Enum.member?(character_id)) do
|
||||
true ->
|
||||
{:ok,
|
||||
%{
|
||||
alliance_id: alliance_id,
|
||||
corporation_id: corporation_id,
|
||||
solar_system_id: solar_system_id,
|
||||
structure_id: structure_id,
|
||||
station_id: station_id,
|
||||
ship: ship_type_id,
|
||||
ship_name: ship_name
|
||||
}} = WandererApp.Character.get_character(character_id)
|
||||
WandererApp.Character.get_map_character(map_id, character_id)
|
||||
|> case do
|
||||
{:ok,
|
||||
%{
|
||||
alliance_id: alliance_id,
|
||||
corporation_id: corporation_id,
|
||||
solar_system_id: solar_system_id,
|
||||
structure_id: structure_id,
|
||||
station_id: station_id,
|
||||
ship: ship_type_id,
|
||||
ship_name: ship_name
|
||||
}} ->
|
||||
map_id
|
||||
|> update_map(%{characters: [character_id | characters]})
|
||||
|
||||
map_id
|
||||
|> update_map(%{characters: [character_id | characters]})
|
||||
WandererApp.Cache.insert(
|
||||
"map:#{map_id}:character:#{character_id}:alliance_id",
|
||||
alliance_id
|
||||
)
|
||||
|
||||
WandererApp.Cache.insert(
|
||||
"map:#{map_id}:character:#{character_id}:alliance_id",
|
||||
alliance_id
|
||||
)
|
||||
WandererApp.Cache.insert(
|
||||
"map:#{map_id}:character:#{character_id}:corporation_id",
|
||||
corporation_id
|
||||
)
|
||||
|
||||
WandererApp.Cache.insert(
|
||||
"map:#{map_id}:character:#{character_id}:corporation_id",
|
||||
corporation_id
|
||||
)
|
||||
# WandererApp.Cache.insert(
|
||||
# "map:#{map_id}:character:#{character_id}:solar_system_id",
|
||||
# solar_system_id
|
||||
# )
|
||||
|
||||
WandererApp.Cache.insert(
|
||||
"map:#{map_id}:character:#{character_id}:solar_system_id",
|
||||
solar_system_id
|
||||
)
|
||||
# WandererApp.Cache.insert(
|
||||
# "map:#{map_id}:character:#{character_id}:structure_id",
|
||||
# structure_id
|
||||
# )
|
||||
|
||||
WandererApp.Cache.insert(
|
||||
"map:#{map_id}:character:#{character_id}:structure_id",
|
||||
structure_id
|
||||
)
|
||||
# WandererApp.Cache.insert(
|
||||
# "map:#{map_id}:character:#{character_id}:station_id",
|
||||
# station_id
|
||||
# )
|
||||
|
||||
WandererApp.Cache.insert(
|
||||
"map:#{map_id}:character:#{character_id}:station_id",
|
||||
station_id
|
||||
)
|
||||
# WandererApp.Cache.insert(
|
||||
# "map:#{map_id}:character:#{character_id}:ship_type_id",
|
||||
# ship_type_id
|
||||
# )
|
||||
|
||||
WandererApp.Cache.insert(
|
||||
"map:#{map_id}:character:#{character_id}:ship_type_id",
|
||||
ship_type_id
|
||||
)
|
||||
# WandererApp.Cache.insert(
|
||||
# "map:#{map_id}:character:#{character_id}:ship_name",
|
||||
# ship_name
|
||||
# )
|
||||
|
||||
WandererApp.Cache.insert(
|
||||
"map:#{map_id}:character:#{character_id}:ship_name",
|
||||
ship_name
|
||||
)
|
||||
:ok
|
||||
|
||||
:ok
|
||||
error ->
|
||||
error
|
||||
end
|
||||
|
||||
_ ->
|
||||
{:error, :already_exists}
|
||||
|
||||
@@ -14,13 +14,16 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
map_id: map_id,
|
||||
tracked: track_character
|
||||
}),
|
||||
{:ok, character} <- WandererApp.Character.get_map_character(map_id, character_id) do
|
||||
{:ok, character} <- WandererApp.Character.get_character(character_id) do
|
||||
Impl.broadcast!(map_id, :character_added, character)
|
||||
:telemetry.execute([:wanderer_app, :map, :character, :added], %{count: 1})
|
||||
:ok
|
||||
else
|
||||
{:error, :not_found} ->
|
||||
:ok
|
||||
|
||||
_error ->
|
||||
{:ok, character} = WandererApp.Character.get_map_character(map_id, character_id)
|
||||
{:ok, character} = WandererApp.Character.get_character(character_id)
|
||||
Impl.broadcast!(map_id, :character_added, character)
|
||||
:ok
|
||||
end
|
||||
@@ -207,7 +210,11 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
end
|
||||
|
||||
def update_characters(%{map_id: map_id} = state) do
|
||||
{:ok, presence_character_ids} =
|
||||
WandererApp.Cache.lookup("map_#{map_id}:presence_character_ids", [])
|
||||
|
||||
WandererApp.Cache.lookup!("maps:#{map_id}:tracked_characters", [])
|
||||
|> Enum.filter(fn character_id -> character_id in presence_character_ids end)
|
||||
|> Enum.map(fn character_id ->
|
||||
Task.start_link(fn ->
|
||||
character_updates =
|
||||
@@ -292,38 +299,47 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
old_location,
|
||||
%{map: map, map_id: map_id, rtree_name: rtree_name, map_opts: map_opts} = _state
|
||||
) do
|
||||
start_solar_system_id =
|
||||
WandererApp.Cache.take("map:#{map_id}:character:#{character_id}:start_solar_system_id")
|
||||
|
||||
case is_nil(old_location.solar_system_id) and
|
||||
is_nil(start_solar_system_id) and
|
||||
ConnectionsImpl.can_add_location(map.scope, location.solar_system_id) do
|
||||
true ->
|
||||
:ok = SystemsImpl.maybe_add_system(map_id, location, nil, rtree_name, map_opts)
|
||||
|
||||
_ ->
|
||||
ConnectionsImpl.is_connection_valid(
|
||||
map.scope,
|
||||
old_location.solar_system_id,
|
||||
location.solar_system_id
|
||||
)
|
||||
|> case do
|
||||
true ->
|
||||
:ok =
|
||||
SystemsImpl.maybe_add_system(map_id, location, old_location, rtree_name, map_opts)
|
||||
|
||||
:ok =
|
||||
SystemsImpl.maybe_add_system(map_id, old_location, location, rtree_name, map_opts)
|
||||
|
||||
if is_character_in_space?(location) do
|
||||
if is_nil(start_solar_system_id) || start_solar_system_id == old_location.solar_system_id do
|
||||
ConnectionsImpl.is_connection_valid(
|
||||
map.scope,
|
||||
old_location.solar_system_id,
|
||||
location.solar_system_id
|
||||
)
|
||||
|> case do
|
||||
true ->
|
||||
:ok =
|
||||
ConnectionsImpl.maybe_add_connection(
|
||||
map_id,
|
||||
location,
|
||||
old_location,
|
||||
character_id,
|
||||
false
|
||||
)
|
||||
end
|
||||
SystemsImpl.maybe_add_system(map_id, location, old_location, rtree_name, map_opts)
|
||||
|
||||
_ ->
|
||||
:ok
|
||||
:ok =
|
||||
SystemsImpl.maybe_add_system(map_id, old_location, location, rtree_name, map_opts)
|
||||
|
||||
if is_character_in_space?(location) do
|
||||
:ok =
|
||||
ConnectionsImpl.maybe_add_connection(
|
||||
map_id,
|
||||
location,
|
||||
old_location,
|
||||
character_id,
|
||||
false
|
||||
)
|
||||
end
|
||||
|
||||
_ ->
|
||||
:ok
|
||||
end
|
||||
else
|
||||
# skip adding connection or system if character just started tracking on the map
|
||||
:ok
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -333,7 +349,9 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
end
|
||||
|
||||
defp track_character(map_id, character_id) do
|
||||
{:ok, character} = WandererApp.Character.get_character(character_id)
|
||||
{:ok, character} =
|
||||
WandererApp.Character.get_map_character(map_id, character_id, not_present: true)
|
||||
|
||||
add_character(%{map_id: map_id}, character, true)
|
||||
|
||||
WandererApp.Character.TrackerManager.update_track_settings(character_id, %{
|
||||
@@ -341,7 +359,8 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
track: true,
|
||||
track_online: true,
|
||||
track_location: true,
|
||||
track_ship: true
|
||||
track_ship: true,
|
||||
solar_system_id: character.solar_system_id
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
@@ -326,8 +326,7 @@ defmodule WandererApp.Map.Server.Impl do
|
||||
if can_broadcast?(map_id) do
|
||||
@pubsub_client.broadcast!(WandererApp.PubSub, map_id, %{
|
||||
event: event,
|
||||
payload: payload,
|
||||
timestamp: DateTime.utc_now()
|
||||
payload: payload
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
@@ -329,15 +329,20 @@ defmodule WandererAppWeb.MapRoutesEventHandler do
|
||||
%{assigns: %{current_user: current_user, has_tracked_characters?: true}} = socket
|
||||
) do
|
||||
character_eve_ids
|
||||
|> Task.async_stream(fn character_eve_id ->
|
||||
set_autopilot_waypoint(
|
||||
current_user,
|
||||
character_eve_id,
|
||||
add_to_beginning,
|
||||
clear_other_waypoints,
|
||||
destination_id
|
||||
)
|
||||
end)
|
||||
|> Task.async_stream(
|
||||
fn character_eve_id ->
|
||||
set_autopilot_waypoint(
|
||||
current_user,
|
||||
character_eve_id,
|
||||
add_to_beginning,
|
||||
clear_other_waypoints,
|
||||
destination_id
|
||||
)
|
||||
end,
|
||||
max_concurrency: System.schedulers_online(),
|
||||
on_timeout: :kill_task,
|
||||
timeout: :timer.minutes(1)
|
||||
)
|
||||
|> Enum.map(fn _result -> :skip end)
|
||||
|
||||
{:noreply, socket}
|
||||
|
||||
@@ -105,19 +105,23 @@ defmodule WandererAppWeb.MapSystemCommentsEventHandler do
|
||||
} =
|
||||
socket
|
||||
) do
|
||||
system =
|
||||
WandererApp.Map.find_system_by_location(map_id, %{
|
||||
solar_system_id: solar_system_id |> String.to_integer()
|
||||
})
|
||||
WandererApp.Map.find_system_by_location(map_id, %{
|
||||
solar_system_id: solar_system_id |> String.to_integer()
|
||||
})
|
||||
|> case do
|
||||
%{id: system_id} when not is_nil(system_id) ->
|
||||
{:ok, comments} = WandererApp.MapSystemCommentRepo.get_by_system(system_id)
|
||||
|
||||
{:ok, comments} = WandererApp.MapSystemCommentRepo.get_by_system(system.id)
|
||||
comments =
|
||||
comments
|
||||
|> Enum.map(fn c -> c |> Ash.load!([:character, :system]) end)
|
||||
|> Enum.map(&map_system_comment/1)
|
||||
|
||||
comments =
|
||||
comments
|
||||
|> Enum.map(fn c -> c |> Ash.load!([:character, :system]) end)
|
||||
|> Enum.map(&map_system_comment/1)
|
||||
{:reply, %{comments: comments}, socket}
|
||||
|
||||
{:reply, %{comments: comments}, socket}
|
||||
_ ->
|
||||
{:reply, %{comments: []}, socket}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_ui_event(
|
||||
|
||||
@@ -306,8 +306,7 @@ defmodule WandererAppWeb.MapEventHandler do
|
||||
socket
|
||||
|> Phoenix.LiveView.Utils.push_event("map_event", %{
|
||||
type: type,
|
||||
body: body,
|
||||
timestamp: DateTime.utc_now()
|
||||
body: body
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ defmodule WandererAppWeb.MapLive do
|
||||
|
||||
require Logger
|
||||
|
||||
@server_event_unsync_timeout :timer.minutes(2)
|
||||
|
||||
@impl true
|
||||
def mount(%{"slug" => map_slug} = _params, _session, socket) when is_connected?(socket) do
|
||||
Process.send_after(self(), %{event: :load_map}, Enum.random(10..800))
|
||||
@@ -96,16 +94,10 @@ defmodule WandererAppWeb.MapLive do
|
||||
|> push_navigate(to: ~p"/tracking/#{map_slug}")}
|
||||
|
||||
@impl true
|
||||
def handle_info(%{timestamp: timestamp} = info, %{assigns: %{map_slug: map_slug}} = socket) do
|
||||
duration = DateTime.diff(DateTime.utc_now(), timestamp, :millisecond)
|
||||
|
||||
if duration > @server_event_unsync_timeout do
|
||||
{:noreply, socket |> push_navigate(to: ~p"/#{map_slug}")}
|
||||
else
|
||||
{:noreply,
|
||||
socket
|
||||
|> WandererAppWeb.MapEventHandler.handle_event(info)}
|
||||
end
|
||||
def handle_info(info, %{assigns: %{map_slug: map_slug}} = socket) do
|
||||
{:noreply,
|
||||
socket
|
||||
|> WandererAppWeb.MapEventHandler.handle_event(info)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
||||
Reference in New Issue
Block a user