Skip to content

Commit 11aec80

Browse files
committed
Removed the entire custom position and role sync API, replaced via patches enumerating through ExPlayer collections instead of ReferenceHub
1 parent 96a84ba commit 11aec80

File tree

15 files changed

+334
-578
lines changed

15 files changed

+334
-578
lines changed

LabExtended/API/Containers/RoleContainer.cs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -426,29 +426,6 @@ public bool IsWearingScp1344
426426
public ZombieRole? ZombieRole => Role as ZombieRole;
427427
#endregion
428428

429-
/// <summary>
430-
/// Gets the role type that the current player appears to have from the perspective of the specified target player.
431-
/// </summary>
432-
/// <param name="target">The player whose perspective is used to determine the appearance. Cannot be null.</param>
433-
/// <param name="allowOverwatchSpoof">Indicates whether Overwatch role spoofing should be considered when determining the appearance. If <see
434-
/// langword="true"/>, the returned role may be spoofed for Overwatch purposes; otherwise, the actual role is used.</param>
435-
/// <returns>The role type identifier representing how the current player appears to the target player.</returns>
436-
/// <exception cref="ArgumentNullException">Thrown if <paramref name="target"/> is null or does not have a valid reference hub.</exception>
437-
public RoleTypeId GetAppearance(ExPlayer target, bool allowOverwatchSpoof = true)
438-
{
439-
if (target?.ReferenceHub == null)
440-
throw new ArgumentNullException(nameof(target));
441-
442-
var appearance = allowOverwatchSpoof
443-
? RoleSync.GetSpoofedRoleToSend(Player, target)
444-
: RoleSync.GetRoleToSend(Player, target);
445-
446-
if (CustomRole != null)
447-
appearance = CustomRole.GetAppearance(Player, target, appearance, ref customRoleData);
448-
449-
return appearance;
450-
}
451-
452429
/// <summary>
453430
/// Sets the player's current role.
454431
/// </summary>

LabExtended/API/ExPlayer.cs

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,13 @@
6666
using VoiceChat;
6767

6868
using System.Text;
69+
6970
using InventorySystem.Items.Firearms;
7071
using InventorySystem.Items.Firearms.Modules;
7172
using InventorySystem.Items.Firearms.ShotEvents;
73+
7274
using LabExtended.Core;
75+
7376
using PlayerStatsSystem;
7477

7578
#pragma warning disable CS8602 // Dereference of a possibly null reference.
@@ -726,18 +729,6 @@ public ExPlayer(ReferenceHub referenceHub, SwitchContainer toggles) : base(refer
726729
public HashSet<PersonalHintElement> HintElements { get; internal set; } =
727730
HashSetPool<PersonalHintElement>.Shared.Rent();
728731

729-
/// <summary>
730-
/// Gets a list of sent role cache.
731-
/// </summary>
732-
public Dictionary<uint, RoleTypeId> SentRoles { get; private set; } =
733-
DictionaryPool<uint, RoleTypeId>.Shared.Rent();
734-
735-
/// <summary>
736-
/// Gets a list of sent positions.
737-
/// </summary>
738-
public Dictionary<uint, PositionSync.SentPosition> SentPositions { get; private set; } =
739-
DictionaryPool<uint, PositionSync.SentPosition>.Shared.Rent();
740-
741732
/// <summary>
742733
/// Gets the currently spectated player.
743734
/// </summary>
@@ -1461,9 +1452,6 @@ public void Dispose()
14611452
if (ply == null)
14621453
return;
14631454

1464-
ply.SentRoles.Remove(NetworkId);
1465-
ply.SentPositions.Remove(NetworkId);
1466-
14671455
ply.PersonalGhostFlags &= ~GhostBit;
14681456
});
14691457

@@ -1519,12 +1507,6 @@ public void Dispose()
15191507

15201508
if (Hints != null)
15211509
ObjectPool<HintCache>.Shared.Return(Hints);
1522-
1523-
if (SentRoles != null)
1524-
DictionaryPool<uint, RoleTypeId>.Shared.Return(SentRoles);
1525-
1526-
if (SentPositions != null)
1527-
DictionaryPool<uint, PositionSync.SentPosition>.Shared.Return(SentPositions);
15281510

15291511
if (infoBuilder != null)
15301512
StringBuilderPool.Shared.Return(infoBuilder);
@@ -1541,9 +1523,6 @@ public void Dispose()
15411523

15421524
Hints = null;
15431525

1544-
SentRoles = null!;
1545-
SentPositions = null!;
1546-
15471526
Position = null!;
15481527
Rotation = null!;
15491528
}

LabExtended/Core/ApiLoader.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,6 @@ private static void InvokeApi(bool isPreload)
375375

376376
FirearmModuleCache.Internal_Init();
377377

