Implement Lifestream With Location Sharing.
This commit is contained in:
@@ -0,0 +1,51 @@
|
|||||||
|
namespace Lifestream.Enums;
|
||||||
|
|
||||||
|
public enum TerritoryTypeIdHousing
|
||||||
|
{
|
||||||
|
None = -1,
|
||||||
|
|
||||||
|
// Mist (Limsa Lominsa)
|
||||||
|
Mist = 339,
|
||||||
|
MistSmall = 282,
|
||||||
|
MistMedium = 283,
|
||||||
|
MistLarge = 284,
|
||||||
|
MistFCRoom = 384,
|
||||||
|
MistFCWorkshop = 423,
|
||||||
|
MistApartment = 608,
|
||||||
|
|
||||||
|
// Lavender Beds (Gridania)
|
||||||
|
Lavender = 340,
|
||||||
|
LavenderSmall = 342,
|
||||||
|
LavenderMedium = 343,
|
||||||
|
LavenderLarge = 344,
|
||||||
|
LavenderFCRoom = 385,
|
||||||
|
LavenderFCWorkshop = 425,
|
||||||
|
LavenderApartment = 609,
|
||||||
|
|
||||||
|
// Goblet (Ul'dah)
|
||||||
|
Goblet = 341,
|
||||||
|
GobletSmall = 345,
|
||||||
|
GobletMedium = 346,
|
||||||
|
GobletLarge = 347,
|
||||||
|
GobletFCRoom = 386,
|
||||||
|
GobletFCWorkshop = 424,
|
||||||
|
GobletApartment = 610,
|
||||||
|
|
||||||
|
// Shirogane (Kugane)
|
||||||
|
Shirogane = 641,
|
||||||
|
ShiroganeSmall = 649,
|
||||||
|
ShiroganeMedium = 650,
|
||||||
|
ShiroganeLarge = 651,
|
||||||
|
ShiroganeFCRoom = 652,
|
||||||
|
ShiroganeFCWorkshop = 653,
|
||||||
|
ShiroganeApartment = 655,
|
||||||
|
|
||||||
|
// Empyreum (Ishgard)
|
||||||
|
Empyream = 979,
|
||||||
|
EmpyreamSmall = 980,
|
||||||
|
EmpyreamMedium = 981,
|
||||||
|
EmpyreamLarge = 982,
|
||||||
|
EmpyreamFCRoom = 983,
|
||||||
|
EmpyreamFCWorkshop = 984,
|
||||||
|
EmpyreamApartment = 999,
|
||||||
|
}
|
||||||
@@ -701,7 +701,23 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
|
|||||||
str += $" Room #{location.RoomId}";
|
str += $" Room #{location.RoomId}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string LocationToLifestream(LocationInfo location)
|
||||||
|
{
|
||||||
|
if (location.ServerId is 0 || location.TerritoryId is 0 || ContentFinderData.Value.ContainsKey(location.TerritoryId)) return String.Empty;
|
||||||
|
var str = WorldData.Value[(ushort)location.ServerId];
|
||||||
|
if (location.HouseId is 0 && location.MapId is not 0)
|
||||||
|
{
|
||||||
|
var mapName = MapData.Value[(ushort)location.MapId].MapName;
|
||||||
|
var parts = mapName.Split(" - ", StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
var locationName = parts.Length > 0 ? parts[^1] : mapName;
|
||||||
|
str += $", tp {locationName}";
|
||||||
|
string message = $"LocationToLifestream: {str}";
|
||||||
|
_logger.LogInformation(message);
|
||||||
|
|
||||||
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Lifestream.Enums;
|
||||||
using LightlessSync.API.Data;
|
using LightlessSync.API.Data;
|
||||||
using LightlessSync.API.Dto.CharaData;
|
using LightlessSync.API.Dto.CharaData;
|
||||||
using LightlessSync.API.Dto.User;
|
using LightlessSync.API.Dto.User;
|
||||||
@@ -108,6 +109,144 @@ namespace LightlessSync.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
public DateTimeOffset GetSharingStatus(string uid)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ using Dalamud.Interface.Utility;
|
|||||||
using Dalamud.Interface.Utility.Raii;
|
using Dalamud.Interface.Utility.Raii;
|
||||||
using LightlessSync.API.Data.Enum;
|
using LightlessSync.API.Data.Enum;
|
||||||
using LightlessSync.API.Data.Extensions;
|
using LightlessSync.API.Data.Extensions;
|
||||||
|
using LightlessSync.API.Dto.CharaData;
|
||||||
using LightlessSync.API.Dto.Group;
|
using LightlessSync.API.Dto.Group;
|
||||||
using LightlessSync.API.Dto.User;
|
using LightlessSync.API.Dto.User;
|
||||||
|
using LightlessSync.Interop.Ipc;
|
||||||
using LightlessSync.LightlessConfiguration;
|
using LightlessSync.LightlessConfiguration;
|
||||||
using LightlessSync.PlayerData.Pairs;
|
using LightlessSync.PlayerData.Pairs;
|
||||||
using LightlessSync.Services;
|
using LightlessSync.Services;
|
||||||
@@ -40,6 +42,7 @@ public class DrawUserPair
|
|||||||
private readonly LocationShareService _locationShareService;
|
private readonly LocationShareService _locationShareService;
|
||||||
private readonly CharaDataManager _charaDataManager;
|
private readonly CharaDataManager _charaDataManager;
|
||||||
private readonly PairLedger _pairLedger;
|
private readonly PairLedger _pairLedger;
|
||||||
|
private readonly IpcCallerLifestream _lifestreamIpc;
|
||||||
private float _menuWidth = -1;
|
private float _menuWidth = -1;
|
||||||
private bool _wasHovered = false;
|
private bool _wasHovered = false;
|
||||||
private TooltipSnapshot _tooltipSnapshot = TooltipSnapshot.Empty;
|
private TooltipSnapshot _tooltipSnapshot = TooltipSnapshot.Empty;
|
||||||
@@ -60,7 +63,8 @@ public class DrawUserPair
|
|||||||
LightlessConfigService configService,
|
LightlessConfigService configService,
|
||||||
LocationShareService locationShareService,
|
LocationShareService locationShareService,
|
||||||
CharaDataManager charaDataManager,
|
CharaDataManager charaDataManager,
|
||||||
PairLedger pairLedger)
|
PairLedger pairLedger,
|
||||||
|
IpcCallerLifestream lifestreamIpc)
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_uiEntry = uiEntry;
|
_uiEntry = uiEntry;
|
||||||
@@ -79,6 +83,7 @@ public class DrawUserPair
|
|||||||
_locationShareService = locationShareService;
|
_locationShareService = locationShareService;
|
||||||
_charaDataManager = charaDataManager;
|
_charaDataManager = charaDataManager;
|
||||||
_pairLedger = pairLedger;
|
_pairLedger = pairLedger;
|
||||||
|
_lifestreamIpc = lifestreamIpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PairDisplayEntry DisplayEntry => _displayEntry;
|
public PairDisplayEntry DisplayEntry => _displayEntry;
|
||||||
@@ -656,6 +661,13 @@ public class DrawUserPair
|
|||||||
using (ImRaii.PushColor(ImGuiCol.Text, shareColor, shareLocation || shareLocationToOther))
|
using (ImRaii.PushColor(ImGuiCol.Text, shareColor, shareLocation || shareLocationToOther))
|
||||||
_uiSharedService.IconText(shareLocationIcon);
|
_uiSharedService.IconText(shareLocationIcon);
|
||||||
|
|
||||||
|
var popupId = $"LocationPopup_{_pair.UserData.UID}";
|
||||||
|
|
||||||
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Left) && shareLocation && !string.IsNullOrEmpty(location))
|
||||||
|
{
|
||||||
|
ImGui.OpenPopup(popupId);
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui.IsItemHovered())
|
if (ImGui.IsItemHovered())
|
||||||
{
|
{
|
||||||
ImGui.BeginTooltip();
|
ImGui.BeginTooltip();
|
||||||
@@ -669,6 +681,8 @@ public class DrawUserPair
|
|||||||
_uiSharedService.IconText(FontAwesomeIcon.LocationArrow);
|
_uiSharedService.IconText(FontAwesomeIcon.LocationArrow);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.TextUnformatted(location);
|
ImGui.TextUnformatted(location);
|
||||||
|
ImGui.Separator();
|
||||||
|
ImGui.TextUnformatted("Click to teleport to this location");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -700,6 +714,62 @@ public class DrawUserPair
|
|||||||
}
|
}
|
||||||
ImGui.EndTooltip();
|
ImGui.EndTooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui.BeginPopup(popupId))
|
||||||
|
{
|
||||||
|
|
||||||
|
var locationInfo = _locationShareService.GetLocationForLifestreamByUid(_pair.UserData.UID);
|
||||||
|
if (locationInfo != null)
|
||||||
|
{
|
||||||
|
var locationLi = locationInfo.Value;
|
||||||
|
var housingAddress = _locationShareService.GetAddressBookEntryByLocation(locationLi);
|
||||||
|
var mapAddress = _locationShareService.GetMapAddressByLocation(locationLi);
|
||||||
|
ImGui.TextUnformatted("Teleport to user?");
|
||||||
|
ImGui.Separator();
|
||||||
|
if (!_lifestreamIpc.APIAvailable)
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("Lifestream IPC is not available. Please ensure Lifestream is enabled");
|
||||||
|
}
|
||||||
|
else if (housingAddress != null || mapAddress != null)
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted($"Go to {location}?");
|
||||||
|
ImGui.TextUnformatted($"NOTE: Teleporting to maps with multiple aetherytes or instances may not be accurate currently. (ie. Thavnair, Yanxia)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("Lifestream cannot teleport here. If you are in a residential area, please make sure you're inside a plot.");
|
||||||
|
}
|
||||||
|
ImGui.Separator();
|
||||||
|
if (_lifestreamIpc.APIAvailable && (housingAddress != null || mapAddress != null))
|
||||||
|
{
|
||||||
|
if (locationLi.HouseId is not 0 && housingAddress != null)
|
||||||
|
{
|
||||||
|
if (ImGui.Button("Navigate"))
|
||||||
|
{
|
||||||
|
_lifestreamIpc.GoToHousingAddress(housingAddress.Value);
|
||||||
|
|
||||||
|
ImGui.CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mapAddress != null && locationLi.HouseId is 0)
|
||||||
|
{
|
||||||
|
if (ImGui.Button("Navigate"))
|
||||||
|
{
|
||||||
|
_lifestreamIpc.ExecuteLifestreamCommand(mapAddress);
|
||||||
|
|
||||||
|
ImGui.CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
}
|
||||||
|
if (ImGui.Button("Close"))
|
||||||
|
{
|
||||||
|
ImGui.CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (individualAnimDisabled || individualSoundsDisabled || individualVFXDisabled || individualIsSticky)
|
if (individualAnimDisabled || individualSoundsDisabled || individualVFXDisabled || individualIsSticky)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ using LightlessSync.UI.Handlers;
|
|||||||
using LightlessSync.UI.Models;
|
using LightlessSync.UI.Models;
|
||||||
using LightlessSync.WebAPI;
|
using LightlessSync.WebAPI;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using LightlessSync.Interop.Ipc;
|
||||||
|
|
||||||
namespace LightlessSync.UI;
|
namespace LightlessSync.UI;
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ public class DrawEntityFactory
|
|||||||
private readonly IdDisplayHandler _uidDisplayHandler;
|
private readonly IdDisplayHandler _uidDisplayHandler;
|
||||||
private readonly PairLedger _pairLedger;
|
private readonly PairLedger _pairLedger;
|
||||||
private readonly PairFactory _pairFactory;
|
private readonly PairFactory _pairFactory;
|
||||||
|
private readonly IpcCallerLifestream _lifestreamIpc;
|
||||||
|
|
||||||
public DrawEntityFactory(
|
public DrawEntityFactory(
|
||||||
ILogger<DrawEntityFactory> logger,
|
ILogger<DrawEntityFactory> logger,
|
||||||
@@ -60,7 +62,8 @@ public class DrawEntityFactory
|
|||||||
RenameSyncshellTagUi renameSyncshellTagUi,
|
RenameSyncshellTagUi renameSyncshellTagUi,
|
||||||
SelectSyncshellForTagUi selectSyncshellForTagUi,
|
SelectSyncshellForTagUi selectSyncshellForTagUi,
|
||||||
PairLedger pairLedger,
|
PairLedger pairLedger,
|
||||||
PairFactory pairFactory)
|
PairFactory pairFactory,
|
||||||
|
IpcCallerLifestream lifestreamIpc)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_apiController = apiController;
|
_apiController = apiController;
|
||||||
@@ -81,6 +84,7 @@ public class DrawEntityFactory
|
|||||||
_selectSyncshellForTagUi = selectSyncshellForTagUi;
|
_selectSyncshellForTagUi = selectSyncshellForTagUi;
|
||||||
_pairLedger = pairLedger;
|
_pairLedger = pairLedger;
|
||||||
_pairFactory = pairFactory;
|
_pairFactory = pairFactory;
|
||||||
|
_lifestreamIpc = lifestreamIpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DrawFolderGroup CreateGroupFolder(
|
public DrawFolderGroup CreateGroupFolder(
|
||||||
@@ -167,7 +171,8 @@ public class DrawEntityFactory
|
|||||||
_configService,
|
_configService,
|
||||||
_locationShareService,
|
_locationShareService,
|
||||||
_charaDataManager,
|
_charaDataManager,
|
||||||
_pairLedger);
|
_pairLedger,
|
||||||
|
_lifestreamIpc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<PairUiEntry> GetAllEntries()
|
public IReadOnlyList<PairUiEntry> GetAllEntries()
|
||||||
|
|||||||
Reference in New Issue
Block a user