Skip to content

Commit a39bdca

Browse files
committed
Refactor FrameworkHandler.cs
1 parent ef9fa47 commit a39bdca

8 files changed

Lines changed: 965 additions & 550 deletions

File tree

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace Visibility.Utils;
6+
7+
/// <summary>
8+
/// Manages containers for different unit types and their relationships
9+
/// </summary>
10+
public class ContainerManager
11+
{
12+
private readonly Dictionary<UnitType, Dictionary<ContainerType, Dictionary<uint, long>>> containers;
13+
private readonly HashSet<uint> idsToDelete = new(capacity: 200);
14+
15+
public ContainerManager()
16+
{
17+
this.containers = new Dictionary<UnitType, Dictionary<ContainerType, Dictionary<uint, long>>>
18+
{
19+
{
20+
UnitType.Players, new Dictionary<ContainerType, Dictionary<uint, long>>
21+
{
22+
{ ContainerType.All, new Dictionary<uint, long>() },
23+
{ ContainerType.Friend, new Dictionary<uint, long>() },
24+
{ ContainerType.Party, new Dictionary<uint, long>() },
25+
{ ContainerType.Company, new Dictionary<uint, long>() },
26+
}
27+
},
28+
{
29+
UnitType.Pets, new Dictionary<ContainerType, Dictionary<uint, long>>
30+
{
31+
{ ContainerType.All, new Dictionary<uint, long>() },
32+
{ ContainerType.Friend, new Dictionary<uint, long>() },
33+
{ ContainerType.Party, new Dictionary<uint, long>() },
34+
{ ContainerType.Company, new Dictionary<uint, long>() },
35+
}
36+
},
37+
{
38+
UnitType.Chocobos, new Dictionary<ContainerType, Dictionary<uint, long>>
39+
{
40+
{ ContainerType.All, new Dictionary<uint, long>() },
41+
{ ContainerType.Friend, new Dictionary<uint, long>() },
42+
{ ContainerType.Party, new Dictionary<uint, long>() },
43+
{ ContainerType.Company, new Dictionary<uint, long>() },
44+
}
45+
},
46+
{
47+
UnitType.Minions, new Dictionary<ContainerType, Dictionary<uint, long>>
48+
{
49+
{ ContainerType.All, new Dictionary<uint, long>() },
50+
{ ContainerType.Friend, new Dictionary<uint, long>() },
51+
{ ContainerType.Party, new Dictionary<uint, long>() },
52+
{ ContainerType.Company, new Dictionary<uint, long>() },
53+
}
54+
},
55+
};
56+
}
57+
58+
/// <summary>
59+
/// Add an entity to a specific container
60+
/// </summary>
61+
public void AddToContainer(UnitType unitType, ContainerType containerType, uint entityId)
62+
{
63+
this.containers[unitType][containerType][entityId] = Environment.TickCount64;
64+
}
65+
66+
/// <summary>
67+
/// Remove an entity from a specific container
68+
/// </summary>
69+
public void RemoveFromContainer(UnitType unitType, ContainerType containerType, uint entityId)
70+
{
71+
this.containers[unitType][containerType].Remove(entityId);
72+
}
73+
74+
/// <summary>
75+
/// Check if an entity exists in a specific container
76+
/// </summary>
77+
public bool IsInContainer(UnitType unitType, ContainerType containerType, uint entityId)
78+
{
79+
return this.containers[unitType][containerType].ContainsKey(entityId);
80+
}
81+
82+
/// <summary>
83+
/// Cleanup expired entries from all containers
84+
/// </summary>
85+
public void CleanupContainers()
86+
{
87+
foreach ((UnitType _, Dictionary<ContainerType, Dictionary<uint, long>>? unitContainer) in this.containers)
88+
{
89+
foreach ((ContainerType _, Dictionary<uint, long>? container) in unitContainer)
90+
{
91+
foreach ((uint id, long ticks) in container)
92+
if (ticks > Environment.TickCount64 + 5000)
93+
this.idsToDelete.Add(id);
94+
95+
foreach (uint id in this.idsToDelete) container.Remove(id);
96+
97+
this.idsToDelete.Clear();
98+
}
99+
}
100+
}
101+
102+
/// <summary>
103+
/// Get all entities in a specific container
104+
/// </summary>
105+
public IEnumerable<KeyValuePair<uint, long>> GetContainerEntities(UnitType unitType, ContainerType containerType)
106+
{
107+
return this.containers[unitType][containerType].ToList();
108+
}
109+
110+
/// <summary>
111+
/// Clear a specific container
112+
/// </summary>
113+
public void ClearContainer(UnitType unitType, ContainerType containerType)
114+
{
115+
this.containers[unitType][containerType].Clear();
116+
}
117+
118+
/// <summary>
119+
/// Clear all containers
120+
/// </summary>
121+
public void ClearAllContainers()
122+
{
123+
foreach ((UnitType _, Dictionary<ContainerType, Dictionary<uint, long>>? unitContainer) in this.containers)
124+
foreach ((ContainerType _, Dictionary<uint, long>? container) in unitContainer)
125+
container.Clear();
126+
}
127+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
using FFXIVClientStructs.FFXIV.Client.Game.Character;
2+
3+
namespace Visibility.Utils.EntityHandlers;
4+
5+
/// <summary>
6+
/// Handles visibility logic for chocobo entities
7+
/// </summary>
8+
public class ChocoboHandler
9+
{
10+
private readonly ContainerManager containerManager;
11+
private readonly VoidListManager voidListManager;
12+
private readonly ObjectVisibilityManager visibilityManager;
13+
14+
public ChocoboHandler(
15+
ContainerManager containerManager,
16+
VoidListManager voidListManager,
17+
ObjectVisibilityManager visibilityManager)
18+
{
19+
this.containerManager = containerManager;
20+
this.voidListManager = voidListManager;
21+
this.visibilityManager = visibilityManager;
22+
}
23+
24+
/// <summary>
25+
/// Process a chocobo entity and determine its visibility
26+
/// </summary>
27+
public unsafe void ProcessChocobo(Character* characterPtr, Character* localPlayer)
28+
{
29+
// Ignore own chocobo
30+
if (characterPtr->GameObject.OwnerId == localPlayer->GameObject.EntityId ||
31+
this.visibilityManager.ShowGameObject(characterPtr)) return;
32+
33+
// Add to containers
34+
this.UpdateContainers(characterPtr);
35+
36+
// Hide chocobo if it belongs to a voided player
37+
if (this.voidListManager.IsObjectVoided(characterPtr->GameObject.OwnerId))
38+
{
39+
this.visibilityManager.HideGameObject(characterPtr);
40+
return;
41+
}
42+
43+
// Check visibility conditions
44+
if (this.ShouldShowChocobo(characterPtr)) return;
45+
46+
this.visibilityManager.HideGameObject(characterPtr);
47+
}
48+
49+
/// <summary>
50+
/// Update container memberships for the chocobo
51+
/// </summary>
52+
private unsafe void UpdateContainers(Character* characterPtr)
53+
{
54+
// All chocobos container
55+
this.containerManager.AddToContainer(UnitType.Chocobos, ContainerType.All, characterPtr->GameObject.EntityId);
56+
57+
// Friend's chocobo container
58+
if (this.containerManager.IsInContainer(UnitType.Players, ContainerType.Friend,
59+
characterPtr->GameObject.OwnerId))
60+
{
61+
this.containerManager.AddToContainer(UnitType.Chocobos, ContainerType.Friend,
62+
characterPtr->GameObject.EntityId);
63+
}
64+
65+
// Party member's chocobo container
66+
if (this.containerManager.IsInContainer(UnitType.Players, ContainerType.Party,
67+
characterPtr->GameObject.OwnerId))
68+
{
69+
this.containerManager.AddToContainer(UnitType.Chocobos, ContainerType.Party,
70+
characterPtr->GameObject.EntityId);
71+
}
72+
73+
// Company member's chocobo container
74+
if (this.containerManager.IsInContainer(UnitType.Players, ContainerType.Company,
75+
characterPtr->GameObject.OwnerId))
76+
{
77+
this.containerManager.AddToContainer(UnitType.Chocobos, ContainerType.Company,
78+
characterPtr->GameObject.EntityId);
79+
}
80+
}
81+
82+
/// <summary>
83+
/// Determine if a chocobo should be shown based on configuration settings
84+
/// </summary>
85+
private unsafe bool ShouldShowChocobo(Character* characterPtr)
86+
{
87+
// Check if plugin is disabled or chocobo hiding is disabled
88+
if (!VisibilityPlugin.Instance.Configuration.Enabled ||
89+
!VisibilityPlugin.Instance.Configuration.CurrentConfig.HideChocobo)
90+
return true;
91+
92+
// Check if chocobo's owner is a friend and show friends' chocobos is enabled
93+
if (VisibilityPlugin.Instance.Configuration.CurrentConfig.ShowFriendChocobo &&
94+
this.containerManager.IsInContainer(UnitType.Players, ContainerType.Friend,
95+
characterPtr->GameObject.OwnerId)) return true;
96+
97+
// Check if chocobo's owner is in the same company and show company members' chocobos is enabled
98+
if (VisibilityPlugin.Instance.Configuration.CurrentConfig.ShowCompanyChocobo &&
99+
this.containerManager.IsInContainer(UnitType.Players, ContainerType.Company,
100+
characterPtr->GameObject.OwnerId)) return true;
101+
102+
// Check if chocobo's owner is in the party and show party members' chocobos is enabled
103+
if (VisibilityPlugin.Instance.Configuration.CurrentConfig.ShowPartyChocobo &&
104+
this.containerManager.IsInContainer(UnitType.Players, ContainerType.Party,
105+
characterPtr->GameObject.OwnerId)) return true;
106+
107+
// Check if chocobo's owner is whitelisted
108+
return this.voidListManager.IsObjectWhitelisted(characterPtr->GameObject.OwnerId);
109+
}
110+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using FFXIVClientStructs.FFXIV.Client.Game.Character;
2+
3+
namespace Visibility.Utils.EntityHandlers;
4+
5+
/// <summary>
6+
/// Handles visibility logic for minion entities
7+
/// </summary>
8+
public class MinionHandler
9+
{
10+
private readonly ContainerManager containerManager;
11+
private readonly ObjectVisibilityManager visibilityManager;
12+
13+
public MinionHandler(
14+
ContainerManager containerManager,
15+
ObjectVisibilityManager visibilityManager)
16+
{
17+
this.containerManager = containerManager;
18+
this.visibilityManager = visibilityManager;
19+
}
20+
21+
/// <summary>
22+
/// Process a minion entity and determine its visibility
23+
/// </summary>
24+
public unsafe void ProcessMinion(Character* characterPtr, Character* localPlayer)
25+
{
26+
if (localPlayer == null ||
27+
characterPtr->CompanionOwnerId == localPlayer->GameObject.EntityId ||
28+
this.visibilityManager.ShowGameObject(characterPtr, ObjectVisibilityManager.ObjectType.Companion))
29+
return;
30+
31+
if (!VisibilityPlugin.Instance.Configuration.Enabled ||
32+
!VisibilityPlugin.Instance.Configuration.CurrentConfig.HideMinion)
33+
return;
34+
35+
// Add to containers
36+
this.UpdateContainers(characterPtr);
37+
38+
// Check visibility conditions
39+
if (this.ShouldShowMinion(characterPtr)) return;
40+
41+
this.visibilityManager.HideGameObject(characterPtr, ObjectVisibilityManager.ObjectType.Companion);
42+
}
43+
44+
/// <summary>
45+
/// Update container memberships for the minion
46+
/// </summary>
47+
private unsafe void UpdateContainers(Character* characterPtr)
48+
{
49+
// All minions container
50+
this.containerManager.AddToContainer(UnitType.Minions, ContainerType.All, characterPtr->CompanionOwnerId);
51+
52+
// Friend's minion container
53+
if (this.containerManager.IsInContainer(UnitType.Players, ContainerType.Friend, characterPtr->CompanionOwnerId))
54+
{
55+
this.containerManager.AddToContainer(UnitType.Minions, ContainerType.Friend,
56+
characterPtr->CompanionOwnerId);
57+
}
58+
59+
// Party member's minion container
60+
if (this.containerManager.IsInContainer(UnitType.Players, ContainerType.Party, characterPtr->CompanionOwnerId))
61+
this.containerManager.AddToContainer(UnitType.Minions, ContainerType.Party, characterPtr->CompanionOwnerId);
62+
63+
// Company member's minion container
64+
if (this.containerManager.IsInContainer(UnitType.Players, ContainerType.Company,
65+
characterPtr->CompanionOwnerId))
66+
{
67+
this.containerManager.AddToContainer(UnitType.Minions, ContainerType.Company,
68+
characterPtr->CompanionOwnerId);
69+
}
70+
}
71+
72+
/// <summary>
73+
/// Determine if a minion should be shown based on configuration settings
74+
/// </summary>
75+
private unsafe bool ShouldShowMinion(Character* characterPtr)
76+
{
77+
// Check if minion's owner is a friend and show friends' minions is enabled
78+
if (VisibilityPlugin.Instance.Configuration.CurrentConfig.ShowFriendMinion &&
79+
this.containerManager.IsInContainer(UnitType.Players, ContainerType.Friend, characterPtr->CompanionOwnerId))
80+
return true;
81+
82+
// Check if minion's owner is in the same company and show company members' minions is enabled
83+
if (VisibilityPlugin.Instance.Configuration.CurrentConfig.ShowCompanyMinion &&
84+
this.containerManager.IsInContainer(UnitType.Players, ContainerType.Company,
85+
characterPtr->CompanionOwnerId)) return true;
86+
87+
// Check if minion's owner is in the party and show party members' minions is enabled
88+
return VisibilityPlugin.Instance.Configuration.CurrentConfig.ShowPartyMinion &&
89+
this.containerManager.IsInContainer(UnitType.Players, ContainerType.Party,
90+
characterPtr->CompanionOwnerId);
91+
}
92+
}

0 commit comments

Comments
 (0)