378-
PositionSync.Internal_Init();
379-
RoleSync.Internal_Init();
380-
381378
PlayerLoopHelper.Internal_InitLast(); // has to be last
382379
}
383380
}

LabExtended/Core/ApiVersion.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static class ApiVersion
2020
/// <summary>
2121
/// The build version part.
2222
/// </summary>
23-
public const int Build = 4;
23+
public const int Build = 5;
2424

2525
/// <summary>
2626
/// The patch version part.
@@ -35,8 +35,7 @@ public static class ApiVersion
3535
/// <summary>
3636
/// Gets the game's current version.
3737
/// </summary>
38-
public static Version Game { get; } =
39-
new(GameCore.Version.Major, GameCore.Version.Minor, GameCore.Version.Revision);
38+
public static Version Game { get; } = new(GameCore.Version.Major, GameCore.Version.Minor, GameCore.Version.Revision);
4039

4140
/// <summary>
4241
/// Gets the loader's game version compatibility.

LabExtended/Core/Configs/Objects/ConfigEffect.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,9 @@ public bool Apply(ExPlayer player)
256256
}
257257
else
258258
{
259-
ApiLog.Warn("LabExtended", $"Tried to apply an invalid config effect (&3{Name}&r)!");
259+
if (!string.IsNullOrEmpty(Name))
260+
ApiLog.Warn("LabExtended", $"Tried to apply an invalid config effect (&3{Name}&r)!");
261+
260262
return false;
261263
}
262264
}
@@ -275,7 +277,7 @@ private void TryGet()
275277
this.customEffect = customEffect;
276278
else if (BaseEffects.TryGetFirst(x => string.Equals(x.Name, Name, StringComparison.OrdinalIgnoreCase), out var baseEffect))
277279
this.baseEffect = baseEffect;
278-
else
280+
else if (!string.IsNullOrEmpty(Name))
279281
ApiLog.Warn("LabExtended", $"Effect &3{Name}&r could not be found in config.");
280282
}
281283
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace LabExtended.Events
2+
{
3+
/// <summary>
4+
/// Provides event data for singleton event scenarios, using a single shared instance of the event type.
5+
/// </summary>
6+
/// <remarks>This class is intended for use in event patterns where a single, reusable instance of event
7+
/// data is sufficient. The static singleton instance is created using the default constructor of the specified
8+
/// event type. This can help reduce allocations in high-frequency event scenarios. The ResetEvent method can be
9+
/// overridden to reset the state of the singleton event data before it is reused.</remarks>
10+
/// <typeparam name="TEvent">The type of the event data to be used as a singleton instance.</typeparam>
11+
public class SingletonBooleanEventArgs<TEvent> : BooleanEventArgs
12+
{
13+
/// <summary>
14+
/// Gets a singleton instance of the event type.
15+
/// </summary>
16+
/// <remarks>The singleton instance is created using the default constructor of the event type.
17+
/// This property is useful when a single, shared instance of the event is sufficient for application logic. The
18+
/// instance is created once and reused for all subsequent accesses.</remarks>
19+
public static TEvent Singleton { get; } = Activator.CreateInstance<TEvent>();
20+
21+
/// <summary>
22+
/// Resets the event to its initial state.
23+
/// </summary>
24+
public virtual void ResetEvent()
25+
{
26+
IsAllowed = true;
27+
}
28+
}
29+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace LabExtended.Events
2+
{
3+
/// <summary>
4+
/// Provides event data for singleton event scenarios, using a single shared instance of the event type.
5+
/// </summary>
6+
/// <remarks>This class is intended for use in event patterns where a single, reusable instance of event
7+
/// data is sufficient. The static singleton instance is created using the default constructor of the specified
8+
/// event type. This can help reduce allocations in high-frequency event scenarios. The ResetEvent method can be
9+
/// overridden to reset the state of the singleton event data before it is reused.</remarks>
10+
/// <typeparam name="TEvent">The type of the event data to be used as a singleton instance.</typeparam>
11+
public class SingletonEventArgs<TEvent> : EventArgs
12+
{
13+
/// <summary>
14+
/// Gets a singleton instance of the event type.
15+
/// </summary>
16+
/// <remarks>The singleton instance is created using the default constructor of the event type.
17+
/// This property is useful when a single, shared instance of the event is sufficient for application logic. The
18+
/// instance is created once and reused for all subsequent accesses.</remarks>
19+
public static TEvent Singleton { get; } = Activator.CreateInstance<TEvent>();
20+
21+
/// <summary>
22+
/// Resets the event to its initial state.
23+
/// </summary>
24+
public virtual void ResetEvent()
25+
{
26+
27+
}
28+
}
29+
}

LabExtended/Extensions/EventExtensions.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,29 @@ namespace LabExtended.Extensions;
1515
/// </summary>
1616
public static class EventExtensions
1717
{
18+
/// <summary>
19+
/// Resets the event state for the specified event argument instance, if supported.
20+
/// </summary>
21+
/// <remarks>This method has an effect only if <paramref name="obj"/> is an instance of a supported
22+
/// singleton event argument type, such as <see cref="SingletonEventArgs{TEvent}"/> or <see
23+
/// cref="SingletonBooleanEventArgs{TEvent}"/>. For other types, the method performs no action.</remarks>
24+
/// <typeparam name="TEvent">The type of the event argument object. Must be compatible with supported singleton event argument types.</typeparam>
25+
/// <param name="obj">The event argument instance whose event state is to be reset.</param>
26+
public static void ResetEvent<TEvent>(this TEvent obj)
27+
{
28+
if (obj is SingletonEventArgs<TEvent> singletonEventArgs)
29+
{
30+
singletonEventArgs.ResetEvent();
31+
return;
32+
}
33+
34+
if (obj is SingletonBooleanEventArgs<TEvent> singletonBooleanEventArgs)
35+
{
36+
singletonBooleanEventArgs.ResetEvent();
37+
return;
38+
}
39+
}
40+
1841
/// <summary>
1942
/// Invokes the <see cref="ExVoiceChatEvents.ReceivingVoiceMessageEventHandler"/> delegate.
2043
/// </summary>

LabExtended/LabExtended.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<TargetFramework>net48</TargetFramework>
55
<Nullable>enable</Nullable>
66
<LangVersion>preview</LangVersion>
7-
<AssemblyVersion>1.2.0.0</AssemblyVersion>
8-
<FileVersion>1.2.0.0</FileVersion>
7+
<AssemblyVersion>1.5.0.0</AssemblyVersion>
8+
<FileVersion>1.5.0.0</FileVersion>
99
<ImplicitUsings>enable</ImplicitUsings>
1010
<AssemblyName>0LabExtended</AssemblyName>
1111
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>

LabExtended/Patches/Events/Player/PlayerSpawningPatch.cs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010
using LabExtended.Utilities;
1111
using LabExtended.Extensions;
1212

13+
using LabExtended.Patches.Functions.Players;
14+
15+
using Mirror;
16+
1317
using PlayerRoles;
18+
using PlayerRoles.FirstPersonControl.NetworkMessages;
1419

1520
namespace LabExtended.Patches.Events.Player;
1621

@@ -68,14 +73,8 @@ changingArgs.NewRole is RoleTypeId.Spectator &&
6873
__instance.InitializeNewRole(newRole, reason, spawnFlags);
6974

7075
beforeSendAction?.InvokeSafe(__instance.CurrentRole);
71-
72-
if (RoleSync.IsEnabled)
73-
RoleSync.Internal_Resync(player);
74-
else
75-
__instance.SendNewRoleInfo();
76-
77-
if (PositionSync.IsEnabled)
78-
PositionSync.Internal_Reset(player);
76+
77+
SendNewRoleInfo(player);
7978

8079
PlayerEvents.OnChangedRole(new PlayerChangedRoleEventArgs(player.ReferenceHub,
8180
curRole?.RoleTypeId ?? RoleTypeId.None,
@@ -90,4 +89,29 @@ changingArgs.NewRole is RoleTypeId.Spectator &&
9089
return true;
9190
}
9291
}
92+
93+
private static void SendNewRoleInfo(ExPlayer player)
94+
{
95+
for (var x = 0; x < ExPlayer.AllCount; x++)
96+
{
97+
var receiver = ExPlayer.AllPlayers[x];
98+
99+
if (receiver?.ReferenceHub == null) continue;
100+
if (receiver.ReferenceHub.isLocalPlayer) continue;
101+
102+
var visibleRole = FpcServerPositionDistributor.GetVisibleRole(receiver.ReferenceHub, player.ReferenceHub);
103+
104+
using var writer = NetworkWriterPool.Get();
105+
106+
var baseRoleEvent = FpcServerPositionDistributor.InvokeRoleSyncEvent(player.ReferenceHub, receiver.ReferenceHub, visibleRole, writer);
107+
var roleEvent = PlayerPositionSyncPatch.InvokeEvent(player, receiver, visibleRole, writer);
108+
109+
if (baseRoleEvent != null) visibleRole = baseRoleEvent.Value;
110+
if (roleEvent != null) visibleRole = roleEvent.Value;
111+
112+
receiver.ReferenceHub.connectionToClient.Send(new RoleSyncInfo(player.ReferenceHub, visibleRole, receiver.ReferenceHub, writer), 0);
113+
114+
player.ReferenceHub.roleManager.PreviouslySentRole[receiver.ReferenceHub.netId] = visibleRole;
115+
}
116+
}
93117
}

0 commit comments

Comments
 (0)