276 lines
10 KiB
C#
276 lines
10 KiB
C#
using Lifestream.Enums;
|
|
using LightlessSync.API.Data;
|
|
using LightlessSync.API.Dto.CharaData;
|
|
using LightlessSync.API.Dto.User;
|
|
using LightlessSync.Services.Mediator;
|
|
using LightlessSync.WebAPI;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Primitives;
|
|
|
|
namespace LightlessSync.Services
|
|
{
|
|
public class LocationShareService : DisposableMediatorSubscriberBase
|
|
{
|
|
private readonly DalamudUtilService _dalamudUtilService;
|
|
private readonly ApiController _apiController;
|
|
private IMemoryCache _locations = new MemoryCache(new MemoryCacheOptions());
|
|
private IMemoryCache _sharingStatus = new MemoryCache(new MemoryCacheOptions());
|
|
private CancellationTokenSource _resetToken = new CancellationTokenSource();
|
|
|
|
public LocationShareService(ILogger<LocationShareService> logger, LightlessMediator mediator, DalamudUtilService dalamudUtilService, ApiController apiController) : base(logger, mediator)
|
|
{
|
|
_dalamudUtilService = dalamudUtilService;
|
|
_apiController = apiController;
|
|
|
|
|
|
Mediator.Subscribe<DisconnectedMessage>(this, (msg) =>
|
|
{
|
|
_resetToken.Cancel();
|
|
_resetToken.Dispose();
|
|
_resetToken = new CancellationTokenSource();
|
|
});
|
|
Mediator.Subscribe<ConnectedMessage>(this, (msg) =>
|
|
{
|
|
_ = _apiController.UpdateLocation(new LocationDto(new UserData(_apiController.UID, apiController.DisplayName), _dalamudUtilService.GetMapData()));
|
|
_ = RequestAllLocation();
|
|
} );
|
|
Mediator.Subscribe<LocationSharingMessage>(this, UpdateLocationList);
|
|
Mediator.Subscribe<MapChangedMessage>(this,
|
|
msg => _ = _apiController.UpdateLocation(new LocationDto(new UserData(_apiController.UID, _apiController.DisplayName), _dalamudUtilService.GetMapData())));
|
|
}
|
|
|
|
private void UpdateLocationList(LocationSharingMessage msg)
|
|
{
|
|
if (_locations.TryGetValue(msg.User.UID, out _) && msg.LocationInfo.ServerId is 0)
|
|
{
|
|
_locations.Remove(msg.User.UID);
|
|
return;
|
|
}
|
|
|
|
if ( msg.LocationInfo.ServerId is not 0 && msg.ExpireAt > DateTime.UtcNow)
|
|
{
|
|
AddLocationInfo(msg.User.UID, msg.LocationInfo, msg.ExpireAt);
|
|
}
|
|
}
|
|
|
|
private void AddLocationInfo(string uid, LocationInfo location, DateTimeOffset expireAt)
|
|
{
|
|
var options = new MemoryCacheEntryOptions()
|
|
.SetAbsoluteExpiration(expireAt)
|
|
.AddExpirationToken(new CancellationChangeToken(_resetToken.Token));
|
|
_locations.Set(uid, location, options);
|
|
}
|
|
|
|
private async Task RequestAllLocation()
|
|
{
|
|
try
|
|
{
|
|
var (data, status) = await _apiController.RequestAllLocationInfo().ConfigureAwait(false);
|
|
foreach (var dto in data)
|
|
{
|
|
AddLocationInfo(dto.LocationDto.User.UID, dto.LocationDto.Location, dto.ExpireAt);
|
|
}
|
|
|
|
foreach (var dto in status)
|
|
{
|
|
AddStatus(dto.User.UID, dto.ExpireAt);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.LogError(e,"RequestAllLocation error : ");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
private void AddStatus(string uid, DateTimeOffset expireAt)
|
|
{
|
|
var options = new MemoryCacheEntryOptions()
|
|
.SetAbsoluteExpiration(expireAt)
|
|
.AddExpirationToken(new CancellationChangeToken(_resetToken.Token));
|
|
_sharingStatus.Set(uid, expireAt, options);
|
|
}
|
|
|
|
public string GetUserLocation(string uid)
|
|
{
|
|
try
|
|
{
|
|
if (_locations.TryGetValue<LocationInfo>(uid, out var location))
|
|
{
|
|
return _dalamudUtilService.LocationToString(location);
|
|
}
|
|
return String.Empty;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.LogError(e,"GetUserLocation error : ");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public LocationInfo? GetLocationForLifestreamByUid(string uid)
|
|
{
|
|
try
|
|
{
|
|
if (_locations.TryGetValue<LocationInfo>(uid, out var location))
|
|
{
|
|
return location;
|
|
}
|
|
return null;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.LogError(e,"GetLocationInfoByUid error : ");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public AddressBookEntryTuple? GetAddressBookEntryByLocation(LocationInfo location)
|
|
{
|
|
if (location.ServerId is 0 || location.TerritoryId is 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var territoryHousing = (TerritoryTypeIdHousing)location.TerritoryId;
|
|
|
|
if (territoryHousing == TerritoryTypeIdHousing.None || !Enum.IsDefined(typeof(TerritoryTypeIdHousing), territoryHousing))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var city = GetResidentialAetheryteKind(territoryHousing);
|
|
|
|
if (city == ResidentialAetheryteKind.None)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (location.HouseId is not 0 and not 100)
|
|
{
|
|
AddressBookEntryTuple addressEntry = (
|
|
Name: "",
|
|
World: (int)location.ServerId,
|
|
City: (int)city,
|
|
Ward: (int)location.WardId,
|
|
PropertyType: 0,
|
|
Plot: (int)location.HouseId,
|
|
Apartment: 0,
|
|
ApartmentSubdivision: location.DivisionId == 2,
|
|
AliasEnabled: false,
|
|
Alias: ""
|
|
);
|
|
return addressEntry;
|
|
}
|
|
else if (location.HouseId is 100)
|
|
{
|
|
AddressBookEntryTuple addressEntry = (
|
|
Name: "",
|
|
World: (int)location.ServerId,
|
|
City: (int)city,
|
|
Ward: (int)location.WardId,
|
|
PropertyType: 1,
|
|
Plot: 0,
|
|
Apartment: (int)location.RoomId,
|
|
ApartmentSubdivision: location.DivisionId == 2,
|
|
AliasEnabled: false,
|
|
Alias: ""
|
|
);
|
|
return addressEntry;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private ResidentialAetheryteKind GetResidentialAetheryteKind(TerritoryTypeIdHousing territoryHousing)
|
|
{
|
|
return territoryHousing switch
|
|
{
|
|
TerritoryTypeIdHousing.Shirogane or
|
|
TerritoryTypeIdHousing.ShiroganeApartment or
|
|
TerritoryTypeIdHousing.ShiroganeSmall or
|
|
TerritoryTypeIdHousing.ShiroganeMedium or
|
|
TerritoryTypeIdHousing.ShiroganeLarge or
|
|
TerritoryTypeIdHousing.ShiroganeFCRoom or
|
|
TerritoryTypeIdHousing.ShiroganeFCWorkshop
|
|
=> ResidentialAetheryteKind.Kugane,
|
|
|
|
TerritoryTypeIdHousing.Lavender or
|
|
TerritoryTypeIdHousing.LavenderSmall or
|
|
TerritoryTypeIdHousing.LavenderMedium or
|
|
TerritoryTypeIdHousing.LavenderLarge or
|
|
TerritoryTypeIdHousing.LavenderApartment or
|
|
TerritoryTypeIdHousing.LavenderFCRoom or
|
|
TerritoryTypeIdHousing.LavenderFCWorkshop
|
|
=> ResidentialAetheryteKind.Gridania,
|
|
|
|
TerritoryTypeIdHousing.Mist or
|
|
TerritoryTypeIdHousing.MistSmall or
|
|
TerritoryTypeIdHousing.MistMedium or
|
|
TerritoryTypeIdHousing.MistLarge or
|
|
TerritoryTypeIdHousing.MistApartment or
|
|
TerritoryTypeIdHousing.MistFCRoom or
|
|
TerritoryTypeIdHousing.MistFCWorkshop
|
|
=> ResidentialAetheryteKind.Limsa,
|
|
|
|
TerritoryTypeIdHousing.Goblet or
|
|
TerritoryTypeIdHousing.GobletSmall or
|
|
TerritoryTypeIdHousing.GobletMedium or
|
|
TerritoryTypeIdHousing.GobletLarge or
|
|
TerritoryTypeIdHousing.GobletApartment or
|
|
TerritoryTypeIdHousing.GobletFCRoom or
|
|
TerritoryTypeIdHousing.GobletFCWorkshop
|
|
=> ResidentialAetheryteKind.Uldah,
|
|
|
|
TerritoryTypeIdHousing.Empyream or
|
|
TerritoryTypeIdHousing.EmpyreamSmall or
|
|
TerritoryTypeIdHousing.EmpyreamMedium or
|
|
TerritoryTypeIdHousing.EmpyreamLarge or
|
|
TerritoryTypeIdHousing.EmpyreamApartment or
|
|
TerritoryTypeIdHousing.EmpyreamFCRoom or
|
|
TerritoryTypeIdHousing.EmpyreamFCWorkshop
|
|
=> ResidentialAetheryteKind.Foundation,
|
|
|
|
_ => ResidentialAetheryteKind.None
|
|
};
|
|
}
|
|
|
|
public string? GetMapAddressByLocation(LocationInfo location)
|
|
{
|
|
string? liString = null;
|
|
var territoryHousing = (TerritoryTypeIdHousing)location.TerritoryId;
|
|
if (GetResidentialAetheryteKind(territoryHousing) == ResidentialAetheryteKind.None)
|
|
{
|
|
liString = _dalamudUtilService.LocationToLifestream(location);
|
|
}
|
|
return liString;
|
|
}
|
|
|
|
public DateTimeOffset GetSharingStatus(string uid)
|
|
{
|
|
try
|
|
{
|
|
if (_sharingStatus.TryGetValue<DateTimeOffset>(uid, out var expireAt))
|
|
{
|
|
return expireAt;
|
|
}
|
|
return DateTimeOffset.MinValue;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.LogError(e,"GetSharingStatus error : ");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public void UpdateSharingStatus(List<string> users, DateTimeOffset expireAt)
|
|
{
|
|
foreach (var user in users)
|
|
{
|
|
AddStatus(user, expireAt);
|
|
}
|
|
}
|
|
|
|
}
|
|
} |